Annotation of embedaddon/nginx/src/core/ngx_log.c, revision 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>