Skip to content

Let the middleware skip paths or log them only on failure - #5

Merged
gustavofreze merged 1 commit into
mainfrom
feat/path-filters
Sep 24, 2026
Merged

gustavofreze merged 1 commit into
mainfrom
feat/path-filters

Conversation

@gustavofreze

Copy link
Copy Markdown
Member

Summary

Every inbound exchange was logged, which made probes and periodic internal calls the bulk of a service's log. Measured
on one fleet over 24 hours: health checks were 67.8% of every byte logged and scheduled sweeps another 15.6%, both
billed per ingested gigabyte, while a failing probe or sweep is already visible to whoever calls it.

The builder gains two options, both matching $request->getUri()->getPath() by exact string equality:

LogMiddleware::create()
    ->withLogger(logger: $logger)
    ->withIgnoredPaths('/health/readiness')
    ->withFailureOnlyPaths('/v1/outbox/dispatches')
    ->build();
  • withIgnoredPaths never logs the listed paths, neither the request nor the response entry, whatever the status.
  • withFailureOnlyPaths logs the listed paths only when the response is an error (4xx or 5xx). On failure it writes
    the request and response entries after the handler returns, with the same context as on any other path. A path
    in both lists is never logged.
  • Every other path is logged exactly as before, and LogMiddleware::build(clock:, logger:) keeps working unchanged,
    with the two lists as optional trailing parameters.

One behaviour to know: a handler that throws on a failure-only path produces no entry, because there is no response
to judge. An error middleware running inside this one turns the exception into a 5xx response, which is then logged.
The README says so.

Related issue

None. The need came from measuring a consumer's log volume.

Checklist

  • Tests added or updated. 11 new test methods, 50 tests in total: ignored paths for 200, 204, 404 and 503;
    failure-only paths silent on 200, 201, 204 and 302 and logged on 400, 404, 422, 500 and 503; unlisted paths
    unchanged; exact matching against prefix, suffix, trailing slash, extra segment and case; correlation id on a
    failure-only failure; backward compatibility of the builder and of build(); a path in both lists.
  • Documentation updated when applicable. README sections "Ignoring paths" and "Logging paths only on failure".
  • make review passes.
  • make tests passes: 50 tests, 89 assertions, 52 mutants, all killed, MSI 100%.

Every inbound exchange was logged, which made probes and periodic
internal calls the bulk of a service's log. Measured on one fleet over
a day, health checks were two thirds of every byte logged and scheduled
sweeps another sixth, while saying nothing their callers do not already
see.

The builder gains two options, both matching the request path exactly.
withIgnoredPaths never logs the listed paths. withFailureOnlyPaths logs
the listed paths only when the response is an error, and then writes
the request and response entries with the same context as any other
path. Every other path is logged as before, and build(clock:, logger:)
keeps working unchanged.
@gustavofreze
gustavofreze merged commit 33367b2 into main Sep 24, 2026
5 checks passed
@gustavofreze
gustavofreze deleted the feat/path-filters branch September 24, 2026 19:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant