Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_log_module.c @ 4986:3efc49b156d9
Access log: the "flush" parameter of the "access_log" directive.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Sun, 23 Dec 2012 15:51:47 +0000 |
parents | a0599b56e748 |
children | 3849bb380605 |
comparison
equal
deleted
inserted
replaced
4985:a0599b56e748 | 4986:3efc49b156d9 |
---|---|
42 | 42 |
43 typedef struct { | 43 typedef struct { |
44 u_char *start; | 44 u_char *start; |
45 u_char *pos; | 45 u_char *pos; |
46 u_char *last; | 46 u_char *last; |
47 | |
48 ngx_event_t *event; | |
49 ngx_msec_t flush; | |
47 } ngx_http_log_buf_t; | 50 } ngx_http_log_buf_t; |
48 | 51 |
49 | 52 |
50 typedef struct { | 53 typedef struct { |
51 ngx_array_t *lengths; | 54 ngx_array_t *lengths; |
84 u_char *buf, size_t len); | 87 u_char *buf, size_t len); |
85 static ssize_t ngx_http_log_script_write(ngx_http_request_t *r, | 88 static ssize_t ngx_http_log_script_write(ngx_http_request_t *r, |
86 ngx_http_log_script_t *script, u_char **name, u_char *buf, size_t len); | 89 ngx_http_log_script_t *script, u_char **name, u_char *buf, size_t len); |
87 | 90 |
88 static void ngx_http_log_flush(ngx_open_file_t *file, ngx_log_t *log); | 91 static void ngx_http_log_flush(ngx_open_file_t *file, ngx_log_t *log); |
92 static void ngx_http_log_flush_handler(ngx_event_t *ev); | |
89 | 93 |
90 static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf, | 94 static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf, |
91 ngx_http_log_op_t *op); | 95 ngx_http_log_op_t *op); |
92 static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf, | 96 static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf, |
93 ngx_http_log_op_t *op); | 97 ngx_http_log_op_t *op); |
139 0, | 143 0, |
140 NULL }, | 144 NULL }, |
141 | 145 |
142 { ngx_string("access_log"), | 146 { ngx_string("access_log"), |
143 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF | 147 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF |
144 |NGX_HTTP_LMT_CONF|NGX_CONF_TAKE123, | 148 |NGX_HTTP_LMT_CONF|NGX_CONF_1MORE, |
145 ngx_http_log_set_log, | 149 ngx_http_log_set_log, |
146 NGX_HTTP_LOC_CONF_OFFSET, | 150 NGX_HTTP_LOC_CONF_OFFSET, |
147 0, | 151 0, |
148 NULL }, | 152 NULL }, |
149 | 153 |
281 | 285 |
282 if (len <= (size_t) (buffer->last - buffer->pos)) { | 286 if (len <= (size_t) (buffer->last - buffer->pos)) { |
283 | 287 |
284 p = buffer->pos; | 288 p = buffer->pos; |
285 | 289 |
290 if (buffer->event && p == buffer->start) { | |
291 ngx_add_timer(buffer->event, buffer->flush); | |
292 } | |
293 | |
286 for (i = 0; i < log[l].format->ops->nelts; i++) { | 294 for (i = 0; i < log[l].format->ops->nelts; i++) { |
287 p = op[i].run(r, p, &op[i]); | 295 p = op[i].run(r, p, &op[i]); |
288 } | 296 } |
289 | 297 |
290 ngx_linefeed(p); | 298 ngx_linefeed(p); |
291 | 299 |
292 buffer->pos = p; | 300 buffer->pos = p; |
293 | 301 |
294 continue; | 302 continue; |
303 } | |
304 | |
305 if (buffer->event && buffer->event->timer_set) { | |
306 ngx_del_timer(buffer->event); | |
295 } | 307 } |
296 } | 308 } |
297 | 309 |
298 line = ngx_pnalloc(r->pool, len); | 310 line = ngx_pnalloc(r->pool, len); |
299 if (line == NULL) { | 311 if (line == NULL) { |
501 ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz", | 513 ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz", |
502 file->name.data, n, len); | 514 file->name.data, n, len); |
503 } | 515 } |
504 | 516 |
505 buffer->pos = buffer->start; | 517 buffer->pos = buffer->start; |
518 | |
519 if (buffer->event && buffer->event->timer_set) { | |
520 ngx_del_timer(buffer->event); | |
521 } | |
522 } | |
523 | |
524 | |
525 static void | |
526 ngx_http_log_flush_handler(ngx_event_t *ev) | |
527 { | |
528 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, | |
529 "http log buffer flush handler"); | |
530 | |
531 ngx_http_log_flush(ev->data, ev->log); | |
506 } | 532 } |
507 | 533 |
508 | 534 |
509 static u_char * | 535 static u_char * |
510 ngx_http_log_copy_short(ngx_http_request_t *r, u_char *buf, | 536 ngx_http_log_copy_short(ngx_http_request_t *r, u_char *buf, |
889 { | 915 { |
890 ngx_http_log_loc_conf_t *llcf = conf; | 916 ngx_http_log_loc_conf_t *llcf = conf; |
891 | 917 |
892 ssize_t size; | 918 ssize_t size; |
893 ngx_uint_t i, n; | 919 ngx_uint_t i, n; |
894 ngx_str_t *value, name; | 920 ngx_msec_t flush; |
921 ngx_str_t *value, name, s; | |
895 ngx_http_log_t *log; | 922 ngx_http_log_t *log; |
896 ngx_http_log_buf_t *buffer; | 923 ngx_http_log_buf_t *buffer; |
897 ngx_http_log_fmt_t *fmt; | 924 ngx_http_log_fmt_t *fmt; |
898 ngx_http_log_main_conf_t *lmcf; | 925 ngx_http_log_main_conf_t *lmcf; |
899 ngx_http_script_compile_t sc; | 926 ngx_http_script_compile_t sc; |
976 for (i = 0; i < lmcf->formats.nelts; i++) { | 1003 for (i = 0; i < lmcf->formats.nelts; i++) { |
977 if (fmt[i].name.len == name.len | 1004 if (fmt[i].name.len == name.len |
978 && ngx_strcasecmp(fmt[i].name.data, name.data) == 0) | 1005 && ngx_strcasecmp(fmt[i].name.data, name.data) == 0) |
979 { | 1006 { |
980 log->format = &fmt[i]; | 1007 log->format = &fmt[i]; |
981 goto buffer; | 1008 break; |
982 } | 1009 } |
983 } | 1010 } |
984 | 1011 |
985 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 1012 if (log->format == NULL) { |
986 "unknown log format \"%V\"", &name); | 1013 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
987 return NGX_CONF_ERROR; | 1014 "unknown log format \"%V\"", &name); |
988 | 1015 return NGX_CONF_ERROR; |
989 buffer: | 1016 } |
990 | 1017 |
991 if (cf->args->nelts == 4) { | 1018 size = 0; |
992 if (ngx_strncmp(value[3].data, "buffer=", 7) != 0) { | 1019 flush = 0; |
993 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 1020 |
994 "invalid parameter \"%V\"", &value[3]); | 1021 for (i = 3; i < cf->args->nelts; i++) { |
995 return NGX_CONF_ERROR; | 1022 |
996 } | 1023 if (ngx_strncmp(value[i].data, "buffer=", 7) == 0) { |
1024 s.len = value[i].len - 7; | |
1025 s.data = value[i].data + 7; | |
1026 | |
1027 size = ngx_parse_size(&s); | |
1028 | |
1029 if (size == NGX_ERROR || size == 0) { | |
1030 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1031 "invalid buffer size \"%V\"", &s); | |
1032 return NGX_CONF_ERROR; | |
1033 } | |
1034 | |
1035 continue; | |
1036 } | |
1037 | |
1038 if (ngx_strncmp(value[i].data, "flush=", 6) == 0) { | |
1039 s.len = value[i].len - 6; | |
1040 s.data = value[i].data + 6; | |
1041 | |
1042 flush = ngx_parse_time(&s, 0); | |
1043 | |
1044 if (flush == (ngx_msec_t) NGX_ERROR || flush == 0) { | |
1045 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1046 "invalid flush time \"%V\"", &s); | |
1047 return NGX_CONF_ERROR; | |
1048 } | |
1049 | |
1050 continue; | |
1051 } | |
1052 | |
1053 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1054 "invalid parameter \"%V\"", &value[i]); | |
1055 return NGX_CONF_ERROR; | |
1056 } | |
1057 | |
1058 if (flush && size == 0) { | |
1059 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1060 "no buffer is defined for access_log \"%V\"", | |
1061 &value[1]); | |
1062 return NGX_CONF_ERROR; | |
1063 } | |
1064 | |
1065 if (size) { | |
997 | 1066 |
998 if (log->script) { | 1067 if (log->script) { |
999 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 1068 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
1000 "buffered logs cannot have variables in name"); | 1069 "buffered logs cannot have variables in name"); |
1001 return NGX_CONF_ERROR; | 1070 return NGX_CONF_ERROR; |
1002 } | 1071 } |
1003 | 1072 |
1004 name.len = value[3].len - 7; | |
1005 name.data = value[3].data + 7; | |
1006 | |
1007 size = ngx_parse_size(&name); | |
1008 | |
1009 if (size == NGX_ERROR) { | |
1010 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1011 "invalid buffer value \"%V\"", &name); | |
1012 return NGX_CONF_ERROR; | |
1013 } | |
1014 | |
1015 if (log->file->data) { | 1073 if (log->file->data) { |
1016 buffer = log->file->data; | 1074 buffer = log->file->data; |
1017 | 1075 |
1018 if (buffer->last - buffer->start != size) { | 1076 if (buffer->last - buffer->start != size |
1077 || buffer->flush != flush) | |
1078 { | |
1019 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 1079 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
1020 "access_log \"%V\" already defined " | 1080 "access_log \"%V\" already defined " |
1021 "with different buffer size", &value[1]); | 1081 "with conflicting parameters", |
1082 &value[1]); | |
1022 return NGX_CONF_ERROR; | 1083 return NGX_CONF_ERROR; |
1023 } | 1084 } |
1024 | 1085 |
1025 return NGX_CONF_OK; | 1086 return NGX_CONF_OK; |
1026 } | 1087 } |
1035 return NGX_CONF_ERROR; | 1096 return NGX_CONF_ERROR; |
1036 } | 1097 } |
1037 | 1098 |
1038 buffer->pos = buffer->start; | 1099 buffer->pos = buffer->start; |
1039 buffer->last = buffer->start + size; | 1100 buffer->last = buffer->start + size; |
1101 | |
1102 if (flush) { | |
1103 buffer->event = ngx_pcalloc(cf->pool, sizeof(ngx_event_t)); | |
1104 if (buffer->event == NULL) { | |
1105 return NGX_CONF_ERROR; | |
1106 } | |
1107 | |
1108 buffer->event->data = log->file; | |
1109 buffer->event->handler = ngx_http_log_flush_handler; | |
1110 buffer->event->log = &cf->cycle->new_log; | |
1111 | |
1112 buffer->flush = flush; | |
1113 } | |
1040 | 1114 |
1041 log->file->flush = ngx_http_log_flush; | 1115 log->file->flush = ngx_http_log_flush; |
1042 log->file->data = buffer; | 1116 log->file->data = buffer; |
1043 } | 1117 } |
1044 | 1118 |