3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
8 #include <ngx_config.h>
12 static char *ngx_error_log(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
);
15 static ngx_command_t ngx_errlog_commands
[] = {
17 {ngx_string("error_log"),
18 NGX_MAIN_CONF
|NGX_CONF_1MORE
,
28 static ngx_core_module_t ngx_errlog_module_ctx
= {
35 ngx_module_t ngx_errlog_module
= {
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 */
51 static ngx_log_t ngx_log
;
52 static ngx_open_file_t ngx_log_file
;
53 ngx_uint_t ngx_use_stderr
= 1;
56 static ngx_str_t err_levels
[] = {
68 static const char *debug_levels
[] = {
69 "debug_core", "debug_alloc", "debug_mutex", "debug_event",
70 "debug_http", "debug_mail", "debug_mysql"
74 #if (NGX_HAVE_VARIADIC_MACROS)
77 ngx_log_error_core(ngx_uint_t level
, ngx_log_t
*log
, ngx_err_t err
,
83 ngx_log_error_core(ngx_uint_t level
, ngx_log_t
*log
, ngx_err_t err
,
84 const char *fmt
, va_list args
)
88 #if (NGX_HAVE_VARIADIC_MACROS)
91 u_char
*p
, *last
, *msg
;
92 u_char errstr
[NGX_MAX_ERROR_STR
];
94 if (log
->file
->fd
== NGX_INVALID_FILE
) {
98 last
= errstr
+ NGX_MAX_ERROR_STR
;
100 ngx_memcpy(errstr
, ngx_cached_err_log_time
.data
,
101 ngx_cached_err_log_time
.len
);
103 p
= errstr
+ ngx_cached_err_log_time
.len
;
105 p
= ngx_slprintf(p
, last
, " [%V] ", &err_levels
[level
]);
108 p
= ngx_slprintf(p
, last
, "%P#" NGX_TID_T_FMT
": ",
109 ngx_log_pid
, ngx_log_tid
);
111 if (log
->connection
) {
112 p
= ngx_slprintf(p
, last
, "*%uA ", log
->connection
);
117 #if (NGX_HAVE_VARIADIC_MACROS)
120 p
= ngx_vslprintf(p
, last
, fmt
, args
);
125 p
= ngx_vslprintf(p
, last
, fmt
, args
);
130 p
= ngx_log_errno(p
, last
, err
);
133 if (level
!= NGX_LOG_DEBUG
&& log
->handler
) {
134 p
= log
->handler(log
, p
, last
- p
);
137 if (p
> last
- NGX_LINEFEED_SIZE
) {
138 p
= last
- NGX_LINEFEED_SIZE
;
143 (void) ngx_write_fd(log
->file
->fd
, errstr
, p
- errstr
);
146 || level
> NGX_LOG_WARN
147 || log
->file
->fd
== ngx_stderr
)
152 msg
-= (7 + err_levels
[level
].len
+ 3);
154 (void) ngx_sprintf(msg
, "nginx: [%V] ", &err_levels
[level
]);
156 (void) ngx_write_console(ngx_stderr
, msg
, p
- msg
);
160 #if !(NGX_HAVE_VARIADIC_MACROS)
163 ngx_log_error(ngx_uint_t level
, ngx_log_t
*log
, ngx_err_t err
,
164 const char *fmt
, ...)
168 if (log
->log_level
>= level
) {
170 ngx_log_error_core(level
, log
, err
, fmt
, args
);
177 ngx_log_debug_core(ngx_log_t
*log
, ngx_err_t err
, const char *fmt
, ...)
182 ngx_log_error_core(NGX_LOG_DEBUG
, log
, err
, fmt
, args
);
190 ngx_log_abort(ngx_err_t err
, const char *fmt
, ...)
194 u_char errstr
[NGX_MAX_CONF_ERRSTR
];
197 p
= ngx_vsnprintf(errstr
, sizeof(errstr
) - 1, fmt
, args
);
200 ngx_log_error(NGX_LOG_ALERT
, ngx_cycle
->log
, err
,
201 "%*s", p
- errstr
, errstr
);
206 ngx_log_stderr(ngx_err_t err
, const char *fmt
, ...)
210 u_char errstr
[NGX_MAX_ERROR_STR
];
212 last
= errstr
+ NGX_MAX_ERROR_STR
;
215 ngx_memcpy(errstr
, "nginx: ", 7);
218 p
= ngx_vslprintf(p
, last
, fmt
, args
);
222 p
= ngx_log_errno(p
, last
, err
);
225 if (p
> last
- NGX_LINEFEED_SIZE
) {
226 p
= last
- NGX_LINEFEED_SIZE
;
231 (void) ngx_write_console(ngx_stderr
, errstr
, p
- errstr
);
236 ngx_log_errno(u_char
*buf
, u_char
*last
, ngx_err_t err
)
238 if (buf
> last
- 50) {
240 /* leave a space for an error code */
249 buf
= ngx_slprintf(buf
, last
, ((unsigned) err
< 0x80000000)
250 ? " (%d: " : " (%Xd: ", err
);
252 buf
= ngx_slprintf(buf
, last
, " (%d: ", err
);
255 buf
= ngx_strerror(err
, buf
, last
- buf
);
266 ngx_log_init(u_char
*prefix
)
271 ngx_log
.file
= &ngx_log_file
;
272 ngx_log
.log_level
= NGX_LOG_NOTICE
;
274 name
= (u_char
*) NGX_ERROR_LOG_PATH
;
277 * we use ngx_strlen() here since BCC warns about
278 * condition is always false and unreachable code
281 nlen
= ngx_strlen(name
);
284 ngx_log_file
.fd
= ngx_stderr
;
291 if (name
[1] != ':') {
293 if (name
[0] != '/') {
297 plen
= ngx_strlen(prefix
);
301 prefix
= (u_char
*) NGX_PREFIX
;
302 plen
= ngx_strlen(prefix
);
309 name
= malloc(plen
+ nlen
+ 2);
314 p
= ngx_cpymem(name
, prefix
, plen
);
316 if (!ngx_path_separator(*(p
- 1))) {
320 ngx_cpystrn(p
, (u_char
*) NGX_ERROR_LOG_PATH
, nlen
+ 1);
326 ngx_log_file
.fd
= ngx_open_file(name
, NGX_FILE_APPEND
,
327 NGX_FILE_CREATE_OR_OPEN
,
328 NGX_FILE_DEFAULT_ACCESS
);
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
);
335 ngx_event_log(ngx_errno
,
336 "could not open error log file: "
337 ngx_open_file_n
" \"%s\" failed", name
);
340 ngx_log_file
.fd
= ngx_stderr
;
352 ngx_log_create(ngx_cycle_t
*cycle
, ngx_str_t
*name
)
356 log
= ngx_pcalloc(cycle
->pool
, sizeof(ngx_log_t
));
361 log
->file
= ngx_conf_open_file(cycle
, name
);
362 if (log
->file
== NULL
) {
371 ngx_log_set_levels(ngx_conf_t
*cf
, ngx_log_t
*log
)
373 ngx_uint_t i
, n
, d
, found
;
376 value
= cf
->args
->elts
;
378 for (i
= 2; i
< cf
->args
->nelts
; i
++) {
381 for (n
= 1; n
<= NGX_LOG_DEBUG
; n
++) {
382 if (ngx_strcmp(value
[i
].data
, err_levels
[n
].data
) == 0) {
384 if (log
->log_level
!= 0) {
385 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
386 "duplicate log level \"%V\"",
388 return NGX_CONF_ERROR
;
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\"",
403 return NGX_CONF_ERROR
;
414 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
415 "invalid log level \"%V\"", &value
[i
]);
416 return NGX_CONF_ERROR
;
420 if (log
->log_level
== NGX_LOG_DEBUG
) {
421 log
->log_level
= NGX_LOG_DEBUG_ALL
;
429 ngx_error_log(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
431 ngx_str_t
*value
, name
;
433 if (cf
->cycle
->new_log
.file
) {
434 return "is duplicate";
437 value
= cf
->args
->elts
;
439 if (ngx_strcmp(value
[1].data
, "stderr") == 0) {
446 cf
->cycle
->new_log
.file
= ngx_conf_open_file(cf
->cycle
, &name
);
447 if (cf
->cycle
->new_log
.file
== NULL
) {
451 if (cf
->args
->nelts
== 2) {
452 cf
->cycle
->new_log
.log_level
= NGX_LOG_ERR
;
456 cf
->cycle
->new_log
.log_level
= 0;
458 return ngx_log_set_levels(cf
, &cf
->cycle
->new_log
);