HTTP: enhanced access log with conditional filtering.

This feature allows users to specify conditions to control if access log
should be recorded. The "if" option supports a string and JavaScript code.
If its value is empty, 0, false, null, or undefined, the logs will not be
recorded. And the '!' as a prefix inverses the condition.

Example 1: Only log requests that sent a session cookie.

    {
        "access_log": {
            "if": "$cookie_session",
            "path": "..."
        }
    }

Example 2: Do not log health check requests.

    {
        "access_log": {
            "if": "`${uri == '/health' ? false : true}`",
            "path": "..."
        }
    }

Example 3: Only log requests when the time is before 22:00.

    {
        "access_log": {
            "if": "`${new Date().getHours() < 22}`",
            "path": "..."
        }
    }

or

    {
        "access_log": {
            "if": "!`${new Date().getHours() >= 22}`",
            "path": "..."
        }
    }

Closes: https://github.com/nginx/unit/issues/594
This commit is contained in:
Zhidao HONG
2024-01-23 18:57:30 +08:00
parent 37abe2e463
commit 4c91bebb50
4 changed files with 112 additions and 6 deletions

View File

@@ -13,6 +13,7 @@
typedef struct {
nxt_str_t path;
nxt_str_t format;
nxt_conf_value_t *expr;
} nxt_router_access_log_conf_t;
@@ -53,6 +54,12 @@ static nxt_conf_map_t nxt_router_access_log_conf[] = {
NXT_CONF_MAP_STR,
offsetof(nxt_router_access_log_conf_t, format),
},
{
nxt_string("if"),
NXT_CONF_MAP_PTR,
offsetof(nxt_router_access_log_conf_t, expr),
},
};
@@ -72,6 +79,8 @@ nxt_router_access_log_create(nxt_task_t *task, nxt_router_conf_t *rtcf,
"[$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) {
@@ -133,6 +142,22 @@ nxt_router_access_log_create(nxt_task_t *task, nxt_router_conf_t *rtcf,
rtcf->access_log = access_log;
rtcf->log_format = format;
if (alcf.expr != NULL) {
nxt_conf_get_string(alcf.expr, &str);
if (str.length > 0 && str.start[0] == '!') {
rtcf->log_negate = 1;
str.start++;
str.length--;
}
rtcf->log_expr = nxt_tstr_compile(rtcf->tstr_state, &str, 0);
if (nxt_slow_path(rtcf->log_expr == NULL)) {
return NXT_ERROR;
}
}
return NXT_OK;
}