Mercurial > hg > nginx-vendor-0-8
comparison src/core/ngx_log.c @ 0:f0b350454894 NGINX_0_1_0
nginx 0.1.0
*) The first public version.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 04 Oct 2004 00:00:00 +0400 |
parents | |
children | 4b2dafa26fe2 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f0b350454894 |
---|---|
1 | |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 | |
10 | |
11 static void ngx_log_write(ngx_log_t *log, char *errstr, size_t len); | |
12 static char *ngx_set_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | |
13 | |
14 | |
15 static ngx_command_t ngx_errlog_commands[] = { | |
16 | |
17 {ngx_string("error_log"), | |
18 NGX_MAIN_CONF|NGX_CONF_1MORE, | |
19 ngx_set_error_log, | |
20 0, | |
21 0, | |
22 NULL}, | |
23 | |
24 ngx_null_command | |
25 }; | |
26 | |
27 | |
28 static ngx_core_module_t ngx_errlog_module_ctx = { | |
29 ngx_string("errlog"), | |
30 NULL, | |
31 NULL | |
32 }; | |
33 | |
34 | |
35 ngx_module_t ngx_errlog_module = { | |
36 NGX_MODULE, | |
37 &ngx_errlog_module_ctx, /* module context */ | |
38 ngx_errlog_commands, /* module directives */ | |
39 NGX_CORE_MODULE, /* module type */ | |
40 NULL, /* init module */ | |
41 NULL /* init child */ | |
42 }; | |
43 | |
44 | |
45 static ngx_log_t ngx_log; | |
46 static ngx_open_file_t ngx_stderr; | |
47 | |
48 | |
49 static const char *err_levels[] = { | |
50 "stderr", "emerg", "alert", "crit", "error", | |
51 "warn", "notice", "info", "debug" | |
52 }; | |
53 | |
54 static const char *debug_levels[] = { | |
55 "debug_core", "debug_alloc", "debug_mutex", "debug_event", | |
56 "debug_http", "debug_imap" | |
57 }; | |
58 | |
59 | |
60 #if (HAVE_VARIADIC_MACROS) | |
61 void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, | |
62 const char *fmt, ...) | |
63 #else | |
64 void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, | |
65 const char *fmt, va_list args) | |
66 #endif | |
67 { | |
68 char errstr[MAX_ERROR_STR]; | |
69 size_t len, max; | |
70 #if (HAVE_VARIADIC_MACROS) | |
71 va_list args; | |
72 #endif | |
73 | |
74 if (log->file->fd == NGX_INVALID_FILE) { | |
75 return; | |
76 } | |
77 | |
78 ngx_memcpy(errstr, ngx_cached_err_log_time.data, | |
79 ngx_cached_err_log_time.len); | |
80 | |
81 #if (WIN32) | |
82 max = MAX_ERROR_STR - 2; | |
83 #else | |
84 max = MAX_ERROR_STR - 1; | |
85 #endif | |
86 | |
87 len = ngx_cached_err_log_time.len; | |
88 | |
89 len += ngx_snprintf(errstr + len, max - len, " [%s] ", err_levels[level]); | |
90 | |
91 /* pid#tid */ | |
92 len += ngx_snprintf(errstr + len, max - len, | |
93 PID_T_FMT "#" TID_T_FMT ": ", ngx_log_pid, ngx_log_tid); | |
94 | |
95 if (log->data && *(int *) log->data != -1) { | |
96 len += ngx_snprintf(errstr + len, max - len, | |
97 "*%u ", *(u_int *) log->data); | |
98 } | |
99 | |
100 #if (HAVE_VARIADIC_MACROS) | |
101 | |
102 va_start(args, fmt); | |
103 len += ngx_vsnprintf(errstr + len, max - len, fmt, args); | |
104 va_end(args); | |
105 | |
106 #else | |
107 | |
108 len += ngx_vsnprintf(errstr + len, max - len, fmt, args); | |
109 | |
110 #endif | |
111 | |
112 if (err) { | |
113 | |
114 if (len > max - 50) { | |
115 | |
116 /* leave a space for an error code */ | |
117 | |
118 len = max - 50; | |
119 errstr[len++] = '.'; | |
120 errstr[len++] = '.'; | |
121 errstr[len++] = '.'; | |
122 } | |
123 | |
124 #if (WIN32) | |
125 if ((unsigned) err >= 0x80000000) { | |
126 len += ngx_snprintf(errstr + len, max - len, " (%X: ", err); | |
127 } else { | |
128 len += ngx_snprintf(errstr + len, max - len, " (%d: ", err); | |
129 } | |
130 #else | |
131 len += ngx_snprintf(errstr + len, max - len, " (%d: ", err); | |
132 #endif | |
133 | |
134 if (len >= max) { | |
135 ngx_log_write(log, errstr, max); | |
136 return; | |
137 } | |
138 | |
139 len += ngx_strerror_r(err, errstr + len, max - len); | |
140 | |
141 if (len >= max) { | |
142 ngx_log_write(log, errstr, max); | |
143 return; | |
144 } | |
145 | |
146 errstr[len++] = ')'; | |
147 | |
148 if (len >= max) { | |
149 ngx_log_write(log, errstr, max); | |
150 return; | |
151 } | |
152 | |
153 } else { | |
154 if (len >= max) { | |
155 ngx_log_write(log, errstr, max); | |
156 return; | |
157 } | |
158 } | |
159 | |
160 if (level != NGX_LOG_DEBUG && log->handler) { | |
161 len += log->handler(log->data, errstr + len, max - len); | |
162 | |
163 if (len >= max) { | |
164 len = max; | |
165 } | |
166 } | |
167 | |
168 ngx_log_write(log, errstr, len); | |
169 } | |
170 | |
171 | |
172 static void ngx_log_write(ngx_log_t *log, char *errstr, size_t len) | |
173 { | |
174 #if (WIN32) | |
175 u_long written; | |
176 | |
177 errstr[len++] = CR; | |
178 errstr[len++] = LF; | |
179 WriteFile(log->file->fd, errstr, len, &written, NULL); | |
180 | |
181 #else | |
182 | |
183 errstr[len++] = LF; | |
184 write(log->file->fd, errstr, len); | |
185 | |
186 #endif | |
187 } | |
188 | |
189 | |
190 #if !(HAVE_VARIADIC_MACROS) | |
191 | |
192 void ngx_log_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, | |
193 const char *fmt, ...) | |
194 { | |
195 va_list args; | |
196 | |
197 if (log->log_level >= level) { | |
198 va_start(args, fmt); | |
199 ngx_log_error_core(level, log, err, fmt, args); | |
200 va_end(args); | |
201 } | |
202 } | |
203 | |
204 | |
205 void ngx_log_debug_core(ngx_log_t *log, ngx_err_t err, const char *fmt, ...) | |
206 { | |
207 va_list args; | |
208 | |
209 va_start(args, fmt); | |
210 ngx_log_error_core(NGX_LOG_DEBUG, log, err, fmt, args); | |
211 va_end(args); | |
212 } | |
213 | |
214 | |
215 void ngx_assert_core(ngx_log_t *log, const char *fmt, ...) | |
216 { | |
217 va_list args; | |
218 | |
219 va_start(args, fmt); | |
220 ngx_log_error_core(NGX_LOG_ALERT, log, 0, fmt, args); | |
221 va_end(args); | |
222 } | |
223 | |
224 #endif | |
225 | |
226 | |
227 ngx_log_t *ngx_log_init_stderr() | |
228 { | |
229 #if (WIN32) | |
230 | |
231 ngx_stderr_fileno = GetStdHandle(STD_ERROR_HANDLE); | |
232 ngx_stderr.fd = ngx_stderr_fileno; | |
233 | |
234 if (ngx_stderr_fileno == NGX_INVALID_FILE) { | |
235 | |
236 /* TODO: where can we log error ? */ | |
237 | |
238 return NULL; | |
239 | |
240 } else if (ngx_stderr_fileno == NULL) { | |
241 | |
242 /* there are no associated standard handles */ | |
243 | |
244 /* TODO: where can we can log possible errors ? */ | |
245 | |
246 ngx_stderr.fd = NGX_INVALID_FILE; | |
247 } | |
248 | |
249 #else | |
250 | |
251 ngx_stderr.fd = STDERR_FILENO; | |
252 | |
253 #endif | |
254 | |
255 ngx_log.file = &ngx_stderr; | |
256 ngx_log.log_level = NGX_LOG_ERR; | |
257 | |
258 return &ngx_log; | |
259 } | |
260 | |
261 | |
262 #if 0 | |
263 | |
264 ngx_int_t ngx_log_init_error_log() | |
265 { | |
266 ngx_fd_t fd; | |
267 | |
268 #ifdef NGX_ERROR_LOG_PATH | |
269 | |
270 fd = ngx_open_file(NGX_ERROR_LOG_PATH, NGX_FILE_RDWR, | |
271 NGX_FILE_CREATE_OR_OPEN|NGX_FILE_APPEND); | |
272 | |
273 if (fd == NGX_INVALID_FILE) { | |
274 ngx_log_error(NGX_LOG_EMERG, (&ngx_log), ngx_errno, | |
275 ngx_open_file_n " \"" NGX_ERROR_LOG_PATH "\" failed"); | |
276 return NGX_ERROR; | |
277 } | |
278 | |
279 #if (WIN32) | |
280 | |
281 if (ngx_file_append_mode(fd) == NGX_ERROR) { | |
282 ngx_log_error(NGX_LOG_EMERG, (&ngx_log), ngx_errno, | |
283 ngx_file_append_mode_n " \"" NGX_ERROR_LOG_PATH | |
284 "\" failed"); | |
285 return NGX_ERROR; | |
286 } | |
287 | |
288 #else | |
289 | |
290 if (dup2(fd, STDERR_FILENO) == NGX_ERROR) { | |
291 ngx_log_error(NGX_LOG_EMERG, (&ngx_log), ngx_errno, | |
292 "dup2(STDERR) failed"); | |
293 return NGX_ERROR; | |
294 } | |
295 | |
296 #endif | |
297 | |
298 #else /* no NGX_ERROR_LOG_PATH */ | |
299 | |
300 ngx_log.log_level = NGX_LOG_INFO; | |
301 | |
302 #endif | |
303 | |
304 return NGX_OK; | |
305 } | |
306 | |
307 #endif | |
308 | |
309 | |
310 ngx_log_t *ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_array_t *args) | |
311 { | |
312 ngx_log_t *log; | |
313 ngx_str_t *value, *name; | |
314 | |
315 if (args) { | |
316 value = args->elts; | |
317 name = &value[1]; | |
318 | |
319 } else { | |
320 name = NULL; | |
321 } | |
322 | |
323 if (!(log = ngx_pcalloc(cycle->pool, sizeof(ngx_log_t)))) { | |
324 return NULL; | |
325 } | |
326 | |
327 if (!(log->file = ngx_conf_open_file(cycle, name))) { | |
328 return NULL; | |
329 } | |
330 | |
331 return log; | |
332 } | |
333 | |
334 | |
335 char *ngx_set_error_log_levels(ngx_conf_t *cf, ngx_log_t *log) | |
336 { | |
337 ngx_uint_t i, n, d; | |
338 ngx_str_t *value; | |
339 | |
340 value = cf->args->elts; | |
341 | |
342 for (i = 2; i < cf->args->nelts; i++) { | |
343 | |
344 for (n = 1; n <= NGX_LOG_DEBUG; n++) { | |
345 if (ngx_strcmp(value[i].data, err_levels[n]) == 0) { | |
346 | |
347 if (log->log_level != 0) { | |
348 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
349 "invalid log level \"%s\"", | |
350 value[i].data); | |
351 return NGX_CONF_ERROR; | |
352 } | |
353 | |
354 log->log_level = n; | |
355 continue; | |
356 } | |
357 } | |
358 | |
359 for (n = 0, d = NGX_LOG_DEBUG_FIRST; d <= NGX_LOG_DEBUG_LAST; d <<= 1) { | |
360 if (ngx_strcmp(value[i].data, debug_levels[n++]) == 0) { | |
361 if (log->log_level & ~NGX_LOG_DEBUG_ALL) { | |
362 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
363 "invalid log level \"%s\"", | |
364 value[i].data); | |
365 return NGX_CONF_ERROR; | |
366 } | |
367 | |
368 log->log_level |= d; | |
369 } | |
370 } | |
371 | |
372 | |
373 if (log->log_level == 0) { | |
374 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
375 "invalid log level \"%s\"", value[i].data); | |
376 return NGX_CONF_ERROR; | |
377 } | |
378 } | |
379 | |
380 if (log->log_level == NGX_LOG_DEBUG) { | |
381 log->log_level = NGX_LOG_DEBUG_ALL; | |
382 } | |
383 | |
384 return NGX_CONF_OK; | |
385 } | |
386 | |
387 | |
388 static char *ngx_set_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
389 { | |
390 ngx_str_t *value; | |
391 | |
392 value = cf->args->elts; | |
393 | |
394 if (value[1].len == 6 && ngx_strcmp(value[1].data, "stderr") == 0) { | |
395 cf->cycle->new_log->file->fd = ngx_stderr.fd; | |
396 cf->cycle->new_log->file->name.len = 0; | |
397 cf->cycle->new_log->file->name.data = NULL; | |
398 | |
399 } else { | |
400 cf->cycle->new_log->file->name = value[1]; | |
401 | |
402 if (ngx_conf_full_name(cf->cycle, &cf->cycle->new_log->file->name) | |
403 == NGX_ERROR) | |
404 { | |
405 return NGX_CONF_ERROR; | |
406 } | |
407 } | |
408 | |
409 return ngx_set_error_log_levels(cf, cf->cycle->new_log); | |
410 } |