Groonga 3.0.9 Source Code Document
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ngx_log.c
Go to the documentation of this file.
1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) Nginx, Inc.
5  */
6 
7 
8 #include <ngx_config.h>
9 #include <ngx_core.h>
10 
11 
12 static char *ngx_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"),
19  ngx_error_log,
20  0,
21  0,
22  NULL},
23 
25 };
26 
27 
28 static ngx_core_module_t ngx_errlog_module_ctx = {
29  ngx_string("errlog"),
30  NULL,
31  NULL
32 };
33 
34 
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 */
48 };
49 
50 
51 static ngx_log_t ngx_log;
52 static ngx_open_file_t ngx_log_file;
54 
55 
56 static ngx_str_t err_levels[] = {
58  ngx_string("emerg"),
59  ngx_string("alert"),
60  ngx_string("crit"),
61  ngx_string("error"),
62  ngx_string("warn"),
63  ngx_string("notice"),
64  ngx_string("info"),
65  ngx_string("debug")
66 };
67 
68 static const char *debug_levels[] = {
69  "debug_core", "debug_alloc", "debug_mutex", "debug_event",
70  "debug_http", "debug_mail", "debug_mysql"
71 };
72 
73 
74 #if (NGX_HAVE_VARIADIC_MACROS)
75 
76 void
78  const char *fmt, ...)
79 
80 #else
81 
82 void
84  const char *fmt, va_list args)
85 
86 #endif
87 {
88 #if (NGX_HAVE_VARIADIC_MACROS)
89  va_list args;
90 #endif
91  u_char *p, *last, *msg;
92  u_char errstr[NGX_MAX_ERROR_STR];
93 
94  if (log->file->fd == NGX_INVALID_FILE) {
95  return;
96  }
97 
98  last = errstr + NGX_MAX_ERROR_STR;
99 
102 
103  p = errstr + ngx_cached_err_log_time.len;
104 
105  p = ngx_slprintf(p, last, " [%V] ", &err_levels[level]);
106 
107  /* pid#tid */
108  p = ngx_slprintf(p, last, "%P#" NGX_TID_T_FMT ": ",
110 
111  if (log->connection) {
112  p = ngx_slprintf(p, last, "*%uA ", log->connection);
113  }
114 
115  msg = p;
116 
117 #if (NGX_HAVE_VARIADIC_MACROS)
118 
119  va_start(args, fmt);
120  p = ngx_vslprintf(p, last, fmt, args);
121  va_end(args);
122 
123 #else
124 
125  p = ngx_vslprintf(p, last, fmt, args);
126 
127 #endif
128 
129  if (err) {
130  p = ngx_log_errno(p, last, err);
131  }
132 
133  if (level != NGX_LOG_DEBUG && log->handler) {
134  p = log->handler(log, p, last - p);
135  }
136 
137  if (p > last - NGX_LINEFEED_SIZE) {
138  p = last - NGX_LINEFEED_SIZE;
139  }
140 
141  ngx_linefeed(p);
142 
143  (void) ngx_write_fd(log->file->fd, errstr, p - errstr);
144 
145  if (!ngx_use_stderr
146  || level > NGX_LOG_WARN
147  || log->file->fd == ngx_stderr)
148  {
149  return;
150  }
151 
152  msg -= (7 + err_levels[level].len + 3);
153 
154  (void) ngx_sprintf(msg, "nginx: [%V] ", &err_levels[level]);
155 
156  (void) ngx_write_console(ngx_stderr, msg, p - msg);
157 }
158 
159 
160 #if !(NGX_HAVE_VARIADIC_MACROS)
161 
162 void ngx_cdecl
164  const char *fmt, ...)
165 {
166  va_list args;
167 
168  if (log->log_level >= level) {
169  va_start(args, fmt);
170  ngx_log_error_core(level, log, err, fmt, args);
171  va_end(args);
172  }
173 }
174 
175 
176 void ngx_cdecl
177 ngx_log_debug_core(ngx_log_t *log, ngx_err_t err, const char *fmt, ...)
178 {
179  va_list args;
180 
181  va_start(args, fmt);
182  ngx_log_error_core(NGX_LOG_DEBUG, log, err, fmt, args);
183  va_end(args);
184 }
185 
186 #endif
187 
188 
189 void ngx_cdecl
190 ngx_log_abort(ngx_err_t err, const char *fmt, ...)
191 {
192  u_char *p;
193  va_list args;
194  u_char errstr[NGX_MAX_CONF_ERRSTR];
195 
196  va_start(args, fmt);
197  p = ngx_vsnprintf(errstr, sizeof(errstr) - 1, fmt, args);
198  va_end(args);
199 
201  "%*s", p - errstr, errstr);
202 }
203 
204 
205 void ngx_cdecl
206 ngx_log_stderr(ngx_err_t err, const char *fmt, ...)
207 {
208  u_char *p, *last;
209  va_list args;
210  u_char errstr[NGX_MAX_ERROR_STR];
211 
212  last = errstr + NGX_MAX_ERROR_STR;
213  p = errstr + 7;
214 
215  ngx_memcpy(errstr, "nginx: ", 7);
216 
217  va_start(args, fmt);
218  p = ngx_vslprintf(p, last, fmt, args);
219  va_end(args);
220 
221  if (err) {
222  p = ngx_log_errno(p, last, err);
223  }
224 
225  if (p > last - NGX_LINEFEED_SIZE) {
226  p = last - NGX_LINEFEED_SIZE;
227  }
228 
229  ngx_linefeed(p);
230 
231  (void) ngx_write_console(ngx_stderr, errstr, p - errstr);
232 }
233 
234 
235 u_char *
236 ngx_log_errno(u_char *buf, u_char *last, ngx_err_t err)
237 {
238  if (buf > last - 50) {
239 
240  /* leave a space for an error code */
241 
242  buf = last - 50;
243  *buf++ = '.';
244  *buf++ = '.';
245  *buf++ = '.';
246  }
247 
248 #if (NGX_WIN32)
249  buf = ngx_slprintf(buf, last, ((unsigned) err < 0x80000000)
250  ? " (%d: " : " (%Xd: ", err);
251 #else
252  buf = ngx_slprintf(buf, last, " (%d: ", err);
253 #endif
254 
255  buf = ngx_strerror(err, buf, last - buf);
256 
257  if (buf < last) {
258  *buf++ = ')';
259  }
260 
261  return buf;
262 }
263 
264 
265 ngx_log_t *
266 ngx_log_init(u_char *prefix)
267 {
268  u_char *p, *name;
269  size_t nlen, plen;
270 
271  ngx_log.file = &ngx_log_file;
272  ngx_log.log_level = NGX_LOG_NOTICE;
273 
274  name = (u_char *) NGX_ERROR_LOG_PATH;
275 
276  /*
277  * we use ngx_strlen() here since BCC warns about
278  * condition is always false and unreachable code
279  */
280 
281  nlen = ngx_strlen(name);
282 
283  if (nlen == 0) {
284  ngx_log_file.fd = ngx_stderr;
285  return &ngx_log;
286  }
287 
288  p = NULL;
289 
290 #if (NGX_WIN32)
291  if (name[1] != ':') {
292 #else
293  if (name[0] != '/') {
294 #endif
295 
296  if (prefix) {
297  plen = ngx_strlen(prefix);
298 
299  } else {
300 #ifdef NGX_PREFIX
301  prefix = (u_char *) NGX_PREFIX;
302  plen = ngx_strlen(prefix);
303 #else
304  plen = 0;
305 #endif
306  }
307 
308  if (plen) {
309  name = malloc(plen + nlen + 2);
310  if (name == NULL) {
311  return NULL;
312  }
313 
314  p = ngx_cpymem(name, prefix, plen);
315 
316  if (!ngx_path_separator(*(p - 1))) {
317  *p++ = '/';
318  }
319 
320  ngx_cpystrn(p, (u_char *) NGX_ERROR_LOG_PATH, nlen + 1);
321 
322  p = name;
323  }
324  }
325 
326  ngx_log_file.fd = ngx_open_file(name, NGX_FILE_APPEND,
329 
330  if (ngx_log_file.fd == NGX_INVALID_FILE) {
332  "[alert] could not open error log file: "
333  ngx_open_file_n " \"%s\" failed", name);
334 #if (NGX_WIN32)
335  ngx_event_log(ngx_errno,
336  "could not open error log file: "
337  ngx_open_file_n " \"%s\" failed", name);
338 #endif
339 
340  ngx_log_file.fd = ngx_stderr;
341  }
342 
343  if (p) {
344  ngx_free(p);
345  }
346 
347  return &ngx_log;
348 }
349 
350 
351 ngx_log_t *
353 {
354  ngx_log_t *log;
355 
356  log = ngx_pcalloc(cycle->pool, sizeof(ngx_log_t));
357  if (log == NULL) {
358  return NULL;
359  }
360 
361  log->file = ngx_conf_open_file(cycle, name);
362  if (log->file == NULL) {
363  return NULL;
364  }
365 
366  return log;
367 }
368 
369 
370 char *
372 {
373  ngx_uint_t i, n, d, found;
374  ngx_str_t *value;
375 
376  value = cf->args->elts;
377 
378  for (i = 2; i < cf->args->nelts; i++) {
379  found = 0;
380 
381  for (n = 1; n <= NGX_LOG_DEBUG; n++) {
382  if (ngx_strcmp(value[i].data, err_levels[n].data) == 0) {
383 
384  if (log->log_level != 0) {
386  "duplicate log level \"%V\"",
387  &value[i]);
388  return NGX_CONF_ERROR;
389  }
390 
391  log->log_level = n;
392  found = 1;
393  break;
394  }
395  }
396 
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) {
401  "invalid log level \"%V\"",
402  &value[i]);
403  return NGX_CONF_ERROR;
404  }
405 
406  log->log_level |= d;
407  found = 1;
408  break;
409  }
410  }
411 
412 
413  if (!found) {
415  "invalid log level \"%V\"", &value[i]);
416  return NGX_CONF_ERROR;
417  }
418  }
419 
420  if (log->log_level == NGX_LOG_DEBUG) {
422  }
423 
424  return NGX_CONF_OK;
425 }
426 
427 
428 static char *
429 ngx_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
430 {
431  ngx_str_t *value, name;
432 
433  if (cf->cycle->new_log.file) {
434  return "is duplicate";
435  }
436 
437  value = cf->args->elts;
438 
439  if (ngx_strcmp(value[1].data, "stderr") == 0) {
440  ngx_str_null(&name);
441 
442  } else {
443  name = value[1];
444  }
445 
446  cf->cycle->new_log.file = ngx_conf_open_file(cf->cycle, &name);
447  if (cf->cycle->new_log.file == NULL) {
448  return NULL;
449  }
450 
451  if (cf->args->nelts == 2) {
453  return NGX_CONF_OK;
454  }
455 
456  cf->cycle->new_log.log_level = 0;
457 
458  return ngx_log_set_levels(cf, &cf->cycle->new_log);
459 }