comparison src/http/modules/ngx_http_log_module.c @ 4985:a0599b56e748

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..
author Valentin Bartenev <vbart@nginx.com>
date Sun, 23 Dec 2012 15:36:52 +0000
parents 7737f0d788c1
children 3efc49b156d9
comparison
equal deleted inserted replaced
4984:7737f0d788c1 4985:a0599b56e748
36 36
37 typedef struct { 37 typedef struct {
38 ngx_array_t formats; /* array of ngx_http_log_fmt_t */ 38 ngx_array_t formats; /* array of ngx_http_log_fmt_t */
39 ngx_uint_t combined_used; /* unsigned combined_used:1 */ 39 ngx_uint_t combined_used; /* unsigned combined_used:1 */
40 } ngx_http_log_main_conf_t; 40 } ngx_http_log_main_conf_t;
41
42
43 typedef struct {
44 u_char *start;
45 u_char *pos;
46 u_char *last;
47 } ngx_http_log_buf_t;
41 48
42 49
43 typedef struct { 50 typedef struct {
44 ngx_array_t *lengths; 51 ngx_array_t *lengths;
45 ngx_array_t *values; 52 ngx_array_t *values;
75 82
76 static void ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log, 83 static void ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log,
77 u_char *buf, size_t len); 84 u_char *buf, size_t len);
78 static ssize_t ngx_http_log_script_write(ngx_http_request_t *r, 85 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); 86 ngx_http_log_script_t *script, u_char **name, u_char *buf, size_t len);
87
88 static void ngx_http_log_flush(ngx_open_file_t *file, ngx_log_t *log);
80 89
81 static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf, 90 static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf,
82 ngx_http_log_op_t *op); 91 ngx_http_log_op_t *op);
83 static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf, 92 static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf,
84 ngx_http_log_op_t *op); 93 ngx_http_log_op_t *op);
214 { 223 {
215 u_char *line, *p; 224 u_char *line, *p;
216 size_t len; 225 size_t len;
217 ngx_uint_t i, l; 226 ngx_uint_t i, l;
218 ngx_http_log_t *log; 227 ngx_http_log_t *log;
219 ngx_open_file_t *file;
220 ngx_http_log_op_t *op; 228 ngx_http_log_op_t *op;
229 ngx_http_log_buf_t *buffer;
221 ngx_http_log_loc_conf_t *lcf; 230 ngx_http_log_loc_conf_t *lcf;
222 231
223 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 232 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
224 "http log handler"); 233 "http log handler");
225 234
256 } 265 }
257 } 266 }
258 267
259 len += NGX_LINEFEED_SIZE; 268 len += NGX_LINEFEED_SIZE;
260 269
261 file = log[l].file; 270 buffer = log[l].file ? log[l].file->data : NULL;
262 271
263 if (file && file->buffer) { 272 if (buffer) {
264 273
265 if (len > (size_t) (file->last - file->pos)) { 274 if (len > (size_t) (buffer->last - buffer->pos)) {
266 275
267 ngx_http_log_write(r, &log[l], file->buffer, 276 ngx_http_log_write(r, &log[l], buffer->start,
268 file->pos - file->buffer); 277 buffer->pos - buffer->start);
269 278
270 file->pos = file->buffer; 279 buffer->pos = buffer->start;
271 } 280 }
272 281
273 if (len <= (size_t) (file->last - file->pos)) { 282 if (len <= (size_t) (buffer->last - buffer->pos)) {
274 283
275 p = file->pos; 284 p = buffer->pos;
276 285
277 for (i = 0; i < log[l].format->ops->nelts; i++) { 286 for (i = 0; i < log[l].format->ops->nelts; i++) {
278 p = op[i].run(r, p, &op[i]); 287 p = op[i].run(r, p, &op[i]);
279 } 288 }
280 289
281 ngx_linefeed(p); 290 ngx_linefeed(p);
282 291
283 file->pos = p; 292 buffer->pos = p;
284 293
285 continue; 294 continue;
286 } 295 }
287 } 296 }
288 297
463 472
464 return n; 473 return n;
465 } 474 }
466 475
467 476
477 static void
478 ngx_http_log_flush(ngx_open_file_t *file, ngx_log_t *log)
479 {
480 size_t len;
481 ssize_t n;
482 ngx_http_log_buf_t *buffer;
483
484 buffer = file->data;
485
486 len = buffer->pos - buffer->start;
487
488 if (len == 0) {
489 return;
490 }
491
492 n = ngx_write_fd(file->fd, buffer->start, len);
493
494 if (n == -1) {
495 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
496 ngx_write_fd_n " to \"%s\" failed",
497 file->name.data);
498
499 } else if ((size_t) n != len) {
500 ngx_log_error(NGX_LOG_ALERT, log, 0,
501 ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz",
502 file->name.data, n, len);
503 }
504
505 buffer->pos = buffer->start;
506 }
507
508
468 static u_char * 509 static u_char *
469 ngx_http_log_copy_short(ngx_http_request_t *r, u_char *buf, 510 ngx_http_log_copy_short(ngx_http_request_t *r, u_char *buf,
470 ngx_http_log_op_t *op) 511 ngx_http_log_op_t *op)
471 { 512 {
472 size_t len; 513 size_t len;
846 static char * 887 static char *
847 ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 888 ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
848 { 889 {
849 ngx_http_log_loc_conf_t *llcf = conf; 890 ngx_http_log_loc_conf_t *llcf = conf;
850 891
851 ssize_t buf; 892 ssize_t size;
852 ngx_uint_t i, n; 893 ngx_uint_t i, n;
853 ngx_str_t *value, name; 894 ngx_str_t *value, name;
854 ngx_http_log_t *log; 895 ngx_http_log_t *log;
896 ngx_http_log_buf_t *buffer;
855 ngx_http_log_fmt_t *fmt; 897 ngx_http_log_fmt_t *fmt;
856 ngx_http_log_main_conf_t *lmcf; 898 ngx_http_log_main_conf_t *lmcf;
857 ngx_http_script_compile_t sc; 899 ngx_http_script_compile_t sc;
858 900
859 value = cf->args->elts; 901 value = cf->args->elts;
960 } 1002 }
961 1003
962 name.len = value[3].len - 7; 1004 name.len = value[3].len - 7;
963 name.data = value[3].data + 7; 1005 name.data = value[3].data + 7;
964 1006
965 buf = ngx_parse_size(&name); 1007 size = ngx_parse_size(&name);
966 1008
967 if (buf == NGX_ERROR) { 1009 if (size == NGX_ERROR) {
968 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 1010 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
969 "invalid buffer value \"%V\"", &name); 1011 "invalid buffer value \"%V\"", &name);
970 return NGX_CONF_ERROR; 1012 return NGX_CONF_ERROR;
971 } 1013 }
972 1014
973 if (log->file->buffer) { 1015 if (log->file->data) {
974 if (log->file->last - log->file->pos != buf) { 1016 buffer = log->file->data;
1017
1018 if (buffer->last - buffer->start != size) {
975 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 1019 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
976 "access_log \"%V\" already defined " 1020 "access_log \"%V\" already defined "
977 "with different buffer size", &value[1]); 1021 "with different buffer size", &value[1]);
978 return NGX_CONF_ERROR; 1022 return NGX_CONF_ERROR;
979 } 1023 }
980 1024
981 return NGX_CONF_OK; 1025 return NGX_CONF_OK;
982 } 1026 }
983 1027
984 log->file->buffer = ngx_palloc(cf->pool, buf); 1028 buffer = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_buf_t));
985 if (log->file->buffer == NULL) { 1029 if (buffer == NULL) {
986 return NGX_CONF_ERROR; 1030 return NGX_CONF_ERROR;
987 } 1031 }
988 1032
989 log->file->pos = log->file->buffer; 1033 buffer->start = ngx_pnalloc(cf->pool, size);
990 log->file->last = log->file->buffer + buf; 1034 if (buffer->start == NULL) {
1035 return NGX_CONF_ERROR;
1036 }
1037
1038 buffer->pos = buffer->start;
1039 buffer->last = buffer->start + size;
1040
1041 log->file->flush = ngx_http_log_flush;
1042 log->file->data = buffer;
991 } 1043 }
992 1044
993 return NGX_CONF_OK; 1045 return NGX_CONF_OK;
994 } 1046 }
995 1047