changeset 2261:07bf557a2e40

*) log_subrequest *) flush variables in access log
author Igor Sysoev <igor@sysoev.ru>
date Sat, 27 Sep 2008 15:08:02 +0000
parents 4f1616b32744
children c31f46332e80
files src/http/modules/ngx_http_log_module.c src/http/ngx_http_core_module.c src/http/ngx_http_core_module.h src/http/ngx_http_request.c
diffstat 4 files changed, 79 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -28,6 +28,7 @@ struct ngx_http_log_op_s {
 
 typedef struct {
     ngx_str_t                   name;
+    ngx_array_t                *flushes;
     ngx_array_t                *ops;        /* array of ngx_http_log_op_t */
 } ngx_http_log_fmt_t;
 
@@ -49,7 +50,7 @@ typedef struct {
     ngx_http_log_script_t      *script;
     time_t                      disk_full_time;
     time_t                      error_log_time;
-    ngx_array_t                *ops;        /* array of ngx_http_log_op_t */
+    ngx_http_log_fmt_t         *format;
 } ngx_http_log_t;
 
 
@@ -113,7 +114,7 @@ static char *ngx_http_log_set_log(ngx_co
 static char *ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
 static char *ngx_http_log_compile_format(ngx_conf_t *cf,
-    ngx_array_t *ops, ngx_array_t *args, ngx_uint_t s);
+    ngx_array_t *flushes, ngx_array_t *ops, ngx_array_t *args, ngx_uint_t s);
 static char *ngx_http_log_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
 static ngx_int_t ngx_http_log_init(ngx_conf_t *cf);
@@ -242,9 +243,11 @@ ngx_http_log_handler(ngx_http_request_t 
             continue;
         }
 
+        ngx_http_script_flush_no_cacheable_variables(r, log[l].format->flushes);
+
         len = 0;
-        op = log[l].ops->elts;
-        for (i = 0; i < log[l].ops->nelts; i++) {
+        op = log[l].format->ops->elts;
+        for (i = 0; i < log[l].format->ops->nelts; i++) {
             if (op[i].len == 0) {
                 len += op[i].getlen(r, op[i].data);
 
@@ -271,7 +274,7 @@ ngx_http_log_handler(ngx_http_request_t 
 
                 p = file->pos;
 
-                for (i = 0; i < log[l].ops->nelts; i++) {
+                for (i = 0; i < log[l].format->ops->nelts; i++) {
                     p = op[i].run(r, p, &op[i]);
                 }
 
@@ -290,7 +293,7 @@ ngx_http_log_handler(ngx_http_request_t 
 
         p = line;
 
-        for (i = 0; i < log[l].ops->nelts; i++) {
+        for (i = 0; i < log[l].format->ops->nelts; i++) {
             p = op[i].run(r, p, &op[i]);
         }
 
@@ -726,6 +729,8 @@ ngx_http_log_create_main_conf(ngx_conf_t
     fmt->name.len = sizeof("combined") - 1;
     fmt->name.data = (u_char *) "combined";
 
+    fmt->flushes = NULL;
+
     fmt->ops = ngx_array_create(cf->pool, 16, sizeof(ngx_http_log_op_t));
     if (fmt->ops == NULL) {
         return NGX_CONF_ERROR;
@@ -806,7 +811,7 @@ ngx_http_log_merge_loc_conf(ngx_conf_t *
     fmt = lmcf->formats.elts;
 
     /* the default "combined" format */
-    log->ops = fmt[0].ops;
+    log->format = &fmt[0];
     lmcf->combined_used = 1;
 
     return NGX_CONF_OK;
@@ -900,7 +905,7 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx
         if (fmt[i].name.len == name.len
             && ngx_strcasecmp(fmt[i].name.data, name.data) == 0)
         {
-            log->ops = fmt[i].ops;
+            log->format = &fmt[i];
             goto buffer;
         }
     }
@@ -985,22 +990,28 @@ ngx_http_log_set_format(ngx_conf_t *cf, 
 
     fmt->name = value[1];
 
+    fmt->flushes = ngx_array_create(cf->pool, 4, sizeof(ngx_int_t));
+    if (fmt->flushes == NULL) {
+        return NGX_CONF_ERROR;
+    }
+
     fmt->ops = ngx_array_create(cf->pool, 16, sizeof(ngx_http_log_op_t));
     if (fmt->ops == NULL) {
         return NGX_CONF_ERROR;
     }
 
-    return ngx_http_log_compile_format(cf, fmt->ops, cf->args, 2);
+    return ngx_http_log_compile_format(cf, fmt->flushes, fmt->ops, cf->args, 2);
 }
 
 
 static char *
-ngx_http_log_compile_format(ngx_conf_t *cf, ngx_array_t *ops,
-    ngx_array_t *args, ngx_uint_t s)
+ngx_http_log_compile_format(ngx_conf_t *cf, ngx_array_t *flushes,
+    ngx_array_t *ops, ngx_array_t *args, ngx_uint_t s)
 {
     u_char              *data, *p, ch;
     size_t               i, len;
     ngx_str_t           *value, var;
+    ngx_int_t           *flush;
     ngx_uint_t           bracket;
     ngx_http_log_op_t   *op;
     ngx_http_log_var_t  *v;
@@ -1114,6 +1125,16 @@ ngx_http_log_compile_format(ngx_conf_t *
                     return NGX_CONF_ERROR;
                 }
 
+                if (flushes) {
+
+                    flush = ngx_array_push(flushes);
+                    if (flush == NULL) {
+                        return NGX_CONF_ERROR;
+                    }
+
+                    *flush = op->data; /* variable index */
+                }
+
             found:
 
                 continue;
@@ -1299,7 +1320,7 @@ ngx_http_log_init(ngx_conf_t *cf)
         *value = ngx_http_combined_fmt;
         fmt = lmcf->formats.elts;
 
-        if (ngx_http_log_compile_format(cf, fmt->ops, &a, 0)
+        if (ngx_http_log_compile_format(cf, NULL, fmt->ops, &a, 0)
             != NGX_CONF_OK)
         {
             return NGX_ERROR;
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -494,6 +494,13 @@ static ngx_command_t  ngx_http_core_comm
       offsetof(ngx_http_core_loc_conf_t, log_not_found),
       NULL },
 
+    { ngx_string("log_subrequest"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+      ngx_conf_set_flag_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_core_loc_conf_t, log_subrequest),
+      NULL },
+
     { ngx_string("recursive_error_pages"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
       ngx_conf_set_flag_slot,
@@ -2674,6 +2681,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t
     lcf->msie_padding = NGX_CONF_UNSET;
     lcf->msie_refresh = NGX_CONF_UNSET;
     lcf->log_not_found = NGX_CONF_UNSET;
+    lcf->log_subrequest = NGX_CONF_UNSET;
     lcf->recursive_error_pages = NGX_CONF_UNSET;
     lcf->server_tokens = NGX_CONF_UNSET;
     lcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
@@ -2898,6 +2906,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t 
     ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1);
     ngx_conf_merge_value(conf->msie_refresh, prev->msie_refresh, 0);
     ngx_conf_merge_value(conf->log_not_found, prev->log_not_found, 1);
+    ngx_conf_merge_value(conf->log_subrequest, prev->log_subrequest, 0);
     ngx_conf_merge_value(conf->recursive_error_pages,
                               prev->recursive_error_pages, 0);
     ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1);
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -311,6 +311,7 @@ struct ngx_http_core_loc_conf_s {
     ngx_flag_t    msie_padding;            /* msie_padding */
     ngx_flag_t    msie_refresh;            /* msie_refresh */
     ngx_flag_t    log_not_found;           /* log_not_found */
+    ngx_flag_t    log_subrequest;          /* log_subrequest */
     ngx_flag_t    recursive_error_pages;   /* recursive_error_pages */
     ngx_flag_t    server_tokens;           /* server_tokens */
 
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -47,6 +47,7 @@ static void ngx_http_lingering_close_han
 static ngx_int_t ngx_http_post_action(ngx_http_request_t *r);
 static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error);
 static void ngx_http_request_done(ngx_http_request_t *r, ngx_int_t error);
+static void ngx_http_log_request(ngx_http_request_t *r);
 static void ngx_http_close_connection(ngx_connection_t *c);
 
 static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len);
@@ -1774,6 +1775,8 @@ ngx_http_finalize_request(ngx_http_reque
         return;
     }
 
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
     if (r != r->main) {
 
         pr = r->parent;
@@ -1807,6 +1810,11 @@ ngx_http_finalize_request(ngx_http_reque
                 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
                                "http fast subrequest: \"%V?%V\" done",
                                &r->uri, &r->args);
+
+                if (clcf->log_subrequest) {
+                    ngx_http_log_request(r);
+                }
+
                 return;
             }
 
@@ -1819,6 +1827,10 @@ ngx_http_finalize_request(ngx_http_reque
             }
         }
 
+        if (clcf->log_subrequest) {
+            ngx_http_log_request(r);
+        }
+
         return;
     }
 
@@ -1857,8 +1869,6 @@ ngx_http_finalize_request(ngx_http_reque
         return;
     }
 
-    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
     if (!ngx_terminate
          && !ngx_exiting
          && r->keepalive
@@ -2604,14 +2614,11 @@ ngx_http_close_request(ngx_http_request_
 static void
 ngx_http_request_done(ngx_http_request_t *r, ngx_int_t error)
 {
-    ngx_log_t                  *log;
-    ngx_uint_t                  i, n;
-    struct linger               linger;
-    ngx_http_cleanup_t         *cln;
-    ngx_http_log_ctx_t         *ctx;
-    ngx_http_handler_pt        *log_handler;
-    ngx_http_core_loc_conf_t   *clcf;
-    ngx_http_core_main_conf_t  *cmcf;
+    ngx_log_t                 *log;
+    struct linger              linger;
+    ngx_http_cleanup_t        *cln;
+    ngx_http_log_ctx_t        *ctx;
+    ngx_http_core_loc_conf_t  *clcf;
 
     log = r->connection->log;
 
@@ -2646,13 +2653,7 @@ ngx_http_request_done(ngx_http_request_t
 
     log->action = "logging request";
 
-    cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
-
-    log_handler = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.elts;
-    n = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.nelts;
-    for (i = 0; i < n; i++) {
-        log_handler[i](r);
-    }
+    ngx_http_log_request(r);
 
     log->action = "closing request";
 
@@ -2685,6 +2686,24 @@ ngx_http_request_done(ngx_http_request_t
 
 
 static void
+ngx_http_log_request(ngx_http_request_t *r)
+{
+    ngx_uint_t                  i, n;
+    ngx_http_handler_pt        *log_handler;
+    ngx_http_core_main_conf_t  *cmcf;
+
+    cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
+
+    log_handler = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.elts;
+    n = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.nelts;
+
+    for (i = 0; i < n; i++) {
+        log_handler[i](r);
+    }
+}
+
+
+static void
 ngx_http_close_connection(ngx_connection_t *c)
 {
     ngx_pool_t  *pool;