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

@@ -175,10 +175,10 @@ Each requirement carries a unique identifier (`FR-X.Y` or `NFR-X.Y`) so that lat
**FR-8 Logtail**
- **FR-8.1** The module MUST support an `ipng_stats_logtail <format_name> udp://host:port [buffer=<size>] [flush=<duration>]` directive
at the `http` level that registers a global log-phase writer which fires unconditionally for every request, regardless of which
`server` or `location` block handled it. One directive at the `http` level is sufficient to cover all vhosts — operators MUST NOT be
required to repeat an `access_log` directive in every `server` block to achieve a single global access log.
- **FR-8.1** The module MUST support an `ipng_stats_logtail <format_name> udp://host:port [buffer=<size>] [flush=<duration>] [if=$var]`
directive at the `http` level that registers a global log-phase writer which fires for every request (unless suppressed by `if=`),
regardless of which `server` or `location` block handled it. One directive at the `http` level is sufficient to cover all vhosts —
operators MUST NOT be required to repeat an `access_log` directive in every `server` block to achieve a single global access log.
- **FR-8.2** The `<format_name>` argument MUST be the name of an existing nginx `log_format` defined in the same `http` block before
this directive. The module MUST look up the compiled log format from nginx's log module at configuration time and use it to render each
log line at request time. The module MUST NOT define its own format language; all `$variable` expansion is handled by nginx's standard
@@ -194,6 +194,11 @@ Each requirement carries a unique identifier (`FR-X.Y` or `NFR-X.Y`) so that lat
present are intentional; the UDP transport is designed for fire-and-forget analytics pipelines where delivery guarantees are
unnecessary and zero disk I/O is preferred over persistence. File-based access logging is not supported by this directive — operators
should use nginx's built-in `access_log` for that purpose.
- **FR-8.5** The directive MAY include an `if=$variable` parameter. When present, the logtail writer MUST evaluate the named nginx
variable at log phase and MUST suppress the log line if the variable is not found, is empty, or equals the string `"0"`. The
condition MUST be checked before the log format is rendered, so that filtered requests incur no formatting cost. This follows the same
semantics as nginx's built-in `access_log ... if=` and is intended for suppressing high-frequency requests (e.g. health checks) from
the logtail stream. Filtered requests MUST still be counted by the stats module — the `if=` condition affects only logtail output.
### Non-Functional Requirements