comparison src/http/modules/ngx_http_log_module.c @ 278:704622b2528a NGINX_0_5_9

nginx 0.5.9 *) Change: now the ngx_http_memcached_module uses the $memcached_key variable value as a key. *) Feature: the $memcached_key variable. *) Feature: the "clean" parameter in the "client_body_in_file_only" directive. *) Feature: the "env" directive. *) Feature: the "sendfile" directive is available inside the "if" block. *) Feature: now on failure of the writing to access nginx logs a message to error_log, but not more often than once a minute. *) Bugfix: the "access_log off" directive did not always turn off the logging.
author Igor Sysoev <http://sysoev.ru>
date Thu, 25 Jan 2007 00:00:00 +0300
parents 251bcd11a5b8
children 2ceaee987f37
comparison
equal deleted inserted replaced
277:b3aec7787b8e 278:704622b2528a
40 40
41 41
42 typedef struct { 42 typedef struct {
43 ngx_open_file_t *file; 43 ngx_open_file_t *file;
44 time_t disk_full_time; 44 time_t disk_full_time;
45 time_t error_log_time;
45 ngx_array_t *ops; /* array of ngx_http_log_op_t */ 46 ngx_array_t *ops; /* array of ngx_http_log_op_t */
46 } ngx_http_log_t; 47 } ngx_http_log_t;
47 48
48 49
49 typedef struct { 50 typedef struct {
56 ngx_str_t name; 57 ngx_str_t name;
57 size_t len; 58 size_t len;
58 ngx_http_log_op_run_pt run; 59 ngx_http_log_op_run_pt run;
59 } ngx_http_log_var_t; 60 } ngx_http_log_var_t;
60 61
62
63 static void ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log,
64 u_char *buf, size_t len);
61 65
62 static u_char *ngx_http_log_connection(ngx_http_request_t *r, u_char *buf, 66 static u_char *ngx_http_log_connection(ngx_http_request_t *r, u_char *buf,
63 ngx_http_log_op_t *op); 67 ngx_http_log_op_t *op);
64 static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf, 68 static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf,
65 ngx_http_log_op_t *op); 69 ngx_http_log_op_t *op);
149 NULL, /* exit master */ 153 NULL, /* exit master */
150 NGX_MODULE_V1_PADDING 154 NGX_MODULE_V1_PADDING
151 }; 155 };
152 156
153 157
154 static ngx_str_t http_access_log = ngx_string(NGX_HTTP_LOG_PATH); 158 static ngx_str_t ngx_http_access_log = ngx_string(NGX_HTTP_LOG_PATH);
155 159
156 160
157 static ngx_str_t ngx_http_combined_fmt = 161 static ngx_str_t ngx_http_combined_fmt =
158 ngx_string("$remote_addr - $remote_user [$time_local] " 162 ngx_string("$remote_addr - $remote_user [$time_local] "
159 "\"$request\" $status $body_bytes_sent " 163 "\"$request\" $status $body_bytes_sent "
181 185
182 186
183 ngx_int_t 187 ngx_int_t
184 ngx_http_log_handler(ngx_http_request_t *r) 188 ngx_http_log_handler(ngx_http_request_t *r)
185 { 189 {
186 ngx_uint_t i, l;
187 u_char *line, *p; 190 u_char *line, *p;
188 size_t len; 191 size_t len;
192 ngx_uint_t i, l;
189 ngx_http_log_t *log; 193 ngx_http_log_t *log;
190 ngx_open_file_t *file; 194 ngx_open_file_t *file;
191 ngx_http_log_op_t *op; 195 ngx_http_log_op_t *op;
192 ngx_http_log_loc_conf_t *lcf; 196 ngx_http_log_loc_conf_t *lcf;
193 197
204 for (l = 0; l < lcf->logs->nelts; l++) { 208 for (l = 0; l < lcf->logs->nelts; l++) {
205 209
206 if (ngx_time() == log[l].disk_full_time) { 210 if (ngx_time() == log[l].disk_full_time) {
207 211
208 /* 212 /*
209 * On FreeBSD writing to a full filesystem with enabled softupdates 213 * on FreeBSD writing to a full filesystem with enabled softupdates
210 * may block process for much longer time than writing to non-full 214 * may block process for much longer time than writing to non-full
211 * filesystem, so we skip writing the log for one second. 215 * filesystem, so we skip writing to a log for one second
212 */ 216 */
213 217
214 continue; 218 continue;
215 } 219 }
216 220
231 235
232 if (file->buffer) { 236 if (file->buffer) {
233 237
234 if (len > (size_t) (file->last - file->pos)) { 238 if (len > (size_t) (file->last - file->pos)) {
235 239
236 if (ngx_write_fd(file->fd, file->buffer, 240 ngx_http_log_write(r, &log[l], file->buffer,
237 file->pos - file->buffer) 241 file->pos - file->buffer);
238 == -1
239 && ngx_errno == NGX_ENOSPC)
240 {
241 log[l].disk_full_time = ngx_time();
242 }
243 242
244 file->pos = file->buffer; 243 file->pos = file->buffer;
245 } 244 }
246 245
247 if (len <= (size_t) (file->last - file->pos)) { 246 if (len <= (size_t) (file->last - file->pos)) {
271 p = op[i].run(r, p, &op[i]); 270 p = op[i].run(r, p, &op[i]);
272 } 271 }
273 272
274 ngx_linefeed(p); 273 ngx_linefeed(p);
275 274
276 if (ngx_write_fd(file->fd, line, p - line) == -1 275 ngx_http_log_write(r, &log[l], line, p - line);
277 && ngx_errno == NGX_ENOSPC)
278 {
279 log[l].disk_full_time = ngx_time();
280 }
281 } 276 }
282 277
283 return NGX_OK; 278 return NGX_OK;
279 }
280
281
282 static void
283 ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log, u_char *buf,
284 size_t len)
285 {
286 time_t now;
287 ssize_t n;
288 ngx_err_t err;
289
290 n = ngx_write_fd(log->file->fd, buf, len);
291
292 if (n == (ssize_t) len) {
293 return;
294 }
295
296 now = ngx_time();
297
298 if (n == -1) {
299 err = ngx_errno;
300
301 if (err == NGX_ENOSPC) {
302 log->disk_full_time = now;
303 }
304
305 if (now - log->error_log_time > 60) {
306 ngx_log_error(NGX_LOG_ALERT, r->connection->log, err,
307 ngx_write_fd_n " to \"%V\" failed",
308 &log->file->name);
309
310 log->error_log_time = now;
311 }
312
313 return;
314 }
315
316 if (now - log->error_log_time > 60) {
317 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
318 ngx_write_fd_n " to \"%V\" was incomplete: %z of %uz",
319 &log->file->name, n, len);
320
321 log->error_log_time = now;
322 }
284 } 323 }
285 324
286 325
287 static u_char * 326 static u_char *
288 ngx_http_log_copy_short(ngx_http_request_t *r, u_char *buf, 327 ngx_http_log_copy_short(ngx_http_request_t *r, u_char *buf,
513 552
514 ngx_http_log_t *log; 553 ngx_http_log_t *log;
515 ngx_http_log_fmt_t *fmt; 554 ngx_http_log_fmt_t *fmt;
516 ngx_http_log_main_conf_t *lmcf; 555 ngx_http_log_main_conf_t *lmcf;
517 556
557 if (conf->logs || conf->off) {
558 return NGX_CONF_OK;
559 }
560
561 *conf = *prev;
562
563 if (conf->logs || conf->off) {
564 return NGX_CONF_OK;
565 }
566
567 conf->logs = ngx_array_create(cf->pool, 2, sizeof(ngx_http_log_t));
518 if (conf->logs == NULL) { 568 if (conf->logs == NULL) {
519 569 return NGX_CONF_ERROR;
520 if (conf->off) { 570 }
521 return NGX_CONF_OK; 571
522 } 572 log = ngx_array_push(conf->logs);
523 573 if (log == NULL) {
524 if (prev->logs) { 574 return NGX_CONF_ERROR;
525 conf->logs = prev->logs; 575 }
526 576
527 } else { 577 log->file = ngx_conf_open_file(cf->cycle, &ngx_http_access_log);
528 578 if (log->file == NULL) {
529 if (prev->off) { 579 return NGX_CONF_ERROR;
530 conf->off = prev->off; 580 }
531 return NGX_CONF_OK; 581
532 } 582 log->disk_full_time = 0;
533 583 log->error_log_time = 0;
534 conf->logs = ngx_array_create(cf->pool, 2, sizeof(ngx_http_log_t)); 584
535 if (conf->logs == NULL) { 585 lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_log_module);
536 return NGX_CONF_ERROR; 586 fmt = lmcf->formats.elts;
537 } 587
538 588 /* the default "combined" format */
539 log = ngx_array_push(conf->logs); 589 log->ops = fmt[0].ops;
540 if (log == NULL) { 590 lmcf->combined_used = 1;
541 return NGX_CONF_ERROR;
542 }
543
544 log->file = ngx_conf_open_file(cf->cycle, &http_access_log);
545 if (log->file == NULL) {
546 return NGX_CONF_ERROR;
547 }
548
549 log->disk_full_time = 0;
550
551 lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_log_module);
552 fmt = lmcf->formats.elts;
553
554 /* the default "combined" format */
555 log->ops = fmt[0].ops;
556 lmcf->combined_used = 1;
557 }
558 }
559 591
560 return NGX_CONF_OK; 592 return NGX_CONF_OK;
561 } 593 }
562 594
563 595
598 if (log->file == NULL) { 630 if (log->file == NULL) {
599 return NGX_CONF_ERROR; 631 return NGX_CONF_ERROR;
600 } 632 }
601 633
602 log->disk_full_time = 0; 634 log->disk_full_time = 0;
635 log->error_log_time = 0;
603 636
604 if (cf->args->nelts >= 3) { 637 if (cf->args->nelts >= 3) {
605 name = value[2]; 638 name = value[2];
606 639
607 if (ngx_strcmp(name.data, "combined") == 0) { 640 if (ngx_strcmp(name.data, "combined") == 0) {