Annotation of embedaddon/nginx/src/core/ngx_log.c, revision 1.1.1.1
1.1 misho 1:
2: /*
3: * Copyright (C) Igor Sysoev
4: * Copyright (C) Nginx, Inc.
5: */
6:
7:
8: #include <ngx_config.h>
9: #include <ngx_core.h>
10:
11:
12: static char *ngx_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_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_V1,
37: &ngx_errlog_module_ctx, /* module context */
38: ngx_errlog_commands, /* module directives */
39: NGX_CORE_MODULE, /* module type */
40: NULL, /* init master */
41: NULL, /* init module */
42: NULL, /* init process */
43: NULL, /* init thread */
44: NULL, /* exit thread */
45: NULL, /* exit process */
46: NULL, /* exit master */
47: NGX_MODULE_V1_PADDING
48: };
49:
50:
51: static ngx_log_t ngx_log;
52: static ngx_open_file_t ngx_log_file;
53: ngx_uint_t ngx_use_stderr = 1;
54:
55:
56: static ngx_str_t err_levels[] = {
57: ngx_null_string,
58: ngx_string("emerg"),
59: ngx_string("alert"),
60: ngx_string("crit"),
61: ngx_string("error"),
62: ngx_string("warn"),
63: ngx_string("notice"),
64: ngx_string("info"),
65: ngx_string("debug")
66: };
67:
68: static const char *debug_levels[] = {
69: "debug_core", "debug_alloc", "debug_mutex", "debug_event",
70: "debug_http", "debug_mail", "debug_mysql"
71: };
72:
73:
74: #if (NGX_HAVE_VARIADIC_MACROS)
75:
76: void
77: ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
78: const char *fmt, ...)
79:
80: #else
81:
82: void
83: ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
84: const char *fmt, va_list args)
85:
86: #endif
87: {
88: #if (NGX_HAVE_VARIADIC_MACROS)
89: va_list args;
90: #endif
91: u_char *p, *last, *msg;
92: u_char errstr[NGX_MAX_ERROR_STR];
93:
94: if (log->file->fd == NGX_INVALID_FILE) {
95: return;
96: }
97:
98: last = errstr + NGX_MAX_ERROR_STR;
99:
100: ngx_memcpy(errstr, ngx_cached_err_log_time.data,
101: ngx_cached_err_log_time.len);
102:
103: p = errstr + ngx_cached_err_log_time.len;
104:
105: p = ngx_slprintf(p, last, " [%V] ", &err_levels[level]);
106:
107: /* pid#tid */
108: p = ngx_slprintf(p, last, "%P#" NGX_TID_T_FMT ": ",
109: ngx_log_pid, ngx_log_tid);
110:
111: if (log->connection) {
112: p = ngx_slprintf(p, last, "*%uA ", log->connection);
113: }
114:
115: msg = p;
116:
117: #if (NGX_HAVE_VARIADIC_MACROS)
118:
119: va_start(args, fmt);
120: p = ngx_vslprintf(p, last, fmt, args);
121: va_end(args);
122:
123: #else
124:
125: p = ngx_vslprintf(p, last, fmt, args);
126:
127: #endif
128:
129: if (err) {
130: p = ngx_log_errno(p, last, err);
131: }
132:
133: if (level != NGX_LOG_DEBUG && log->handler) {
134: p = log->handler(log, p, last - p);
135: }
136:
137: if (p > last - NGX_LINEFEED_SIZE) {
138: p = last - NGX_LINEFEED_SIZE;
139: }
140:
141: ngx_linefeed(p);
142:
143: (void) ngx_write_fd(log->file->fd, errstr, p - errstr);
144:
145: if (!ngx_use_stderr
146: || level > NGX_LOG_WARN
147: || log->file->fd == ngx_stderr)
148: {
149: return;
150: }
151:
152: msg -= (7 + err_levels[level].len + 3);
153:
154: (void) ngx_sprintf(msg, "nginx: [%V] ", &err_levels[level]);
155:
156: (void) ngx_write_console(ngx_stderr, msg, p - msg);
157: }
158:
159:
160: #if !(NGX_HAVE_VARIADIC_MACROS)
161:
162: void ngx_cdecl
163: ngx_log_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
164: const char *fmt, ...)
165: {
166: va_list args;
167:
168: if (log->log_level >= level) {
169: va_start(args, fmt);
170: ngx_log_error_core(level, log, err, fmt, args);
171: va_end(args);
172: }
173: }
174:
175:
176: void ngx_cdecl
177: ngx_log_debug_core(ngx_log_t *log, ngx_err_t err, const char *fmt, ...)
178: {
179: va_list args;
180:
181: va_start(args, fmt);
182: ngx_log_error_core(NGX_LOG_DEBUG, log, err, fmt, args);
183: va_end(args);
184: }
185:
186: #endif
187:
188:
189: void ngx_cdecl
190: ngx_log_abort(ngx_err_t err, const char *fmt, ...)
191: {
192: u_char *p;
193: va_list args;
194: u_char errstr[NGX_MAX_CONF_ERRSTR];
195:
196: va_start(args, fmt);
197: p = ngx_vsnprintf(errstr, sizeof(errstr) - 1, fmt, args);
198: va_end(args);
199:
200: ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err,
201: "%*s", p - errstr, errstr);
202: }
203:
204:
205: void ngx_cdecl
206: ngx_log_stderr(ngx_err_t err, const char *fmt, ...)
207: {
208: u_char *p, *last;
209: va_list args;
210: u_char errstr[NGX_MAX_ERROR_STR];
211:
212: last = errstr + NGX_MAX_ERROR_STR;
213: p = errstr + 7;
214:
215: ngx_memcpy(errstr, "nginx: ", 7);
216:
217: va_start(args, fmt);
218: p = ngx_vslprintf(p, last, fmt, args);
219: va_end(args);
220:
221: if (err) {
222: p = ngx_log_errno(p, last, err);
223: }
224:
225: if (p > last - NGX_LINEFEED_SIZE) {
226: p = last - NGX_LINEFEED_SIZE;
227: }
228:
229: ngx_linefeed(p);
230:
231: (void) ngx_write_console(ngx_stderr, errstr, p - errstr);
232: }
233:
234:
235: u_char *
236: ngx_log_errno(u_char *buf, u_char *last, ngx_err_t err)
237: {
238: if (buf > last - 50) {
239:
240: /* leave a space for an error code */
241:
242: buf = last - 50;
243: *buf++ = '.';
244: *buf++ = '.';
245: *buf++ = '.';
246: }
247:
248: #if (NGX_WIN32)
249: buf = ngx_slprintf(buf, last, ((unsigned) err < 0x80000000)
250: ? " (%d: " : " (%Xd: ", err);
251: #else
252: buf = ngx_slprintf(buf, last, " (%d: ", err);
253: #endif
254:
255: buf = ngx_strerror(err, buf, last - buf);
256:
257: if (buf < last) {
258: *buf++ = ')';
259: }
260:
261: return buf;
262: }
263:
264:
265: ngx_log_t *
266: ngx_log_init(u_char *prefix)
267: {
268: u_char *p, *name;
269: size_t nlen, plen;
270:
271: ngx_log.file = &ngx_log_file;
272: ngx_log.log_level = NGX_LOG_NOTICE;
273:
274: name = (u_char *) NGX_ERROR_LOG_PATH;
275:
276: /*
277: * we use ngx_strlen() here since BCC warns about
278: * condition is always false and unreachable code
279: */
280:
281: nlen = ngx_strlen(name);
282:
283: if (nlen == 0) {
284: ngx_log_file.fd = ngx_stderr;
285: return &ngx_log;
286: }
287:
288: p = NULL;
289:
290: #if (NGX_WIN32)
291: if (name[1] != ':') {
292: #else
293: if (name[0] != '/') {
294: #endif
295:
296: if (prefix) {
297: plen = ngx_strlen(prefix);
298:
299: } else {
300: #ifdef NGX_PREFIX
301: prefix = (u_char *) NGX_PREFIX;
302: plen = ngx_strlen(prefix);
303: #else
304: plen = 0;
305: #endif
306: }
307:
308: if (plen) {
309: name = malloc(plen + nlen + 2);
310: if (name == NULL) {
311: return NULL;
312: }
313:
314: p = ngx_cpymem(name, prefix, plen);
315:
316: if (!ngx_path_separator(*(p - 1))) {
317: *p++ = '/';
318: }
319:
320: ngx_cpystrn(p, (u_char *) NGX_ERROR_LOG_PATH, nlen + 1);
321:
322: p = name;
323: }
324: }
325:
326: ngx_log_file.fd = ngx_open_file(name, NGX_FILE_APPEND,
327: NGX_FILE_CREATE_OR_OPEN,
328: NGX_FILE_DEFAULT_ACCESS);
329:
330: if (ngx_log_file.fd == NGX_INVALID_FILE) {
331: ngx_log_stderr(ngx_errno,
332: "[alert] could not open error log file: "
333: ngx_open_file_n " \"%s\" failed", name);
334: #if (NGX_WIN32)
335: ngx_event_log(ngx_errno,
336: "could not open error log file: "
337: ngx_open_file_n " \"%s\" failed", name);
338: #endif
339:
340: ngx_log_file.fd = ngx_stderr;
341: }
342:
343: if (p) {
344: ngx_free(p);
345: }
346:
347: return &ngx_log;
348: }
349:
350:
351: ngx_log_t *
352: ngx_log_create(ngx_cycle_t *cycle, ngx_str_t *name)
353: {
354: ngx_log_t *log;
355:
356: log = ngx_pcalloc(cycle->pool, sizeof(ngx_log_t));
357: if (log == NULL) {
358: return NULL;
359: }
360:
361: log->file = ngx_conf_open_file(cycle, name);
362: if (log->file == NULL) {
363: return NULL;
364: }
365:
366: return log;
367: }
368:
369:
370: char *
371: ngx_log_set_levels(ngx_conf_t *cf, ngx_log_t *log)
372: {
373: ngx_uint_t i, n, d, found;
374: ngx_str_t *value;
375:
376: value = cf->args->elts;
377:
378: for (i = 2; i < cf->args->nelts; i++) {
379: found = 0;
380:
381: for (n = 1; n <= NGX_LOG_DEBUG; n++) {
382: if (ngx_strcmp(value[i].data, err_levels[n].data) == 0) {
383:
384: if (log->log_level != 0) {
385: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
386: "duplicate log level \"%V\"",
387: &value[i]);
388: return NGX_CONF_ERROR;
389: }
390:
391: log->log_level = n;
392: found = 1;
393: break;
394: }
395: }
396:
397: for (n = 0, d = NGX_LOG_DEBUG_FIRST; d <= NGX_LOG_DEBUG_LAST; d <<= 1) {
398: if (ngx_strcmp(value[i].data, debug_levels[n++]) == 0) {
399: if (log->log_level & ~NGX_LOG_DEBUG_ALL) {
400: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
401: "invalid log level \"%V\"",
402: &value[i]);
403: return NGX_CONF_ERROR;
404: }
405:
406: log->log_level |= d;
407: found = 1;
408: break;
409: }
410: }
411:
412:
413: if (!found) {
414: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
415: "invalid log level \"%V\"", &value[i]);
416: return NGX_CONF_ERROR;
417: }
418: }
419:
420: if (log->log_level == NGX_LOG_DEBUG) {
421: log->log_level = NGX_LOG_DEBUG_ALL;
422: }
423:
424: return NGX_CONF_OK;
425: }
426:
427:
428: static char *
429: ngx_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
430: {
431: ngx_str_t *value, name;
432:
433: if (cf->cycle->new_log.file) {
434: return "is duplicate";
435: }
436:
437: value = cf->args->elts;
438:
439: if (ngx_strcmp(value[1].data, "stderr") == 0) {
440: ngx_str_null(&name);
441:
442: } else {
443: name = value[1];
444: }
445:
446: cf->cycle->new_log.file = ngx_conf_open_file(cf->cycle, &name);
447: if (cf->cycle->new_log.file == NULL) {
448: return NULL;
449: }
450:
451: if (cf->args->nelts == 2) {
452: cf->cycle->new_log.log_level = NGX_LOG_ERR;
453: return NGX_CONF_OK;
454: }
455:
456: cf->cycle->new_log.log_level = 0;
457:
458: return ngx_log_set_levels(cf, &cf->cycle->new_log);
459: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>