diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nxt_conf_validation.c | 51 | ||||
-rw-r--r-- | src/nxt_router_access_log.c | 194 |
2 files changed, 229 insertions, 16 deletions
diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 0dde39ff..a0b4992f 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -216,6 +216,11 @@ static nxt_int_t nxt_conf_vldt_server_weight(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); static nxt_int_t nxt_conf_vldt_access_log(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); +static nxt_int_t nxt_conf_vldt_access_log_format(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data); +static nxt_int_t nxt_conf_vldt_access_log_format_field( + nxt_conf_validation_t *vldt, const nxt_str_t *name, + nxt_conf_value_t *value); static nxt_int_t nxt_conf_vldt_isolation(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); @@ -1465,7 +1470,8 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_access_log_members[] = { .type = NXT_CONF_VLDT_STRING, }, { .name = nxt_string("format"), - .type = NXT_CONF_VLDT_STRING, + .type = NXT_CONF_VLDT_STRING | NXT_CONF_VLDT_OBJECT, + .validator = nxt_conf_vldt_access_log_format, }, { .name = nxt_string("if"), .type = NXT_CONF_VLDT_STRING, @@ -3624,3 +3630,46 @@ nxt_conf_vldt_access_log(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, return NXT_OK; } + + +static nxt_int_t +nxt_conf_vldt_access_log_format(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data) +{ + static const nxt_str_t format = nxt_string("format"); + + if (nxt_conf_type(value) == NXT_CONF_OBJECT) { + return nxt_conf_vldt_object_iterator(vldt, value, + nxt_conf_vldt_access_log_format_field); + } + + /* NXT_CONF_STRING */ + + return nxt_conf_vldt_access_log_format_field(vldt, &format, value); +} + + +static nxt_int_t +nxt_conf_vldt_access_log_format_field(nxt_conf_validation_t *vldt, + const nxt_str_t *name, nxt_conf_value_t *value) +{ + nxt_str_t str; + + if (name->length == 0) { + return nxt_conf_vldt_error(vldt, "In the access log format, the name " + "must not be empty."); + } + + if (nxt_conf_type(value) != NXT_CONF_STRING) { + return nxt_conf_vldt_error(vldt, "In the access log format, the value " + "must be a string."); + } + + nxt_conf_get_string(value, &str); + + if (nxt_is_tstr(&str)) { + return nxt_conf_vldt_var(vldt, name, &str); + } + + return NXT_OK; +} 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; } |