comparison 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
comparison
equal deleted inserted replaced
481:0c98173187ac 482:392c16f2d858
46 NGX_MODULE_V1_PADDING 46 NGX_MODULE_V1_PADDING
47 }; 47 };
48 48
49 49
50 static ngx_log_t ngx_log; 50 static ngx_log_t ngx_log;
51 static ngx_open_file_t ngx_stderr; 51 static ngx_open_file_t ngx_log_file;
52 52 ngx_uint_t ngx_use_stderr = 1;
53 53
54 static const char *err_levels[] = { 54
55 "stderr", "emerg", "alert", "crit", "error", 55 static ngx_str_t err_levels[] = {
56 "warn", "notice", "info", "debug" 56 ngx_string("stderr"),
57 ngx_string("emerg"),
58 ngx_string("alert"),
59 ngx_string("crit"),
60 ngx_string("error"),
61 ngx_string("warn"),
62 ngx_string("notice"),
63 ngx_string("info"),
64 ngx_string("debug")
57 }; 65 };
58 66
59 static const char *debug_levels[] = { 67 static const char *debug_levels[] = {
60 "debug_core", "debug_alloc", "debug_mutex", "debug_event", 68 "debug_core", "debug_alloc", "debug_mutex", "debug_event",
61 "debug_http", "debug_mail", "debug_mysql" 69 "debug_http", "debug_mail", "debug_mysql"
77 #endif 85 #endif
78 { 86 {
79 #if (NGX_HAVE_VARIADIC_MACROS) 87 #if (NGX_HAVE_VARIADIC_MACROS)
80 va_list args; 88 va_list args;
81 #endif 89 #endif
82 u_char errstr[NGX_MAX_ERROR_STR], *p, *last; 90 u_char *p, *last, *msg;
91 u_char errstr[NGX_MAX_ERROR_STR];
83 92
84 if (log->file->fd == NGX_INVALID_FILE) { 93 if (log->file->fd == NGX_INVALID_FILE) {
85 return; 94 return;
86 } 95 }
87 96
90 ngx_memcpy(errstr, ngx_cached_err_log_time.data, 99 ngx_memcpy(errstr, ngx_cached_err_log_time.data,
91 ngx_cached_err_log_time.len); 100 ngx_cached_err_log_time.len);
92 101
93 p = errstr + ngx_cached_err_log_time.len; 102 p = errstr + ngx_cached_err_log_time.len;
94 103
95 p = ngx_snprintf(p, last - p, " [%s] ", err_levels[level]); 104 p = ngx_snprintf(p, last - p, " [%V] ", &err_levels[level]);
96 105
97 /* pid#tid */ 106 /* pid#tid */
98 p = ngx_snprintf(p, last - p, "%P#" NGX_TID_T_FMT ": ", 107 p = ngx_snprintf(p, last - p, "%P#" NGX_TID_T_FMT ": ",
99 ngx_log_pid, ngx_log_tid); 108 ngx_log_pid, ngx_log_tid);
100 109
101 if (log->connection) { 110 if (log->connection) {
102 p = ngx_snprintf(p, last - p, "*%uA ", log->connection); 111 p = ngx_snprintf(p, last - p, "*%uA ", log->connection);
103 } 112 }
113
114 msg = p;
104 115
105 #if (NGX_HAVE_VARIADIC_MACROS) 116 #if (NGX_HAVE_VARIADIC_MACROS)
106 117
107 va_start(args, fmt); 118 va_start(args, fmt);
108 p = ngx_vsnprintf(p, last - p, fmt, args); 119 p = ngx_vsnprintf(p, last - p, fmt, args);
149 } 160 }
150 161
151 ngx_linefeed(p); 162 ngx_linefeed(p);
152 163
153 (void) ngx_write_fd(log->file->fd, errstr, p - errstr); 164 (void) ngx_write_fd(log->file->fd, errstr, p - errstr);
165
166 if (!ngx_use_stderr
167 || level > NGX_LOG_WARN
168 || log->file->fd == ngx_stderr)
169 {
170 return;
171 }
172
173 msg -= (err_levels[level].len + 4);
174
175 (void) ngx_sprintf(msg, "[%V]: ", &err_levels[level]);
176
177 (void) ngx_write_fd(ngx_stderr, msg, p - msg);
154 } 178 }
155 179
156 180
157 #if !(NGX_HAVE_VARIADIC_MACROS) 181 #if !(NGX_HAVE_VARIADIC_MACROS)
158 182
181 } 205 }
182 206
183 #endif 207 #endif
184 208
185 209
186 void
187 ngx_log_abort(ngx_err_t err, const char *text, void *param)
188 {
189 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err, text, param);
190 }
191
192
193 void ngx_cdecl 210 void ngx_cdecl
194 ngx_log_stderr(const char *fmt, ...) 211 ngx_log_abort(ngx_err_t err, const char *fmt, ...)
195 { 212 {
196 u_char *p; 213 u_char *p;
214 va_list args;
215 u_char errstr[NGX_MAX_CONF_ERRSTR];
216
217 va_start(args, fmt);
218 p = ngx_vsnprintf(errstr, sizeof(errstr) - 1, fmt, args);
219 va_end(args);
220
221 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err,
222 "%*s", p - errstr, errstr);
223 }
224
225
226 void ngx_cdecl
227 ngx_log_stderr(ngx_err_t err, const char *fmt, ...)
228 {
229 u_char *p, *last;
197 va_list args; 230 va_list args;
198 u_char errstr[NGX_MAX_ERROR_STR]; 231 u_char errstr[NGX_MAX_ERROR_STR];
199 232
200 va_start(args, fmt); 233 va_start(args, fmt);
201 p = ngx_vsnprintf(errstr, NGX_MAX_ERROR_STR, fmt, args); 234 p = ngx_vsnprintf(errstr, NGX_MAX_ERROR_STR, fmt, args);
203 236
204 if (p > errstr + NGX_MAX_ERROR_STR - NGX_LINEFEED_SIZE) { 237 if (p > errstr + NGX_MAX_ERROR_STR - NGX_LINEFEED_SIZE) {
205 p = errstr + NGX_MAX_ERROR_STR - NGX_LINEFEED_SIZE; 238 p = errstr + NGX_MAX_ERROR_STR - NGX_LINEFEED_SIZE;
206 } 239 }
207 240
241 if (err) {
242
243 last = errstr + NGX_MAX_ERROR_STR;
244
245 if (p > last - 50) {
246
247 /* leave a space for an error code */
248
249 p = last - 50;
250 *p++ = '.';
251 *p++ = '.';
252 *p++ = '.';
253 }
254
255 #if (NGX_WIN32)
256 p = ngx_snprintf(p, last - p, ((unsigned) err < 0x80000000)
257 ? " (%d: " : " (%Xd: ", err);
258 #else
259 p = ngx_snprintf(p, last - p, " (%d: ", err);
260 #endif
261
262 p = ngx_strerror_r(err, p, last - p);
263
264 if (p < last) {
265 *p++ = ')';
266 }
267 }
268
208 ngx_linefeed(p); 269 ngx_linefeed(p);
209 270
210 (void) ngx_write_fd(ngx_stderr_fileno, errstr, p - errstr); 271 (void) ngx_write_fd(ngx_stderr, errstr, p - errstr);
211 } 272 }
212 273
213 274
214 ngx_log_t * 275 ngx_log_t *
215 ngx_log_init(void) 276 ngx_log_init(u_char *prefix)
216 { 277 {
217 ngx_log.file = &ngx_stderr; 278 u_char *p, *name;
279 size_t nlen, plen;
280
281 ngx_log.file = &ngx_log_file;
218 ngx_log.log_level = NGX_LOG_NOTICE; 282 ngx_log.log_level = NGX_LOG_NOTICE;
219 283
284 name = (u_char *) NGX_ERROR_LOG_PATH;
285
286 /*
287 * we use ngx_strlen() here since BCC warns about
288 * condition is always false and unreachable code
289 */
290
291 nlen = ngx_strlen(name);
292
293 if (nlen == 0) {
294 ngx_log_file.fd = ngx_stderr;
295 return &ngx_log;
296 }
297
298 p = NULL;
299
220 #if (NGX_WIN32) 300 #if (NGX_WIN32)
221 301 if (name[1] != ':') {
222 ngx_stderr_fileno = GetStdHandle(STD_ERROR_HANDLE);
223
224 ngx_stderr.fd = ngx_open_file((u_char *) NGX_ERROR_LOG_PATH,
225 NGX_FILE_APPEND,
226 NGX_FILE_CREATE_OR_OPEN,
227 NGX_FILE_DEFAULT_ACCESS);
228
229 if (ngx_stderr.fd == NGX_INVALID_FILE) {
230 ngx_event_log(ngx_errno,
231 "Could not open error log file: "
232 ngx_open_file_n " \"" NGX_ERROR_LOG_PATH "\" failed");
233 return NULL;
234 }
235
236 #else 302 #else
237 303 if (name[0] != '/') {
238 ngx_stderr.fd = STDERR_FILENO; 304 #endif
239 305 plen = 0;
240 #endif 306
307 if (prefix) {
308 plen = ngx_strlen(prefix);
309
310 #ifdef NGX_PREFIX
311 } else {
312 prefix = (u_char *) NGX_PREFIX;
313 plen = ngx_strlen(prefix);
314 #endif
315 }
316
317 if (plen) {
318 name = malloc(plen + nlen + 2);
319 if (name == NULL) {
320 return NULL;
321 }
322
323 p = ngx_cpymem(name, prefix, plen);
324
325 if (!ngx_path_separator(*(p - 1))) {
326 *p++ = '/';
327 }
328
329 ngx_cpystrn(p, (u_char *) NGX_ERROR_LOG_PATH, nlen + 1);
330
331 p = name;
332 }
333 }
334
335 ngx_log_file.fd = ngx_open_file(name, NGX_FILE_APPEND,
336 NGX_FILE_CREATE_OR_OPEN,
337 NGX_FILE_DEFAULT_ACCESS);
338
339 if (ngx_log_file.fd == NGX_INVALID_FILE) {
340 ngx_log_stderr(ngx_errno,
341 "[alert]: could not open error log file: "
342 ngx_open_file_n " \"%s\" failed", name);
343 #if (NGX_WIN32)
344 ngx_event_log(ngx_errno,
345 "could not open error log file: "
346 ngx_open_file_n " \"%s\" failed", name);
347 #endif
348
349 ngx_log_file.fd = ngx_stderr;
350 }
351
352 if (p) {
353 ngx_free(p);
354 }
241 355
242 return &ngx_log; 356 return &ngx_log;
243 } 357 }
244 358
245 359
246 ngx_log_t * 360 ngx_log_t *
247 ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_array_t *args) 361 ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_str_t *name)
248 { 362 {
249 ngx_log_t *log; 363 ngx_log_t *log;
250 ngx_str_t *value, *name;
251
252 if (args) {
253 value = args->elts;
254 name = &value[1];
255
256 } else {
257 name = NULL;
258 }
259 364
260 log = ngx_pcalloc(cycle->pool, sizeof(ngx_log_t)); 365 log = ngx_pcalloc(cycle->pool, sizeof(ngx_log_t));
261 if (log == NULL) { 366 if (log == NULL) {
262 return NULL; 367 return NULL;
263 } 368 }
280 value = cf->args->elts; 385 value = cf->args->elts;
281 386
282 for (i = 2; i < cf->args->nelts; i++) { 387 for (i = 2; i < cf->args->nelts; i++) {
283 388
284 for (n = 1; n <= NGX_LOG_DEBUG; n++) { 389 for (n = 1; n <= NGX_LOG_DEBUG; n++) {
285 if (ngx_strcmp(value[i].data, err_levels[n]) == 0) { 390 if (ngx_strcmp(value[i].data, err_levels[n].data) == 0) {
286 391
287 if (log->log_level != 0) { 392 if (log->log_level != 0) {
288 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 393 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
289 "duplicate log level \"%s\"", 394 "duplicate log level \"%V\"",
290 value[i].data); 395 &value[i]);
291 return NGX_CONF_ERROR; 396 return NGX_CONF_ERROR;
292 } 397 }
293 398
294 log->log_level = n; 399 log->log_level = n;
295 continue; 400 continue;
298 403
299 for (n = 0, d = NGX_LOG_DEBUG_FIRST; d <= NGX_LOG_DEBUG_LAST; d <<= 1) { 404 for (n = 0, d = NGX_LOG_DEBUG_FIRST; d <= NGX_LOG_DEBUG_LAST; d <<= 1) {
300 if (ngx_strcmp(value[i].data, debug_levels[n++]) == 0) { 405 if (ngx_strcmp(value[i].data, debug_levels[n++]) == 0) {
301 if (log->log_level & ~NGX_LOG_DEBUG_ALL) { 406 if (log->log_level & ~NGX_LOG_DEBUG_ALL) {
302 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 407 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
303 "invalid log level \"%s\"", 408 "invalid log level \"%V\"",
304 value[i].data); 409 &value[i]);
305 return NGX_CONF_ERROR; 410 return NGX_CONF_ERROR;
306 } 411 }
307 412
308 log->log_level |= d; 413 log->log_level |= d;
309 } 414 }
310 } 415 }
311 416
312 417
313 if (log->log_level == 0) { 418 if (log->log_level == 0) {
314 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 419 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
315 "invalid log level \"%s\"", value[i].data); 420 "invalid log level \"%V\"", &value[i]);
316 return NGX_CONF_ERROR; 421 return NGX_CONF_ERROR;
317 } 422 }
318 } 423 }
319 424
320 if (log->log_level == 0) { 425 if (log->log_level == 0) {
334 ngx_str_t *value; 439 ngx_str_t *value;
335 440
336 value = cf->args->elts; 441 value = cf->args->elts;
337 442
338 if (value[1].len == 6 && ngx_strcmp(value[1].data, "stderr") == 0) { 443 if (value[1].len == 6 && ngx_strcmp(value[1].data, "stderr") == 0) {
339 cf->cycle->new_log->file->fd = ngx_stderr.fd; 444 cf->cycle->new_log->file->fd = ngx_stderr;
340 cf->cycle->new_log->file->name.len = 0; 445 cf->cycle->new_log->file->name.len = 0;
341 cf->cycle->new_log->file->name.data = NULL; 446 cf->cycle->new_log->file->name.data = NULL;
342 447
343 } else { 448 } else {
344 cf->cycle->new_log->file->name = value[1]; 449 cf->cycle->new_log->file->name = value[1];