blob: 1f7bb11a9efc84d17a9f5933c39c353a92ca4f75 [file] [log] [blame]
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00001
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00002#include <ngx_config.h>
Igor Sysoev1c13c662003-05-20 15:37:55 +00003#include <ngx_core.h>
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00004
5
Igor Sysoevd8e1f072004-01-22 06:47:28 +00006static void ngx_log_write(ngx_log_t *log, char *errstr, size_t len);
Igor Sysoev1c104622003-06-03 15:42:58 +00007static char *ngx_set_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
8
9
10static ngx_str_t errlog_name = ngx_string("errlog");
11
12static ngx_command_t ngx_errlog_commands[] = {
13
14 {ngx_string("error_log"),
Igor Sysoev5f800782003-12-08 20:48:12 +000015 NGX_MAIN_CONF|NGX_CONF_1MORE,
Igor Sysoev1c104622003-06-03 15:42:58 +000016 ngx_set_error_log,
17 0,
18 0,
19 NULL},
20
21 ngx_null_command
22};
23
24
25ngx_module_t ngx_errlog_module = {
26 NGX_MODULE,
27 &errlog_name, /* module context */
28 ngx_errlog_commands, /* module directives */
29 NGX_CORE_MODULE, /* module type */
Igor Sysoeva7f7fa82003-07-11 04:50:59 +000030 NULL, /* init module */
31 NULL /* init child */
Igor Sysoev1c104622003-06-03 15:42:58 +000032};
33
34
Igor Sysoevf5e97c52003-06-26 15:35:36 +000035static ngx_open_file_t ngx_stderr;
36static ngx_log_t ngx_log;
Igor Sysoev1c104622003-06-03 15:42:58 +000037
38
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000039static const char *err_levels[] = {
Igor Sysoev1c13c662003-05-20 15:37:55 +000040 "stderr", "emerg", "alert", "crit", "error",
41 "warn", "notice", "info", "debug"
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000042};
43
Igor Sysoev5f800782003-12-08 20:48:12 +000044static const char *debug_levels[] = {
Igor Sysoev3c3ca172004-01-05 20:55:48 +000045 "debug", "debug_core", "debug_alloc", "debug_event", "debug_http"
Igor Sysoev5f800782003-12-08 20:48:12 +000046};
47
48
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000049#if (HAVE_VARIADIC_MACROS)
50void ngx_log_error_core(int level, ngx_log_t *log, ngx_err_t err,
51 const char *fmt, ...)
52#else
53void ngx_log_error_core(int level, ngx_log_t *log, ngx_err_t err,
54 const char *fmt, va_list args)
55#endif
56{
Igor Sysoev1c13c662003-05-20 15:37:55 +000057 char errstr[MAX_ERROR_STR];
Igor Sysoevd8e1f072004-01-22 06:47:28 +000058 size_t len, max;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000059#if (HAVE_VARIADIC_MACROS)
Igor Sysoev1c13c662003-05-20 15:37:55 +000060 va_list args;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000061#endif
62
Igor Sysoev890fc962003-07-20 21:15:59 +000063 if (log->file->fd == NGX_INVALID_FILE) {
64 return;
65 }
66
Igor Sysoev562e53e2003-11-13 06:14:05 +000067 ngx_memcpy(errstr, ngx_cached_err_log_time.data,
68 ngx_cached_err_log_time.len);
69
Igor Sysoevd8e1f072004-01-22 06:47:28 +000070#if (WIN32)
71 max = MAX_ERROR_STR - 2;
72#else
73 max = MAX_ERROR_STR - 1;
74#endif
75
Igor Sysoev562e53e2003-11-13 06:14:05 +000076 len = ngx_cached_err_log_time.len;
77
Igor Sysoevd8e1f072004-01-22 06:47:28 +000078 len += ngx_snprintf(errstr + len, max - len, " [%s] ", err_levels[level]);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000079
Igor Sysoeva6717c42002-12-23 06:29:22 +000080 /* pid#tid */
Igor Sysoevd8e1f072004-01-22 06:47:28 +000081 len += ngx_snprintf(errstr + len, max - len,
Igor Sysoeva2aca9a2004-01-18 21:09:21 +000082 PID_T_FMT "#%d: ", ngx_getpid(), /* STUB */ 0);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000083
Igor Sysoev160d7742003-11-19 16:26:41 +000084 if (log->data) {
Igor Sysoevd8e1f072004-01-22 06:47:28 +000085 len += ngx_snprintf(errstr + len, max - len,
Igor Sysoev160d7742003-11-19 16:26:41 +000086 "*%u ", * (u_int *) log->data);
87 }
88
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000089#if (HAVE_VARIADIC_MACROS)
Igor Sysoev160d7742003-11-19 16:26:41 +000090
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000091 va_start(args, fmt);
Igor Sysoevd8e1f072004-01-22 06:47:28 +000092 len += ngx_vsnprintf(errstr + len, max - len, fmt, args);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000093 va_end(args);
Igor Sysoev160d7742003-11-19 16:26:41 +000094
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000095#else
Igor Sysoev160d7742003-11-19 16:26:41 +000096
Igor Sysoevd8e1f072004-01-22 06:47:28 +000097 len += ngx_vsnprintf(errstr + len, max - len, fmt, args);
Igor Sysoev160d7742003-11-19 16:26:41 +000098
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000099#endif
100
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000101 if (err) {
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000102
Igor Sysoevd8e1f072004-01-22 06:47:28 +0000103 if (len > max - 50) {
Igor Sysoev2f2491b2004-01-21 16:38:54 +0000104 /* leave a space for an error code */
Igor Sysoevd8e1f072004-01-22 06:47:28 +0000105 len = max - 50;
Igor Sysoev2f2491b2004-01-21 16:38:54 +0000106 errstr[len++] = '.';
107 errstr[len++] = '.';
108 errstr[len++] = '.';
109 }
110
Igor Sysoeva6717c42002-12-23 06:29:22 +0000111#if (WIN32)
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000112 if ((unsigned) err >= 0x80000000) {
Igor Sysoevd8e1f072004-01-22 06:47:28 +0000113 len += ngx_snprintf(errstr + len, max - len, " (%X: ", err);
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000114 } else {
Igor Sysoevd8e1f072004-01-22 06:47:28 +0000115 len += ngx_snprintf(errstr + len, max - len, " (%d: ", err);
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000116 }
117#else
Igor Sysoevd8e1f072004-01-22 06:47:28 +0000118 len += ngx_snprintf(errstr + len, max - len, " (%d: ", err);
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000119#endif
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000120
Igor Sysoevd8e1f072004-01-22 06:47:28 +0000121 if (len >= max) {
122 ngx_log_write(log, errstr, max);
Igor Sysoev2f2491b2004-01-21 16:38:54 +0000123 return;
124 }
125
Igor Sysoevd8e1f072004-01-22 06:47:28 +0000126 len += ngx_strerror_r(err, errstr + len, max - len);
Igor Sysoev2f2491b2004-01-21 16:38:54 +0000127
Igor Sysoevd8e1f072004-01-22 06:47:28 +0000128 if (len >= max) {
129 ngx_log_write(log, errstr, max);
Igor Sysoev2f2491b2004-01-21 16:38:54 +0000130 return;
131 }
132
133 errstr[len++] = ')';
134
Igor Sysoevd8e1f072004-01-22 06:47:28 +0000135 if (len >= max) {
136 ngx_log_write(log, errstr, max);
Igor Sysoev2f2491b2004-01-21 16:38:54 +0000137 return;
138 }
139
140 } else {
Igor Sysoevd8e1f072004-01-22 06:47:28 +0000141 if (len >= max) {
142 ngx_log_write(log, errstr, max);
Igor Sysoev2f2491b2004-01-21 16:38:54 +0000143 return;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000144 }
145 }
146
Igor Sysoeva6717c42002-12-23 06:29:22 +0000147 if (level != NGX_LOG_DEBUG && log->handler) {
Igor Sysoevd8e1f072004-01-22 06:47:28 +0000148 len += log->handler(log->data, errstr + len, max - len);
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000149
Igor Sysoevd8e1f072004-01-22 06:47:28 +0000150 if (len >= max) {
151 len = max;
Igor Sysoev2f2491b2004-01-21 16:38:54 +0000152 }
Igor Sysoeva6717c42002-12-23 06:29:22 +0000153 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000154
Igor Sysoevd8e1f072004-01-22 06:47:28 +0000155 ngx_log_write(log, errstr, len);
156}
157
158
159static void ngx_log_write(ngx_log_t *log, char *errstr, size_t len)
160{
Igor Sysoeva6717c42002-12-23 06:29:22 +0000161#if (WIN32)
Igor Sysoevd8e1f072004-01-22 06:47:28 +0000162 u_long written;
Igor Sysoev890fc962003-07-20 21:15:59 +0000163
164 errstr[len++] = CR;
165 errstr[len++] = LF;
166 WriteFile(log->file->fd, errstr, len, &written, NULL);
167
Igor Sysoev1c104622003-06-03 15:42:58 +0000168#else
Igor Sysoev890fc962003-07-20 21:15:59 +0000169
170 errstr[len++] = LF;
Igor Sysoevf5e97c52003-06-26 15:35:36 +0000171 write(log->file->fd, errstr, len);
Igor Sysoev1c104622003-06-03 15:42:58 +0000172
Igor Sysoeva6717c42002-12-23 06:29:22 +0000173#endif
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000174}
175
Igor Sysoev1c13c662003-05-20 15:37:55 +0000176
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000177#if !(HAVE_VARIADIC_MACROS)
178
179void ngx_log_error(int level, ngx_log_t *log, ngx_err_t err,
180 const char *fmt, ...)
181{
182 va_list args;
183
184 if (log->log_level >= level) {
185 va_start(args, fmt);
186 ngx_log_error_core(level, log, err, fmt, args);
187 va_end(args);
188 }
189}
190
Igor Sysoev1c13c662003-05-20 15:37:55 +0000191
Igor Sysoev865c1502003-11-30 20:03:18 +0000192void ngx_log_debug_core(ngx_log_t *log, ngx_err_t err, const char *fmt, ...)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000193{
194 va_list args;
195
196 va_start(args, fmt);
Igor Sysoev865c1502003-11-30 20:03:18 +0000197 ngx_log_error_core(NGX_LOG_DEBUG, log, err, fmt, args);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000198 va_end(args);
199}
200
Igor Sysoev1c13c662003-05-20 15:37:55 +0000201
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000202void ngx_assert_core(ngx_log_t *log, const char *fmt, ...)
203{
204 va_list args;
205
206 va_start(args, fmt);
207 ngx_log_error_core(NGX_LOG_ALERT, log, 0, fmt, args);
208 va_end(args);
209}
210
211#endif
Igor Sysoev1c13c662003-05-20 15:37:55 +0000212
213
Igor Sysoev1c104622003-06-03 15:42:58 +0000214#if 0
215
Igor Sysoev1c13c662003-05-20 15:37:55 +0000216void ngx_log_stderr(ngx_event_t *ev)
217{
218 char errstr[MAX_ERROR_STR];
219 ssize_t n;
220 ngx_err_t err;
221
222 for ( ;; ) {
223 n = read((ngx_fd_t) ev->data, errstr, sizeof(errstr - 1));
224
225 if (n == -1) {
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000226 err = ngx_errno;
Igor Sysoev1c13c662003-05-20 15:37:55 +0000227 if (err == NGX_EAGAIN) {
228 return;
229 }
230
231 ngx_log_error(NGX_LOG_ALERT, &ngx_log, err, "read() failed");
232 return;
233 }
234
235 if (n == 0) {
236 ngx_log_error(NGX_LOG_ALERT, &ngx_log, 0, "stderr clolsed");
237 return;
238 }
239
240 errstr[n] = '\0';
241 ngx_log_error(NGX_LOG_STDERR, &ngx_log, 0, "%s", errstr);
242 }
243}
Igor Sysoev1c104622003-06-03 15:42:58 +0000244
245#endif
246
247
Igor Sysoev1c104622003-06-03 15:42:58 +0000248
249ngx_log_t *ngx_log_init_errlog()
250{
251#if (WIN32)
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000252
Igor Sysoevf5e97c52003-06-26 15:35:36 +0000253 ngx_stderr.fd = GetStdHandle(STD_ERROR_HANDLE);
Igor Sysoev1c104622003-06-03 15:42:58 +0000254
Igor Sysoevf5e97c52003-06-26 15:35:36 +0000255 if (ngx_stderr.fd == NGX_INVALID_FILE) {
Igor Sysoev62260f22003-12-05 17:07:27 +0000256 /* TODO: where can we log error ? */
Igor Sysoev1c104622003-06-03 15:42:58 +0000257 return NULL;
258
Igor Sysoevf5e97c52003-06-26 15:35:36 +0000259 } else if (ngx_stderr.fd == NULL) {
Igor Sysoev62260f22003-12-05 17:07:27 +0000260
Igor Sysoev1c104622003-06-03 15:42:58 +0000261 /* there are no associated standard handles */
Igor Sysoev62260f22003-12-05 17:07:27 +0000262
263 /* TODO: where can we can log possible errors ? */
Igor Sysoev890fc962003-07-20 21:15:59 +0000264
265 ngx_stderr.fd = NGX_INVALID_FILE;
Igor Sysoev1c104622003-06-03 15:42:58 +0000266 }
267
268#else
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000269
Igor Sysoevf5e97c52003-06-26 15:35:36 +0000270 ngx_stderr.fd = STDERR_FILENO;
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000271
Igor Sysoev1c104622003-06-03 15:42:58 +0000272#endif
273
Igor Sysoevf5e97c52003-06-26 15:35:36 +0000274 ngx_log.file = &ngx_stderr;
Igor Sysoev1c104622003-06-03 15:42:58 +0000275 ngx_log.log_level = NGX_LOG_INFO;
Igor Sysoev62260f22003-12-05 17:07:27 +0000276
277#if 0
Igor Sysoev1c104622003-06-03 15:42:58 +0000278 /* STUB */ ngx_log.log_level = NGX_LOG_DEBUG;
Igor Sysoev62260f22003-12-05 17:07:27 +0000279#endif
Igor Sysoev1c104622003-06-03 15:42:58 +0000280
281 return &ngx_log;
282}
283
284
Igor Sysoev5f800782003-12-08 20:48:12 +0000285ngx_log_t *ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_array_t *args)
Igor Sysoev96c56c92003-07-02 14:41:17 +0000286{
287 ngx_log_t *log;
Igor Sysoev5f800782003-12-08 20:48:12 +0000288 ngx_str_t *value, *name;
289
290 if (args) {
291 value = args->elts;
292 name = &value[1];
293
294 } else {
295 name = NULL;
296 }
Igor Sysoev96c56c92003-07-02 14:41:17 +0000297
298 ngx_test_null(log, ngx_pcalloc(cycle->pool, sizeof(ngx_log_t)), NULL);
Igor Sysoev890fc962003-07-20 21:15:59 +0000299 ngx_test_null(log->file, ngx_conf_open_file(cycle, name), NULL);
300
Igor Sysoevd8e1f072004-01-22 06:47:28 +0000301#if 0
Igor Sysoev0911f772004-01-14 18:19:42 +0000302 /* STUB */ log->log_level = NGX_LOG_DEBUG | NGX_LOG_DEBUG_CORE | NGX_LOG_DEBUG_ALLOC | NGX_LOG_DEBUG_EVENT | NGX_LOG_DEBUG_HTTP;
Igor Sysoev62260f22003-12-05 17:07:27 +0000303#endif
Igor Sysoev96c56c92003-07-02 14:41:17 +0000304
305 return log;
306}
307
308
Igor Sysoev340b03b2003-07-04 15:10:33 +0000309static char *ngx_set_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
310{
311 ngx_str_t *value;
312
313 value = cf->args->elts;
314
315 if (value[1].len == 6 && ngx_strcmp(value[1].data, "stderr") == 0) {
316 cf->cycle->log->file = &ngx_stderr;
317
318 } else {
319 cf->cycle->log->file->name = value[1];
320 }
321
Igor Sysoev03420a62004-01-20 20:40:08 +0000322 return ngx_set_error_log_levels(cf, cf->cycle->log);
323}
324
325
326char *ngx_set_error_log_levels(ngx_conf_t *cf, ngx_log_t *log)
327{
328 ngx_int_t i, n, d;
329 ngx_str_t *value;
330
331 value = cf->args->elts;
332
Igor Sysoev5f800782003-12-08 20:48:12 +0000333 for (i = 2; i < cf->args->nelts; i++) {
334
335 for (n = 1; n < NGX_LOG_DEBUG; n++) {
336 if (ngx_strcmp(value[i].data, err_levels[n]) == 0) {
337
Igor Sysoev03420a62004-01-20 20:40:08 +0000338 if (log->log_level != 0) {
Igor Sysoev5f800782003-12-08 20:48:12 +0000339 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
340 "invalid log level \"%s\"",
341 value[i].data);
342 return NGX_CONF_ERROR;
343 }
344
Igor Sysoev03420a62004-01-20 20:40:08 +0000345 log->log_level = n;
Igor Sysoev5f800782003-12-08 20:48:12 +0000346 continue;
Igor Sysoev62260f22003-12-05 17:07:27 +0000347 }
348 }
Igor Sysoev5f800782003-12-08 20:48:12 +0000349
Igor Sysoevd8e1f072004-01-22 06:47:28 +0000350 for (n = 0, d = NGX_LOG_DEBUG_FIRST; d <= NGX_LOG_DEBUG_LAST; d <<= 1) {
351 if (ngx_strcmp(value[i].data, debug_levels[n++]) == 0) {
Igor Sysoev03420a62004-01-20 20:40:08 +0000352 if (log->log_level & ~NGX_LOG_DEBUG_ALL) {
Igor Sysoev5f800782003-12-08 20:48:12 +0000353 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
354 "invalid log level \"%s\"",
355 value[i].data);
356 return NGX_CONF_ERROR;
357 }
358
Igor Sysoev03420a62004-01-20 20:40:08 +0000359 log->log_level |= d;
Igor Sysoev5f800782003-12-08 20:48:12 +0000360 }
361 }
362
363
Igor Sysoev03420a62004-01-20 20:40:08 +0000364 if (log->log_level == 0) {
Igor Sysoev62260f22003-12-05 17:07:27 +0000365 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev5f800782003-12-08 20:48:12 +0000366 "invalid log level \"%s\"", value[i].data);
Igor Sysoev62260f22003-12-05 17:07:27 +0000367 return NGX_CONF_ERROR;
368 }
Igor Sysoev1c104622003-06-03 15:42:58 +0000369 }
370
Igor Sysoev1c104622003-06-03 15:42:58 +0000371 return NGX_CONF_OK;
372}