Add logtail if=$variable filtering and update log format examples

- ipng_stats_logtail now accepts an optional if=$variable parameter
  that suppresses log lines when the variable is empty or "0",
  following the same semantics as nginx's access_log if=. The
  condition is checked before format rendering for zero overhead on
  filtered requests. Filtered requests are still counted by stats.
- Log format examples updated to include $scheme for http/https
  visibility, and renamed to ipng_stats_logtail to match production.
- Robot test added for the if= filter (19 tests, 19 pass).
- FR-8.5 added to design doc for the if= semantics.
This commit is contained in:
2026-04-16 18:49:13 +02:00
parent 5a7e2f77f1
commit 87050bcf13
6 changed files with 124 additions and 30 deletions

View File

@@ -194,6 +194,7 @@ typedef struct {
struct sockaddr_in logtail_udp_addr; /* destination address */
size_t logtail_buf_size; /* per-worker buffer, default 64k */
ngx_msec_t logtail_flush; /* max flush interval, default 1s */
ngx_uint_t logtail_if_index; /* if=$var: variable index, 0=none */
} ngx_http_ipng_stats_main_conf_t;
@@ -908,6 +909,27 @@ ngx_http_ipng_stats_logtail(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
continue;
}
if (value[i].len > 3
&& ngx_strncmp(value[i].data, "if=", 3) == 0)
{
ngx_str_t var_name = { value[i].len - 3, value[i].data + 3 };
if (var_name.len < 2 || var_name.data[0] != '$') {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"ipng_stats_logtail: if= requires a $variable, "
"got \"%V\"", &value[i]);
return NGX_CONF_ERROR;
}
var_name.data++;
var_name.len--;
imcf->logtail_if_index = ngx_http_get_variable_index(cf,
&var_name);
if (imcf->logtail_if_index == (ngx_uint_t) NGX_ERROR) {
return NGX_CONF_ERROR;
}
/* Shift from 0-based to 1-based so 0 means "not set". */
imcf->logtail_if_index++;
continue;
}
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"ipng_stats_logtail: unknown parameter \"%V\"", &value[i]);
return NGX_CONF_ERROR;
@@ -1720,6 +1742,19 @@ ngx_http_ipng_stats_logtail_write(ngx_http_request_t *r,
return;
}
/* if=$variable: skip this request when the variable is empty or "0". */
if (imcf->logtail_if_index) {
ngx_http_variable_value_t *val;
val = ngx_http_get_indexed_variable(r, imcf->logtail_if_index - 1);
if (val == NULL || val->not_found
|| val->len == 0
|| (val->len == 1 && val->data[0] == '0'))
{
return;
}
}
ops = imcf->logtail_fmt->ops->elts;
nops = imcf->logtail_fmt->ops->nelts;