diff options
Diffstat (limited to 'src/nxt_router_access_log.c')
-rw-r--r-- | src/nxt_router_access_log.c | 194 |
1 files changed, 179 insertions, 15 deletions
diff --git a/src/nxt_router_access_log.c b/src/nxt_router_access_log.c index 30b38aa1..1ec1a2d2 100644 --- a/src/nxt_router_access_log.c +++ b/src/nxt_router_access_log.c @@ -11,20 +11,28 @@ typedef struct { - nxt_str_t path; - nxt_conf_value_t *format; - nxt_conf_value_t *expr; + nxt_str_t path; + nxt_conf_value_t *format; + nxt_conf_value_t *expr; } nxt_router_access_log_conf_t; typedef struct { - nxt_str_t text; - nxt_router_access_log_t *access_log; + nxt_str_t text; + nxt_router_access_log_t *access_log; } nxt_router_access_log_ctx_t; +typedef struct { + nxt_str_t name; + nxt_tstr_t *tstr; +} nxt_router_access_log_member_t; + + struct nxt_router_access_log_format_s { - nxt_tstr_t *tstr; + nxt_tstr_t *tstr; + nxt_uint_t nmembers; + nxt_router_access_log_member_t *member; }; @@ -33,6 +41,11 @@ static nxt_router_access_log_format_t *nxt_router_access_log_format_create( static void nxt_router_access_log_writer(nxt_task_t *task, nxt_http_request_t *r, nxt_router_access_log_t *access_log, nxt_router_access_log_format_t *format); +static nxt_int_t nxt_router_access_log_text(nxt_task_t *task, + nxt_http_request_t *r, nxt_router_access_log_ctx_t *ctx, nxt_tstr_t *tstr); +static nxt_int_t nxt_router_access_log_json(nxt_task_t *task, + nxt_http_request_t *r, nxt_router_access_log_ctx_t *ctx, + nxt_router_access_log_format_t *format); static void nxt_router_access_log_write(nxt_task_t *task, nxt_http_request_t *r, nxt_router_access_log_ctx_t *ctx); static void nxt_router_access_log_ready(nxt_task_t *task, @@ -145,7 +158,12 @@ static nxt_router_access_log_format_t * nxt_router_access_log_format_create(nxt_task_t *task, nxt_router_conf_t *rtcf, nxt_conf_value_t *value) { - nxt_str_t str; + size_t size; + uint32_t i, n, next; + nxt_str_t name, str, *dst; + nxt_bool_t has_js; + nxt_conf_value_t *cv; + nxt_router_access_log_member_t *member; nxt_router_access_log_format_t *format; static const nxt_str_t default_format = nxt_string("$remote_addr - - " @@ -159,7 +177,74 @@ nxt_router_access_log_format_create(nxt_task_t *task, nxt_router_conf_t *rtcf, } if (value != NULL) { - nxt_conf_get_string(value, &str); + + if (nxt_conf_type(value) == NXT_CONF_OBJECT) { + next = 0; + has_js = 0; + + n = nxt_conf_object_members_count(value); + + for ( ;; ) { + cv = nxt_conf_next_object_member(value, &name, &next); + if (cv == NULL) { + break; + } + + nxt_conf_get_string(cv, &str); + + if (nxt_tstr_is_js(&str)) { + has_js = 1; + } + } + + if (has_js) { + member = nxt_mp_alloc(rtcf->mem_pool, + n * sizeof(nxt_router_access_log_member_t)); + if (nxt_slow_path(member == NULL)) { + return NULL; + } + + next = 0; + + for (i = 0; i < n; i++) { + cv = nxt_conf_next_object_member(value, &name, &next); + if (cv == NULL) { + break; + } + + dst = nxt_str_dup(rtcf->mem_pool, &member[i].name, &name); + if (nxt_slow_path(dst == NULL)) { + return NULL; + } + + nxt_conf_get_string(cv, &str); + + member[i].tstr = nxt_tstr_compile(rtcf->tstr_state, &str, + NXT_TSTR_LOGGING); + if (nxt_slow_path(member[i].tstr == NULL)) { + return NULL; + } + } + + format->nmembers = n; + format->member = member; + + return format; + } + + size = nxt_conf_json_length(value, NULL); + + str.start = nxt_mp_nget(rtcf->mem_pool, size); + if (nxt_slow_path(str.start == NULL)) { + return NULL; + } + + str.length = nxt_conf_json_print(str.start, value, NULL) + - str.start; + + } else { + nxt_conf_get_string(value, &str); + } } else { str = default_format; @@ -180,7 +265,6 @@ nxt_router_access_log_writer(nxt_task_t *task, nxt_http_request_t *r, nxt_router_access_log_t *access_log, nxt_router_access_log_format_t *format) { nxt_int_t ret; - nxt_router_conf_t *rtcf; nxt_router_access_log_ctx_t *ctx; ctx = nxt_mp_get(r->mem_pool, sizeof(nxt_router_access_log_ctx_t)); @@ -190,8 +274,28 @@ nxt_router_access_log_writer(nxt_task_t *task, nxt_http_request_t *r, ctx->access_log = access_log; - if (nxt_tstr_is_const(format->tstr)) { - nxt_tstr_str(format->tstr, &ctx->text); + if (format->tstr != NULL) { + ret = nxt_router_access_log_text(task, r, ctx, format->tstr); + + } else { + ret = nxt_router_access_log_json(task, r, ctx, format); + } + + if (ret == NXT_OK) { + nxt_router_access_log_write(task, r, ctx); + } +} + + +static nxt_int_t +nxt_router_access_log_text(nxt_task_t *task, nxt_http_request_t *r, + nxt_router_access_log_ctx_t *ctx, nxt_tstr_t *tstr) +{ + nxt_int_t ret; + nxt_router_conf_t *rtcf; + + if (nxt_tstr_is_const(tstr)) { + nxt_tstr_str(tstr, &ctx->text); } else { rtcf = r->conf->socket_conf->router_conf; @@ -199,16 +303,76 @@ nxt_router_access_log_writer(nxt_task_t *task, nxt_http_request_t *r, ret = nxt_tstr_query_init(&r->tstr_query, rtcf->tstr_state, &r->tstr_cache, r, r->mem_pool); if (nxt_slow_path(ret != NXT_OK)) { - return; + return NXT_ERROR; } - ret = nxt_tstr_query(task, r->tstr_query, format->tstr, &ctx->text); + ret = nxt_tstr_query(task, r->tstr_query, tstr, &ctx->text); if (nxt_slow_path(ret != NXT_OK)) { - return; + return NXT_ERROR; } } - nxt_router_access_log_write(task, r, ctx); + return NXT_OK; +} + + +static nxt_int_t +nxt_router_access_log_json(nxt_task_t *task, nxt_http_request_t *r, + nxt_router_access_log_ctx_t *ctx, nxt_router_access_log_format_t *format) +{ + u_char *p; + size_t size; + nxt_int_t ret; + nxt_str_t str; + nxt_uint_t i; + nxt_conf_value_t *value; + nxt_router_conf_t *rtcf; + nxt_router_access_log_member_t *member; + + rtcf = r->conf->socket_conf->router_conf; + + value = nxt_conf_create_object(r->mem_pool, format->nmembers); + if (nxt_slow_path(value == NULL)) { + return NXT_ERROR; + } + + for (i = 0; i < format->nmembers; i++) { + member = &format->member[i]; + + if (nxt_tstr_is_const(member->tstr)) { + nxt_tstr_str(member->tstr, &str); + + } else { + ret = nxt_tstr_query_init(&r->tstr_query, rtcf->tstr_state, + &r->tstr_cache, r, r->mem_pool); + if (nxt_slow_path(ret != NXT_OK)) { + return NXT_ERROR; + } + + ret = nxt_tstr_query(task, r->tstr_query, member->tstr, &str); + if (nxt_slow_path(ret != NXT_OK)) { + return NXT_ERROR; + } + } + + nxt_conf_set_member_string(value, &member->name, &str, i); + } + + size = nxt_conf_json_length(value, NULL) + 1; + + p = nxt_mp_nget(r->mem_pool, size); + if (nxt_slow_path(p == NULL)) { + return NXT_ERROR; + } + + ctx->text.start = p; + + p = nxt_conf_json_print(p, value, NULL); + *p++ = '\n'; + + ctx->text.length = p - ctx->text.start; + + return NXT_OK; } |