From bc838c5e1b6270c5195c4bdaa6a0a4bb72e48549 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Mon, 28 Oct 2024 17:45:19 +0800 Subject: http: Support JSON format in access log Allow format to be an object to generate JSON logs. The object keys become JSON field names, and values support string, variable, and JS. Note that when there is no JS in the format values, the object will be pre-serialized to a JSON template string at configuration phase for better performance. Example config: { "access_log": { "path": "/tmp/access.log", "format": { "remote_addr": "$remote_addr", "time_local": "$time_local", "request_line": "$request_line", "status": "$status", "body_bytes_sent": "$body_bytes_sent", "header_referer": "$header_referer", "header_user_agent": "$header_user_agent" } } } --- src/nxt_conf_validation.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) (limited to 'src/nxt_conf_validation.c') 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; +} -- cgit