Mercurial > hg > nginx
comparison src/http/modules/ngx_http_log_module.c @ 5053:004af18ddb86 stable-1.2
Merge of r4985, r4986, r4987, r4988, r4989, r5002: access_log gzip.
*) Access log: fixed redundant buffer reallocation. Previously a new
buffer was allocated for every "access_log" directive with the same
file path and "buffer=" parameters, while only one buffer per file
is used.
*) Reopening log files code moved to a separate function. The code
refactored in a way to call custom handler that can do appropriate
cleanup work (if any), like flushing buffers, finishing compress
streams, finalizing connections to log daemon, etc..
*) Access log: the "flush" parameter of the "access_log" directive.
*) Configure: added the NGX_ZLIB define. This was introduced for
conditional compilation of the code that requires the zlib library.
*) Access log: the "gzip" parameter of the "access_log" directive.
Note: this requires zlib version 1.2.0.4 or above to work.
*) The data pointer in ngx_open_file_t objects must be initialized.
Uninitialized pointer may result in arbitrary segfaults if access_log
is used without buffer and without variables in file path.
Patch by Tatsuhiko Kubo (ticket #268).
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 11 Feb 2013 14:34:00 +0000 |
parents | 5cad4cb1f484 |
children |
comparison
equal
deleted
inserted
replaced
5052:f2dcb25987df | 5053:004af18ddb86 |
---|---|
6 | 6 |
7 | 7 |
8 #include <ngx_config.h> | 8 #include <ngx_config.h> |
9 #include <ngx_core.h> | 9 #include <ngx_core.h> |
10 #include <ngx_http.h> | 10 #include <ngx_http.h> |
11 | |
12 #if (NGX_ZLIB) | |
13 #include <zlib.h> | |
14 #endif | |
11 | 15 |
12 | 16 |
13 typedef struct ngx_http_log_op_s ngx_http_log_op_t; | 17 typedef struct ngx_http_log_op_s ngx_http_log_op_t; |
14 | 18 |
15 typedef u_char *(*ngx_http_log_op_run_pt) (ngx_http_request_t *r, u_char *buf, | 19 typedef u_char *(*ngx_http_log_op_run_pt) (ngx_http_request_t *r, u_char *buf, |
36 | 40 |
37 typedef struct { | 41 typedef struct { |
38 ngx_array_t formats; /* array of ngx_http_log_fmt_t */ | 42 ngx_array_t formats; /* array of ngx_http_log_fmt_t */ |
39 ngx_uint_t combined_used; /* unsigned combined_used:1 */ | 43 ngx_uint_t combined_used; /* unsigned combined_used:1 */ |
40 } ngx_http_log_main_conf_t; | 44 } ngx_http_log_main_conf_t; |
45 | |
46 | |
47 typedef struct { | |
48 u_char *start; | |
49 u_char *pos; | |
50 u_char *last; | |
51 | |
52 ngx_event_t *event; | |
53 ngx_msec_t flush; | |
54 ngx_int_t gzip; | |
55 } ngx_http_log_buf_t; | |
41 | 56 |
42 | 57 |
43 typedef struct { | 58 typedef struct { |
44 ngx_array_t *lengths; | 59 ngx_array_t *lengths; |
45 ngx_array_t *values; | 60 ngx_array_t *values; |
75 | 90 |
76 static void ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log, | 91 static void ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log, |
77 u_char *buf, size_t len); | 92 u_char *buf, size_t len); |
78 static ssize_t ngx_http_log_script_write(ngx_http_request_t *r, | 93 static ssize_t ngx_http_log_script_write(ngx_http_request_t *r, |
79 ngx_http_log_script_t *script, u_char **name, u_char *buf, size_t len); | 94 ngx_http_log_script_t *script, u_char **name, u_char *buf, size_t len); |
95 | |
96 #if (NGX_ZLIB) | |
97 static ssize_t ngx_http_log_gzip(ngx_fd_t fd, u_char *buf, size_t len, | |
98 ngx_int_t level, ngx_log_t *log); | |
99 | |
100 static void *ngx_http_log_gzip_alloc(void *opaque, u_int items, u_int size); | |
101 static void ngx_http_log_gzip_free(void *opaque, void *address); | |
102 #endif | |
103 | |
104 static void ngx_http_log_flush(ngx_open_file_t *file, ngx_log_t *log); | |
105 static void ngx_http_log_flush_handler(ngx_event_t *ev); | |
80 | 106 |
81 static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf, | 107 static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf, |
82 ngx_http_log_op_t *op); | 108 ngx_http_log_op_t *op); |
83 static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf, | 109 static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf, |
84 ngx_http_log_op_t *op); | 110 ngx_http_log_op_t *op); |
130 0, | 156 0, |
131 NULL }, | 157 NULL }, |
132 | 158 |
133 { ngx_string("access_log"), | 159 { ngx_string("access_log"), |
134 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF | 160 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF |
135 |NGX_HTTP_LMT_CONF|NGX_CONF_TAKE123, | 161 |NGX_HTTP_LMT_CONF|NGX_CONF_1MORE, |
136 ngx_http_log_set_log, | 162 ngx_http_log_set_log, |
137 NGX_HTTP_LOC_CONF_OFFSET, | 163 NGX_HTTP_LOC_CONF_OFFSET, |
138 0, | 164 0, |
139 NULL }, | 165 NULL }, |
140 | 166 |
214 { | 240 { |
215 u_char *line, *p; | 241 u_char *line, *p; |
216 size_t len; | 242 size_t len; |
217 ngx_uint_t i, l; | 243 ngx_uint_t i, l; |
218 ngx_http_log_t *log; | 244 ngx_http_log_t *log; |
219 ngx_open_file_t *file; | |
220 ngx_http_log_op_t *op; | 245 ngx_http_log_op_t *op; |
246 ngx_http_log_buf_t *buffer; | |
221 ngx_http_log_loc_conf_t *lcf; | 247 ngx_http_log_loc_conf_t *lcf; |
222 | 248 |
223 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 249 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
224 "http log handler"); | 250 "http log handler"); |
225 | 251 |
256 } | 282 } |
257 } | 283 } |
258 | 284 |
259 len += NGX_LINEFEED_SIZE; | 285 len += NGX_LINEFEED_SIZE; |
260 | 286 |
261 file = log[l].file; | 287 buffer = log[l].file ? log[l].file->data : NULL; |
262 | 288 |
263 if (file && file->buffer) { | 289 if (buffer) { |
264 | 290 |
265 if (len > (size_t) (file->last - file->pos)) { | 291 if (len > (size_t) (buffer->last - buffer->pos)) { |
266 | 292 |
267 ngx_http_log_write(r, &log[l], file->buffer, | 293 ngx_http_log_write(r, &log[l], buffer->start, |
268 file->pos - file->buffer); | 294 buffer->pos - buffer->start); |
269 | 295 |
270 file->pos = file->buffer; | 296 buffer->pos = buffer->start; |
271 } | 297 } |
272 | 298 |
273 if (len <= (size_t) (file->last - file->pos)) { | 299 if (len <= (size_t) (buffer->last - buffer->pos)) { |
274 | 300 |
275 p = file->pos; | 301 p = buffer->pos; |
302 | |
303 if (buffer->event && p == buffer->start) { | |
304 ngx_add_timer(buffer->event, buffer->flush); | |
305 } | |
276 | 306 |
277 for (i = 0; i < log[l].format->ops->nelts; i++) { | 307 for (i = 0; i < log[l].format->ops->nelts; i++) { |
278 p = op[i].run(r, p, &op[i]); | 308 p = op[i].run(r, p, &op[i]); |
279 } | 309 } |
280 | 310 |
281 ngx_linefeed(p); | 311 ngx_linefeed(p); |
282 | 312 |
283 file->pos = p; | 313 buffer->pos = p; |
284 | 314 |
285 continue; | 315 continue; |
316 } | |
317 | |
318 if (buffer->event && buffer->event->timer_set) { | |
319 ngx_del_timer(buffer->event); | |
286 } | 320 } |
287 } | 321 } |
288 | 322 |
289 line = ngx_pnalloc(r->pool, len); | 323 line = ngx_pnalloc(r->pool, len); |
290 if (line == NULL) { | 324 if (line == NULL) { |
308 | 342 |
309 static void | 343 static void |
310 ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log, u_char *buf, | 344 ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log, u_char *buf, |
311 size_t len) | 345 size_t len) |
312 { | 346 { |
313 u_char *name; | 347 u_char *name; |
314 time_t now; | 348 time_t now; |
315 ssize_t n; | 349 ssize_t n; |
316 ngx_err_t err; | 350 ngx_err_t err; |
351 #if (NGX_ZLIB) | |
352 ngx_http_log_buf_t *buffer; | |
353 #endif | |
317 | 354 |
318 if (log->script == NULL) { | 355 if (log->script == NULL) { |
319 name = log->file->name.data; | 356 name = log->file->name.data; |
357 | |
358 #if (NGX_ZLIB) | |
359 buffer = log->file->data; | |
360 | |
361 if (buffer && buffer->gzip) { | |
362 n = ngx_http_log_gzip(log->file->fd, buf, len, buffer->gzip, | |
363 r->connection->log); | |
364 } else { | |
365 n = ngx_write_fd(log->file->fd, buf, len); | |
366 } | |
367 #else | |
320 n = ngx_write_fd(log->file->fd, buf, len); | 368 n = ngx_write_fd(log->file->fd, buf, len); |
369 #endif | |
321 | 370 |
322 } else { | 371 } else { |
323 name = NULL; | 372 name = NULL; |
324 n = ngx_http_log_script_write(r, log->script, &name, buf, len); | 373 n = ngx_http_log_script_write(r, log->script, &name, buf, len); |
325 } | 374 } |
463 | 512 |
464 return n; | 513 return n; |
465 } | 514 } |
466 | 515 |
467 | 516 |
517 #if (NGX_ZLIB) | |
518 | |
519 static ssize_t | |
520 ngx_http_log_gzip(ngx_fd_t fd, u_char *buf, size_t len, ngx_int_t level, | |
521 ngx_log_t *log) | |
522 { | |
523 int rc, wbits, memlevel; | |
524 u_char *out; | |
525 size_t size; | |
526 ssize_t n; | |
527 z_stream zstream; | |
528 ngx_err_t err; | |
529 ngx_pool_t *pool; | |
530 | |
531 wbits = MAX_WBITS; | |
532 memlevel = MAX_MEM_LEVEL - 1; | |
533 | |
534 while ((ssize_t) len < ((1 << (wbits - 1)) - 262)) { | |
535 wbits--; | |
536 memlevel--; | |
537 } | |
538 | |
539 /* | |
540 * This is a formula from deflateBound() for conservative upper bound of | |
541 * compressed data plus 18 bytes of gzip wrapper. | |
542 */ | |
543 | |
544 size = len + ((len + 7) >> 3) + ((len + 63) >> 6) + 5 + 18; | |
545 | |
546 ngx_memzero(&zstream, sizeof(z_stream)); | |
547 | |
548 pool = ngx_create_pool(256, log); | |
549 if (pool == NULL) { | |
550 /* simulate successful logging */ | |
551 return len; | |
552 } | |
553 | |
554 pool->log = log; | |
555 | |
556 zstream.zalloc = ngx_http_log_gzip_alloc; | |
557 zstream.zfree = ngx_http_log_gzip_free; | |
558 zstream.opaque = pool; | |
559 | |
560 out = ngx_pnalloc(pool, size); | |
561 if (out == NULL) { | |
562 goto done; | |
563 } | |
564 | |
565 zstream.next_in = buf; | |
566 zstream.avail_in = len; | |
567 zstream.next_out = out; | |
568 zstream.avail_out = size; | |
569 | |
570 rc = deflateInit2(&zstream, (int) level, Z_DEFLATED, wbits + 16, memlevel, | |
571 Z_DEFAULT_STRATEGY); | |
572 | |
573 if (rc != Z_OK) { | |
574 ngx_log_error(NGX_LOG_ALERT, log, 0, "deflateInit2() failed: %d", rc); | |
575 goto done; | |
576 } | |
577 | |
578 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, log, 0, | |
579 "deflate in: ni:%p no:%p ai:%ud ao:%ud", | |
580 zstream.next_in, zstream.next_out, | |
581 zstream.avail_in, zstream.avail_out); | |
582 | |
583 rc = deflate(&zstream, Z_FINISH); | |
584 | |
585 if (rc != Z_STREAM_END) { | |
586 ngx_log_error(NGX_LOG_ALERT, log, 0, | |
587 "deflate(Z_FINISH) failed: %d", rc); | |
588 goto done; | |
589 } | |
590 | |
591 ngx_log_debug5(NGX_LOG_DEBUG_HTTP, log, 0, | |
592 "deflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d", | |
593 zstream.next_in, zstream.next_out, | |
594 zstream.avail_in, zstream.avail_out, | |
595 rc); | |
596 | |
597 size -= zstream.avail_out; | |
598 | |
599 rc = deflateEnd(&zstream); | |
600 | |
601 if (rc != Z_OK) { | |
602 ngx_log_error(NGX_LOG_ALERT, log, 0, "deflateEnd() failed: %d", rc); | |
603 goto done; | |
604 } | |
605 | |
606 n = ngx_write_fd(fd, out, size); | |
607 | |
608 if (n != (ssize_t) size) { | |
609 err = (n == -1) ? ngx_errno : 0; | |
610 | |
611 ngx_destroy_pool(pool); | |
612 | |
613 ngx_set_errno(err); | |
614 return -1; | |
615 } | |
616 | |
617 done: | |
618 | |
619 ngx_destroy_pool(pool); | |
620 | |
621 /* simulate successful logging */ | |
622 return len; | |
623 } | |
624 | |
625 | |
626 static void * | |
627 ngx_http_log_gzip_alloc(void *opaque, u_int items, u_int size) | |
628 { | |
629 ngx_pool_t *pool = opaque; | |
630 | |
631 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pool->log, 0, | |
632 "gzip alloc: n:%ud s:%ud", items, size); | |
633 | |
634 return ngx_palloc(pool, items * size); | |
635 } | |
636 | |
637 | |
638 static void | |
639 ngx_http_log_gzip_free(void *opaque, void *address) | |
640 { | |
641 #if 0 | |
642 ngx_pool_t *pool = opaque; | |
643 | |
644 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pool->log, 0, "gzip free: %p", address); | |
645 #endif | |
646 } | |
647 | |
648 #endif | |
649 | |
650 | |
651 static void | |
652 ngx_http_log_flush(ngx_open_file_t *file, ngx_log_t *log) | |
653 { | |
654 size_t len; | |
655 ssize_t n; | |
656 ngx_http_log_buf_t *buffer; | |
657 | |
658 buffer = file->data; | |
659 | |
660 len = buffer->pos - buffer->start; | |
661 | |
662 if (len == 0) { | |
663 return; | |
664 } | |
665 | |
666 #if (NGX_ZLIB) | |
667 if (buffer->gzip) { | |
668 n = ngx_http_log_gzip(file->fd, buffer->start, len, buffer->gzip, log); | |
669 } else { | |
670 n = ngx_write_fd(file->fd, buffer->start, len); | |
671 } | |
672 #else | |
673 n = ngx_write_fd(file->fd, buffer->start, len); | |
674 #endif | |
675 | |
676 if (n == -1) { | |
677 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
678 ngx_write_fd_n " to \"%s\" failed", | |
679 file->name.data); | |
680 | |
681 } else if ((size_t) n != len) { | |
682 ngx_log_error(NGX_LOG_ALERT, log, 0, | |
683 ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz", | |
684 file->name.data, n, len); | |
685 } | |
686 | |
687 buffer->pos = buffer->start; | |
688 | |
689 if (buffer->event && buffer->event->timer_set) { | |
690 ngx_del_timer(buffer->event); | |
691 } | |
692 } | |
693 | |
694 | |
695 static void | |
696 ngx_http_log_flush_handler(ngx_event_t *ev) | |
697 { | |
698 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, | |
699 "http log buffer flush handler"); | |
700 | |
701 ngx_http_log_flush(ev->data, ev->log); | |
702 } | |
703 | |
704 | |
468 static u_char * | 705 static u_char * |
469 ngx_http_log_copy_short(ngx_http_request_t *r, u_char *buf, | 706 ngx_http_log_copy_short(ngx_http_request_t *r, u_char *buf, |
470 ngx_http_log_op_t *op) | 707 ngx_http_log_op_t *op) |
471 { | 708 { |
472 size_t len; | 709 size_t len; |
846 static char * | 1083 static char * |
847 ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 1084 ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
848 { | 1085 { |
849 ngx_http_log_loc_conf_t *llcf = conf; | 1086 ngx_http_log_loc_conf_t *llcf = conf; |
850 | 1087 |
851 ssize_t buf; | 1088 ssize_t size; |
1089 ngx_int_t gzip; | |
852 ngx_uint_t i, n; | 1090 ngx_uint_t i, n; |
853 ngx_str_t *value, name; | 1091 ngx_msec_t flush; |
1092 ngx_str_t *value, name, s; | |
854 ngx_http_log_t *log; | 1093 ngx_http_log_t *log; |
1094 ngx_http_log_buf_t *buffer; | |
855 ngx_http_log_fmt_t *fmt; | 1095 ngx_http_log_fmt_t *fmt; |
856 ngx_http_log_main_conf_t *lmcf; | 1096 ngx_http_log_main_conf_t *lmcf; |
857 ngx_http_script_compile_t sc; | 1097 ngx_http_script_compile_t sc; |
858 | 1098 |
859 value = cf->args->elts; | 1099 value = cf->args->elts; |
934 for (i = 0; i < lmcf->formats.nelts; i++) { | 1174 for (i = 0; i < lmcf->formats.nelts; i++) { |
935 if (fmt[i].name.len == name.len | 1175 if (fmt[i].name.len == name.len |
936 && ngx_strcasecmp(fmt[i].name.data, name.data) == 0) | 1176 && ngx_strcasecmp(fmt[i].name.data, name.data) == 0) |
937 { | 1177 { |
938 log->format = &fmt[i]; | 1178 log->format = &fmt[i]; |
939 goto buffer; | 1179 break; |
940 } | 1180 } |
941 } | 1181 } |
942 | 1182 |
943 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 1183 if (log->format == NULL) { |
944 "unknown log format \"%V\"", &name); | 1184 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
945 return NGX_CONF_ERROR; | 1185 "unknown log format \"%V\"", &name); |
946 | 1186 return NGX_CONF_ERROR; |
947 buffer: | 1187 } |
948 | 1188 |
949 if (cf->args->nelts == 4) { | 1189 size = 0; |
950 if (ngx_strncmp(value[3].data, "buffer=", 7) != 0) { | 1190 flush = 0; |
1191 gzip = 0; | |
1192 | |
1193 for (i = 3; i < cf->args->nelts; i++) { | |
1194 | |
1195 if (ngx_strncmp(value[i].data, "buffer=", 7) == 0) { | |
1196 s.len = value[i].len - 7; | |
1197 s.data = value[i].data + 7; | |
1198 | |
1199 size = ngx_parse_size(&s); | |
1200 | |
1201 if (size == NGX_ERROR || size == 0) { | |
1202 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1203 "invalid buffer size \"%V\"", &s); | |
1204 return NGX_CONF_ERROR; | |
1205 } | |
1206 | |
1207 continue; | |
1208 } | |
1209 | |
1210 if (ngx_strncmp(value[i].data, "flush=", 6) == 0) { | |
1211 s.len = value[i].len - 6; | |
1212 s.data = value[i].data + 6; | |
1213 | |
1214 flush = ngx_parse_time(&s, 0); | |
1215 | |
1216 if (flush == (ngx_msec_t) NGX_ERROR || flush == 0) { | |
1217 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1218 "invalid flush time \"%V\"", &s); | |
1219 return NGX_CONF_ERROR; | |
1220 } | |
1221 | |
1222 continue; | |
1223 } | |
1224 | |
1225 if (ngx_strncmp(value[i].data, "gzip", 4) == 0 | |
1226 && (value[i].len == 4 || value[i].data[4] == '=')) | |
1227 { | |
1228 #if (NGX_ZLIB) | |
1229 if (size == 0) { | |
1230 size = 64 * 1024; | |
1231 } | |
1232 | |
1233 if (value[i].len == 4) { | |
1234 gzip = Z_BEST_SPEED; | |
1235 continue; | |
1236 } | |
1237 | |
1238 s.len = value[i].len - 5; | |
1239 s.data = value[i].data + 5; | |
1240 | |
1241 gzip = ngx_atoi(s.data, s.len); | |
1242 | |
1243 if (gzip < 1 || gzip > 9) { | |
1244 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1245 "invalid compression level \"%V\"", &s); | |
1246 return NGX_CONF_ERROR; | |
1247 } | |
1248 | |
1249 continue; | |
1250 | |
1251 #else | |
951 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 1252 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
952 "invalid parameter \"%V\"", &value[3]); | 1253 "nginx was built without zlib support"); |
953 return NGX_CONF_ERROR; | 1254 return NGX_CONF_ERROR; |
954 } | 1255 #endif |
1256 } | |
1257 | |
1258 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1259 "invalid parameter \"%V\"", &value[i]); | |
1260 return NGX_CONF_ERROR; | |
1261 } | |
1262 | |
1263 if (flush && size == 0) { | |
1264 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1265 "no buffer is defined for access_log \"%V\"", | |
1266 &value[1]); | |
1267 return NGX_CONF_ERROR; | |
1268 } | |
1269 | |
1270 if (size) { | |
955 | 1271 |
956 if (log->script) { | 1272 if (log->script) { |
957 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 1273 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
958 "buffered logs cannot have variables in name"); | 1274 "buffered logs cannot have variables in name"); |
959 return NGX_CONF_ERROR; | 1275 return NGX_CONF_ERROR; |
960 } | 1276 } |
961 | 1277 |
962 name.len = value[3].len - 7; | 1278 if (log->file->data) { |
963 name.data = value[3].data + 7; | 1279 buffer = log->file->data; |
964 | 1280 |
965 buf = ngx_parse_size(&name); | 1281 if (buffer->last - buffer->start != size |
966 | 1282 || buffer->flush != flush |
967 if (buf == NGX_ERROR) { | 1283 || buffer->gzip != gzip) |
968 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 1284 { |
969 "invalid buffer value \"%V\"", &name); | 1285 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
1286 "access_log \"%V\" already defined " | |
1287 "with conflicting parameters", | |
1288 &value[1]); | |
1289 return NGX_CONF_ERROR; | |
1290 } | |
1291 | |
1292 return NGX_CONF_OK; | |
1293 } | |
1294 | |
1295 buffer = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_buf_t)); | |
1296 if (buffer == NULL) { | |
970 return NGX_CONF_ERROR; | 1297 return NGX_CONF_ERROR; |
971 } | 1298 } |
972 | 1299 |
973 if (log->file->buffer && log->file->last - log->file->pos != buf) { | 1300 buffer->start = ngx_pnalloc(cf->pool, size); |
974 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 1301 if (buffer->start == NULL) { |
975 "access_log \"%V\" already defined " | |
976 "with different buffer size", &value[1]); | |
977 return NGX_CONF_ERROR; | 1302 return NGX_CONF_ERROR; |
978 } | 1303 } |
979 | 1304 |
980 log->file->buffer = ngx_palloc(cf->pool, buf); | 1305 buffer->pos = buffer->start; |
981 if (log->file->buffer == NULL) { | 1306 buffer->last = buffer->start + size; |
982 return NGX_CONF_ERROR; | 1307 |
983 } | 1308 if (flush) { |
984 | 1309 buffer->event = ngx_pcalloc(cf->pool, sizeof(ngx_event_t)); |
985 log->file->pos = log->file->buffer; | 1310 if (buffer->event == NULL) { |
986 log->file->last = log->file->buffer + buf; | 1311 return NGX_CONF_ERROR; |
1312 } | |
1313 | |
1314 buffer->event->data = log->file; | |
1315 buffer->event->handler = ngx_http_log_flush_handler; | |
1316 buffer->event->log = &cf->cycle->new_log; | |
1317 | |
1318 buffer->flush = flush; | |
1319 } | |
1320 | |
1321 buffer->gzip = gzip; | |
1322 | |
1323 log->file->flush = ngx_http_log_flush; | |
1324 log->file->data = buffer; | |
987 } | 1325 } |
988 | 1326 |
989 return NGX_CONF_OK; | 1327 return NGX_CONF_OK; |
990 } | 1328 } |
991 | 1329 |