summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_router_access_log.c
diff options
context:
space:
mode:
authorKonstantin Pavlov <thresh@nginx.com>2024-12-19 10:23:57 -0800
committerKonstantin Pavlov <thresh@nginx.com>2024-12-19 10:23:57 -0800
commitd8acad350a52a20918c46c09cb0a0f5479400923 (patch)
tree7d9c4b64daa60d3ac121743dfa3735c6fc5687a4 /src/nxt_router_access_log.c
parent624debcf17ea7faab01fa841bd4dcd9f308cf306 (diff)
parent27bde184dedcbf687db2f314c60c037623318a8d (diff)
downloadunit-1.34.0-1.tar.gz
unit-1.34.0-1.tar.bz2
Merge tag '1.34.0' into packaging1.34.0-1
Unit 1.34.0 release.
Diffstat (limited to 'src/nxt_router_access_log.c')
-rw-r--r--src/nxt_router_access_log.c262
1 files changed, 224 insertions, 38 deletions
diff --git a/src/nxt_router_access_log.c b/src/nxt_router_access_log.c
index afecd0b1..1ec1a2d2 100644
--- a/src/nxt_router_access_log.c
+++ b/src/nxt_router_access_log.c
@@ -11,21 +11,41 @@
typedef struct {
- nxt_str_t path;
- nxt_str_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_uint_t nmembers;
+ nxt_router_access_log_member_t *member;
+};
+
+
+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);
static void nxt_router_access_log_writer(nxt_task_t *task,
nxt_http_request_t *r, nxt_router_access_log_t *access_log,
- nxt_tstr_t *format);
+ 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,
@@ -49,7 +69,7 @@ static nxt_conf_map_t nxt_router_access_log_conf[] = {
{
nxt_string("format"),
- NXT_CONF_MAP_STR,
+ NXT_CONF_MAP_PTR,
offsetof(nxt_router_access_log_conf_t, format),
},
@@ -65,22 +85,14 @@ nxt_int_t
nxt_router_access_log_create(nxt_task_t *task, nxt_router_conf_t *rtcf,
nxt_conf_value_t *value)
{
- u_char *p;
nxt_int_t ret;
nxt_str_t str;
- nxt_tstr_t *format;
nxt_router_t *router;
nxt_router_access_log_t *access_log;
nxt_router_access_log_conf_t alcf;
- static const nxt_str_t log_format_str = nxt_string("$remote_addr - - "
- "[$time_local] \"$request_line\" $status $body_bytes_sent "
- "\"$header_referer\" \"$header_user_agent\"");
-
nxt_memzero(&alcf, sizeof(nxt_router_access_log_conf_t));
- alcf.format = log_format_str;
-
if (nxt_conf_type(value) == NXT_CONF_STRING) {
nxt_conf_get_string(value, &alcf.path);
@@ -121,25 +133,14 @@ nxt_router_access_log_create(nxt_task_t *task, nxt_router_conf_t *rtcf,
nxt_memcpy(access_log->path.start, alcf.path.start, alcf.path.length);
}
- str.length = alcf.format.length + 1;
-
- str.start = nxt_malloc(str.length);
- if (str.start == NULL) {
- nxt_alert(task, "failed to allocate log format structure");
- return NXT_ERROR;
- }
-
- p = nxt_cpymem(str.start, alcf.format.start, alcf.format.length);
- *p = '\n';
+ rtcf->access_log = access_log;
- format = nxt_tstr_compile(rtcf->tstr_state, &str, NXT_TSTR_LOGGING);
- if (nxt_slow_path(format == NULL)) {
+ rtcf->log_format = nxt_router_access_log_format_create(task, rtcf,
+ alcf.format);
+ if (nxt_slow_path(rtcf->log_format == NULL)) {
return NXT_ERROR;
}
- rtcf->access_log = access_log;
- rtcf->log_format = format;
-
if (alcf.expr != NULL) {
nxt_conf_get_string(alcf.expr, &str);
@@ -153,12 +154,117 @@ nxt_router_access_log_create(nxt_task_t *task, nxt_router_conf_t *rtcf,
}
+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)
+{
+ 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 - - "
+ "[$time_local] \"$request_line\" $status $body_bytes_sent "
+ "\"$header_referer\" \"$header_user_agent\"");
+
+ format = nxt_mp_zalloc(rtcf->mem_pool,
+ sizeof(nxt_router_access_log_format_t));
+ if (nxt_slow_path(format == NULL)) {
+ return NULL;
+ }
+
+ if (value != NULL) {
+
+ 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;
+ }
+
+ format->tstr = nxt_tstr_compile(rtcf->tstr_state, &str,
+ NXT_TSTR_LOGGING | NXT_TSTR_NEWLINE);
+ if (nxt_slow_path(format->tstr == NULL)) {
+ return NULL;
+ }
+
+ return format;
+}
+
+
static void
nxt_router_access_log_writer(nxt_task_t *task, nxt_http_request_t *r,
- nxt_router_access_log_t *access_log, nxt_tstr_t *format)
+ 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));
@@ -168,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)) {
- nxt_tstr_str(format, &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;
@@ -177,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, &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;
}