summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nxt_conf_validation.c51
-rw-r--r--src/nxt_router_access_log.c194
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;
}