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

@@ -77,6 +77,8 @@ static nxt_int_t nxt_conf_vldt_error(nxt_conf_validation_t *vldt,
const char *fmt, ...);
static nxt_int_t nxt_conf_vldt_var(nxt_conf_validation_t *vldt, nxt_str_t *name,
nxt_str_t *value);
static nxt_int_t nxt_conf_vldt_if(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data);
nxt_inline nxt_int_t nxt_conf_vldt_unsupported(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data)
NXT_MAYBE_UNUSED;
@@ -1369,6 +1371,10 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_access_log_members[] = {
}, {
.name = nxt_string("format"),
.type = NXT_CONF_VLDT_STRING,
}, {
.name = nxt_string("if"),
.type = NXT_CONF_VLDT_STRING,
.validator = nxt_conf_vldt_if,
},
NXT_CONF_VLDT_END
@@ -1538,6 +1544,37 @@ nxt_conf_vldt_var(nxt_conf_validation_t *vldt, nxt_str_t *name,
}
static nxt_int_t
nxt_conf_vldt_if(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
void *data)
{
nxt_str_t str;
static nxt_str_t if_str = nxt_string("if");
if (nxt_conf_type(value) != NXT_CONF_STRING) {
return nxt_conf_vldt_error(vldt, "The \"if\" must be a string");
}
nxt_conf_get_string(value, &str);
if (str.length == 0) {
return NXT_OK;
}
if (str.start[0] == '!') {
str.start++;
str.length--;
}
if (nxt_is_tstr(&str)) {
return nxt_conf_vldt_var(vldt, &if_str, &str);
}
return NXT_OK;
}
typedef struct {
nxt_mp_t *pool;
nxt_str_t *type;