diff src/core/ngx_log.c @ 482:392c16f2d858 NGINX_0_7_53

nginx 0.7.53 *) Change: now a log set by --error-log-path is created from the very start-up. *) Feature: now the start up errors and warnings are outputted to an error_log and stderr. *) Feature: the empty --prefix= configure parameter forces nginx to use a directory where it was run as prefix. *) Feature: the -p switch. *) Feature: the -s switch on Unix platforms. *) Feature: the -? and -h switches. Thanks to Jerome Loyet. *) Feature: now switches may be set in condensed form. *) Bugfix: nginx/Windows did not work if configuration file was given by the -c switch. *) Bugfix: temporary files might be not removed if the "proxy_store", "fastcgi_store", "proxy_cache", or "fastcgi_cache" were used. Thanks to Maxim Dounin. *) Bugfix: an incorrect value was passed to mail proxy authentication server in "Auth-Method" header line; the bug had appeared in 0.7.34. Thanks to Simon Lecaille. *) Bugfix: system error text descriptions were not logged on Linux; the bug had appeared in 0.7.45. *) Bugfix: the "fastcgi_cache_min_uses" directive did not work. Thanks to Andrew Vorobyoff.
author Igor Sysoev <http://sysoev.ru>
date Mon, 27 Apr 2009 00:00:00 +0400
parents 549994537f15
children ed5e10fb40fc
line wrap: on
line diff
--- a/src/core/ngx_log.c
+++ b/src/core/ngx_log.c
@@ -48,12 +48,20 @@ ngx_module_t  ngx_errlog_module = {
 
 
 static ngx_log_t        ngx_log;
-static ngx_open_file_t  ngx_stderr;
+static ngx_open_file_t  ngx_log_file;
+ngx_uint_t              ngx_use_stderr = 1;
 
 
-static const char *err_levels[] = {
-    "stderr", "emerg", "alert", "crit", "error",
-    "warn", "notice", "info", "debug"
+static ngx_str_t err_levels[] = {
+    ngx_string("stderr"),
+    ngx_string("emerg"),
+    ngx_string("alert"),
+    ngx_string("crit"),
+    ngx_string("error"),
+    ngx_string("warn"),
+    ngx_string("notice"),
+    ngx_string("info"),
+    ngx_string("debug")
 };
 
 static const char *debug_levels[] = {
@@ -79,7 +87,8 @@ ngx_log_error_core(ngx_uint_t level, ngx
 #if (NGX_HAVE_VARIADIC_MACROS)
     va_list  args;
 #endif
-    u_char   errstr[NGX_MAX_ERROR_STR], *p, *last;
+    u_char  *p, *last, *msg;
+    u_char   errstr[NGX_MAX_ERROR_STR];
 
     if (log->file->fd == NGX_INVALID_FILE) {
         return;
@@ -92,7 +101,7 @@ ngx_log_error_core(ngx_uint_t level, ngx
 
     p = errstr + ngx_cached_err_log_time.len;
 
-    p = ngx_snprintf(p, last - p, " [%s] ", err_levels[level]);
+    p = ngx_snprintf(p, last - p, " [%V] ", &err_levels[level]);
 
     /* pid#tid */
     p = ngx_snprintf(p, last - p, "%P#" NGX_TID_T_FMT ": ",
@@ -102,6 +111,8 @@ ngx_log_error_core(ngx_uint_t level, ngx
         p = ngx_snprintf(p, last - p, "*%uA ", log->connection);
     }
 
+    msg = p;
+
 #if (NGX_HAVE_VARIADIC_MACROS)
 
     va_start(args, fmt);
@@ -151,6 +162,19 @@ ngx_log_error_core(ngx_uint_t level, ngx
     ngx_linefeed(p);
 
     (void) ngx_write_fd(log->file->fd, errstr, p - errstr);
+
+    if (!ngx_use_stderr
+        || level > NGX_LOG_WARN
+        || log->file->fd == ngx_stderr)
+    {
+        return;
+    }
+
+    msg -= (err_levels[level].len + 4);
+
+    (void) ngx_sprintf(msg, "[%V]: ", &err_levels[level]);
+
+    (void) ngx_write_fd(ngx_stderr, msg, p - msg);
 }
 
 
@@ -183,17 +207,26 @@ ngx_log_debug_core(ngx_log_t *log, ngx_e
 #endif
 
 
-void
-ngx_log_abort(ngx_err_t err, const char *text, void *param)
+void ngx_cdecl
+ngx_log_abort(ngx_err_t err, const char *fmt, ...)
 {
-    ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err, text, param);
+    u_char   *p;
+    va_list   args;
+    u_char    errstr[NGX_MAX_CONF_ERRSTR];
+
+    va_start(args, fmt);
+    p = ngx_vsnprintf(errstr, sizeof(errstr) - 1, fmt, args);
+    va_end(args);
+
+    ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err,
+                  "%*s", p - errstr, errstr);
 }
 
 
 void ngx_cdecl
-ngx_log_stderr(const char *fmt, ...)
+ngx_log_stderr(ngx_err_t err, const char *fmt, ...)
 {
-    u_char   *p;
+    u_char   *p, *last;
     va_list   args;
     u_char    errstr[NGX_MAX_ERROR_STR];
 
@@ -205,57 +238,129 @@ ngx_log_stderr(const char *fmt, ...)
         p = errstr + NGX_MAX_ERROR_STR - NGX_LINEFEED_SIZE;
     }
 
+    if (err) {
+
+        last = errstr + NGX_MAX_ERROR_STR;
+
+        if (p > last - 50) {
+
+            /* leave a space for an error code */
+
+            p = last - 50;
+            *p++ = '.';
+            *p++ = '.';
+            *p++ = '.';
+        }
+
+#if (NGX_WIN32)
+        p = ngx_snprintf(p, last - p, ((unsigned) err < 0x80000000)
+                                           ? " (%d: " : " (%Xd: ", err);
+#else
+        p = ngx_snprintf(p, last - p, " (%d: ", err);
+#endif
+
+        p = ngx_strerror_r(err, p, last - p);
+
+        if (p < last) {
+            *p++ = ')';
+        }
+    }
+
     ngx_linefeed(p);
 
-    (void) ngx_write_fd(ngx_stderr_fileno, errstr, p - errstr);
+    (void) ngx_write_fd(ngx_stderr, errstr, p - errstr);
 }
 
 
 ngx_log_t *
-ngx_log_init(void)
+ngx_log_init(u_char *prefix)
 {
-    ngx_log.file = &ngx_stderr;
+    u_char  *p, *name;
+    size_t   nlen, plen;
+
+    ngx_log.file = &ngx_log_file;
     ngx_log.log_level = NGX_LOG_NOTICE;
 
+    name = (u_char *) NGX_ERROR_LOG_PATH;
+
+    /*
+     * we use ngx_strlen() here since BCC warns about
+     * condition is always false and unreachable code
+     */
+
+    nlen = ngx_strlen(name);
+
+    if (nlen == 0) {
+        ngx_log_file.fd = ngx_stderr;
+        return &ngx_log;
+    }
+
+    p = NULL;
+
 #if (NGX_WIN32)
+    if (name[1] != ':') {
+#else
+    if (name[0] != '/') {
+#endif
+        plen = 0;
 
-    ngx_stderr_fileno = GetStdHandle(STD_ERROR_HANDLE);
+        if (prefix) {
+            plen = ngx_strlen(prefix);
+
+#ifdef NGX_PREFIX
+        } else {
+            prefix = (u_char *) NGX_PREFIX;
+            plen = ngx_strlen(prefix);
+#endif
+        }
 
-    ngx_stderr.fd = ngx_open_file((u_char *) NGX_ERROR_LOG_PATH,
-                                  NGX_FILE_APPEND,
-                                  NGX_FILE_CREATE_OR_OPEN,
-                                  NGX_FILE_DEFAULT_ACCESS);
+        if (plen) {
+            name = malloc(plen + nlen + 2);
+            if (name == NULL) {
+                return NULL;
+            }
+
+            p = ngx_cpymem(name, prefix, plen);
 
-    if (ngx_stderr.fd == NGX_INVALID_FILE) {
-        ngx_event_log(ngx_errno, 
-                      "Could not open error log file: "
-                      ngx_open_file_n " \"" NGX_ERROR_LOG_PATH "\" failed");
-        return NULL;
+            if (!ngx_path_separator(*(p - 1))) {
+                *p++ = '/';
+            }
+
+            ngx_cpystrn(p, (u_char *) NGX_ERROR_LOG_PATH, nlen + 1);
+
+            p = name;
+        }
     }
 
-#else
+    ngx_log_file.fd = ngx_open_file(name, NGX_FILE_APPEND,
+                                    NGX_FILE_CREATE_OR_OPEN,
+                                    NGX_FILE_DEFAULT_ACCESS);
 
-    ngx_stderr.fd = STDERR_FILENO;
+    if (ngx_log_file.fd == NGX_INVALID_FILE) {
+        ngx_log_stderr(ngx_errno,
+                       "[alert]: could not open error log file: "
+                       ngx_open_file_n " \"%s\" failed", name);
+#if (NGX_WIN32)
+        ngx_event_log(ngx_errno,
+                       "could not open error log file: "
+                       ngx_open_file_n " \"%s\" failed", name);
+#endif
 
-#endif
+        ngx_log_file.fd = ngx_stderr;
+    }
+
+    if (p) {
+        ngx_free(p);
+    }
 
     return &ngx_log;
 }
 
 
 ngx_log_t *
-ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_array_t *args)
+ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_str_t *name)
 {
     ngx_log_t  *log;
-    ngx_str_t  *value, *name;
-
-    if (args) {
-        value = args->elts;
-        name = &value[1];
-
-    } else {
-        name = NULL;
-    }
 
     log = ngx_pcalloc(cycle->pool, sizeof(ngx_log_t));
     if (log == NULL) {
@@ -282,12 +387,12 @@ ngx_set_error_log_levels(ngx_conf_t *cf,
     for (i = 2; i < cf->args->nelts; i++) {
 
         for (n = 1; n <= NGX_LOG_DEBUG; n++) {
-            if (ngx_strcmp(value[i].data, err_levels[n]) == 0) {
+            if (ngx_strcmp(value[i].data, err_levels[n].data) == 0) {
 
                 if (log->log_level != 0) {
                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                                       "duplicate log level \"%s\"",
-                                       value[i].data);
+                                       "duplicate log level \"%V\"",
+                                       &value[i]);
                     return NGX_CONF_ERROR;
                 }
 
@@ -300,8 +405,8 @@ ngx_set_error_log_levels(ngx_conf_t *cf,
             if (ngx_strcmp(value[i].data, debug_levels[n++]) == 0) {
                 if (log->log_level & ~NGX_LOG_DEBUG_ALL) {
                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                                       "invalid log level \"%s\"",
-                                       value[i].data);
+                                       "invalid log level \"%V\"",
+                                       &value[i]);
                     return NGX_CONF_ERROR;
                 }
 
@@ -312,7 +417,7 @@ ngx_set_error_log_levels(ngx_conf_t *cf,
 
         if (log->log_level == 0) {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                               "invalid log level \"%s\"", value[i].data);
+                               "invalid log level \"%V\"", &value[i]);
             return NGX_CONF_ERROR;
         }
     }
@@ -336,7 +441,7 @@ ngx_set_error_log(ngx_conf_t *cf, ngx_co
     value = cf->args->elts;
 
     if (value[1].len == 6 && ngx_strcmp(value[1].data, "stderr") == 0) {
-        cf->cycle->new_log->file->fd = ngx_stderr.fd;
+        cf->cycle->new_log->file->fd = ngx_stderr;
         cf->cycle->new_log->file->name.len = 0;
         cf->cycle->new_log->file->name.data = NULL;