comparison src/core/ngx_log.c @ 0:f0b350454894 NGINX_0_1_0

nginx 0.1.0 *) The first public version.
author Igor Sysoev <http://sysoev.ru>
date Mon, 04 Oct 2004 00:00:00 +0400
parents
children 4b2dafa26fe2
comparison
equal deleted inserted replaced
-1:000000000000 0:f0b350454894
1
2 /*
3 * Copyright (C) Igor Sysoev
4 */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9
10
11 static void ngx_log_write(ngx_log_t *log, char *errstr, size_t len);
12 static char *ngx_set_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_set_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,
37 &ngx_errlog_module_ctx, /* module context */
38 ngx_errlog_commands, /* module directives */
39 NGX_CORE_MODULE, /* module type */
40 NULL, /* init module */
41 NULL /* init child */
42 };
43
44
45 static ngx_log_t ngx_log;
46 static ngx_open_file_t ngx_stderr;
47
48
49 static const char *err_levels[] = {
50 "stderr", "emerg", "alert", "crit", "error",
51 "warn", "notice", "info", "debug"
52 };
53
54 static const char *debug_levels[] = {
55 "debug_core", "debug_alloc", "debug_mutex", "debug_event",
56 "debug_http", "debug_imap"
57 };
58
59
60 #if (HAVE_VARIADIC_MACROS)
61 void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
62 const char *fmt, ...)
63 #else
64 void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
65 const char *fmt, va_list args)
66 #endif
67 {
68 char errstr[MAX_ERROR_STR];
69 size_t len, max;
70 #if (HAVE_VARIADIC_MACROS)
71 va_list args;
72 #endif
73
74 if (log->file->fd == NGX_INVALID_FILE) {
75 return;
76 }
77
78 ngx_memcpy(errstr, ngx_cached_err_log_time.data,
79 ngx_cached_err_log_time.len);
80
81 #if (WIN32)
82 max = MAX_ERROR_STR - 2;
83 #else
84 max = MAX_ERROR_STR - 1;
85 #endif
86
87 len = ngx_cached_err_log_time.len;
88
89 len += ngx_snprintf(errstr + len, max - len, " [%s] ", err_levels[level]);
90
91 /* pid#tid */
92 len += ngx_snprintf(errstr + len, max - len,
93 PID_T_FMT "#" TID_T_FMT ": ", ngx_log_pid, ngx_log_tid);
94
95 if (log->data && *(int *) log->data != -1) {
96 len += ngx_snprintf(errstr + len, max - len,
97 "*%u ", *(u_int *) log->data);
98 }
99
100 #if (HAVE_VARIADIC_MACROS)
101
102 va_start(args, fmt);
103 len += ngx_vsnprintf(errstr + len, max - len, fmt, args);
104 va_end(args);
105
106 #else
107
108 len += ngx_vsnprintf(errstr + len, max - len, fmt, args);
109
110 #endif
111
112 if (err) {
113
114 if (len > max - 50) {
115
116 /* leave a space for an error code */
117
118 len = max - 50;
119 errstr[len++] = '.';
120 errstr[len++] = '.';
121 errstr[len++] = '.';
122 }
123
124 #if (WIN32)
125 if ((unsigned) err >= 0x80000000) {
126 len += ngx_snprintf(errstr + len, max - len, " (%X: ", err);
127 } else {
128 len += ngx_snprintf(errstr + len, max - len, " (%d: ", err);
129 }
130 #else
131 len += ngx_snprintf(errstr + len, max - len, " (%d: ", err);
132 #endif
133
134 if (len >= max) {
135 ngx_log_write(log, errstr, max);
136 return;
137 }
138
139 len += ngx_strerror_r(err, errstr + len, max - len);
140
141 if (len >= max) {
142 ngx_log_write(log, errstr, max);
143 return;
144 }
145
146 errstr[len++] = ')';
147
148 if (len >= max) {
149 ngx_log_write(log, errstr, max);
150 return;
151 }
152
153 } else {
154 if (len >= max) {
155 ngx_log_write(log, errstr, max);
156 return;
157 }
158 }
159
160 if (level != NGX_LOG_DEBUG && log->handler) {
161 len += log->handler(log->data, errstr + len, max - len);
162
163 if (len >= max) {
164 len = max;
165 }
166 }
167
168 ngx_log_write(log, errstr, len);
169 }
170
171
172 static void ngx_log_write(ngx_log_t *log, char *errstr, size_t len)
173 {
174 #if (WIN32)
175 u_long written;
176
177 errstr[len++] = CR;
178 errstr[len++] = LF;
179 WriteFile(log->file->fd, errstr, len, &written, NULL);
180
181 #else
182
183 errstr[len++] = LF;
184 write(log->file->fd, errstr, len);
185
186 #endif
187 }
188
189
190 #if !(HAVE_VARIADIC_MACROS)
191
192 void ngx_log_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
193 const char *fmt, ...)
194 {
195 va_list args;
196
197 if (log->log_level >= level) {
198 va_start(args, fmt);
199 ngx_log_error_core(level, log, err, fmt, args);
200 va_end(args);
201 }
202 }
203
204
205 void ngx_log_debug_core(ngx_log_t *log, ngx_err_t err, const char *fmt, ...)
206 {
207 va_list args;
208
209 va_start(args, fmt);
210 ngx_log_error_core(NGX_LOG_DEBUG, log, err, fmt, args);
211 va_end(args);
212 }
213
214
215 void ngx_assert_core(ngx_log_t *log, const char *fmt, ...)
216 {
217 va_list args;
218
219 va_start(args, fmt);
220 ngx_log_error_core(NGX_LOG_ALERT, log, 0, fmt, args);
221 va_end(args);
222 }
223
224 #endif
225
226
227 ngx_log_t *ngx_log_init_stderr()
228 {
229 #if (WIN32)
230
231 ngx_stderr_fileno = GetStdHandle(STD_ERROR_HANDLE);
232 ngx_stderr.fd = ngx_stderr_fileno;
233
234 if (ngx_stderr_fileno == NGX_INVALID_FILE) {
235
236 /* TODO: where can we log error ? */
237
238 return NULL;
239
240 } else if (ngx_stderr_fileno == NULL) {
241
242 /* there are no associated standard handles */
243
244 /* TODO: where can we can log possible errors ? */
245
246 ngx_stderr.fd = NGX_INVALID_FILE;
247 }
248
249 #else
250
251 ngx_stderr.fd = STDERR_FILENO;
252
253 #endif
254
255 ngx_log.file = &ngx_stderr;
256 ngx_log.log_level = NGX_LOG_ERR;
257
258 return &ngx_log;
259 }
260
261
262 #if 0
263
264 ngx_int_t ngx_log_init_error_log()
265 {
266 ngx_fd_t fd;
267
268 #ifdef NGX_ERROR_LOG_PATH
269
270 fd = ngx_open_file(NGX_ERROR_LOG_PATH, NGX_FILE_RDWR,
271 NGX_FILE_CREATE_OR_OPEN|NGX_FILE_APPEND);
272
273 if (fd == NGX_INVALID_FILE) {
274 ngx_log_error(NGX_LOG_EMERG, (&ngx_log), ngx_errno,
275 ngx_open_file_n " \"" NGX_ERROR_LOG_PATH "\" failed");
276 return NGX_ERROR;
277 }
278
279 #if (WIN32)
280
281 if (ngx_file_append_mode(fd) == NGX_ERROR) {
282 ngx_log_error(NGX_LOG_EMERG, (&ngx_log), ngx_errno,
283 ngx_file_append_mode_n " \"" NGX_ERROR_LOG_PATH
284 "\" failed");
285 return NGX_ERROR;
286 }
287
288 #else
289
290 if (dup2(fd, STDERR_FILENO) == NGX_ERROR) {
291 ngx_log_error(NGX_LOG_EMERG, (&ngx_log), ngx_errno,
292 "dup2(STDERR) failed");
293 return NGX_ERROR;
294 }
295
296 #endif
297
298 #else /* no NGX_ERROR_LOG_PATH */
299
300 ngx_log.log_level = NGX_LOG_INFO;
301
302 #endif
303
304 return NGX_OK;
305 }
306
307 #endif
308
309
310 ngx_log_t *ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_array_t *args)
311 {
312 ngx_log_t *log;
313 ngx_str_t *value, *name;
314
315 if (args) {
316 value = args->elts;
317 name = &value[1];
318
319 } else {
320 name = NULL;
321 }
322
323 if (!(log = ngx_pcalloc(cycle->pool, sizeof(ngx_log_t)))) {
324 return NULL;
325 }
326
327 if (!(log->file = ngx_conf_open_file(cycle, name))) {
328 return NULL;
329 }
330
331 return log;
332 }
333
334
335 char *ngx_set_error_log_levels(ngx_conf_t *cf, ngx_log_t *log)
336 {
337 ngx_uint_t i, n, d;
338 ngx_str_t *value;
339
340 value = cf->args->elts;
341
342 for (i = 2; i < cf->args->nelts; i++) {
343
344 for (n = 1; n <= NGX_LOG_DEBUG; n++) {
345 if (ngx_strcmp(value[i].data, err_levels[n]) == 0) {
346
347 if (log->log_level != 0) {
348 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
349 "invalid log level \"%s\"",
350 value[i].data);
351 return NGX_CONF_ERROR;
352 }
353
354 log->log_level = n;
355 continue;
356 }
357 }
358
359 for (n = 0, d = NGX_LOG_DEBUG_FIRST; d <= NGX_LOG_DEBUG_LAST; d <<= 1) {
360 if (ngx_strcmp(value[i].data, debug_levels[n++]) == 0) {
361 if (log->log_level & ~NGX_LOG_DEBUG_ALL) {
362 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
363 "invalid log level \"%s\"",
364 value[i].data);
365 return NGX_CONF_ERROR;
366 }
367
368 log->log_level |= d;
369 }
370 }
371
372
373 if (log->log_level == 0) {
374 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
375 "invalid log level \"%s\"", value[i].data);
376 return NGX_CONF_ERROR;
377 }
378 }
379
380 if (log->log_level == NGX_LOG_DEBUG) {
381 log->log_level = NGX_LOG_DEBUG_ALL;
382 }
383
384 return NGX_CONF_OK;
385 }
386
387
388 static char *ngx_set_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
389 {
390 ngx_str_t *value;
391
392 value = cf->args->elts;
393
394 if (value[1].len == 6 && ngx_strcmp(value[1].data, "stderr") == 0) {
395 cf->cycle->new_log->file->fd = ngx_stderr.fd;
396 cf->cycle->new_log->file->name.len = 0;
397 cf->cycle->new_log->file->name.data = NULL;
398
399 } else {
400 cf->cycle->new_log->file->name = value[1];
401
402 if (ngx_conf_full_name(cf->cycle, &cf->cycle->new_log->file->name)
403 == NGX_ERROR)
404 {
405 return NGX_CONF_ERROR;
406 }
407 }
408
409 return ngx_set_error_log_levels(cf, cf->cycle->new_log);
410 }