Skip to content

feat!: group 404s without a matching route under one url label by default - #5

Open
brommell wants to merge 1 commit into
labstack:mainfrom
brommell:feat/404-single-url-label
Open

brommell wants to merge 1 commit into
labstack:mainfrom
brommell:feat/404-single-url-label

Conversation

@brommell

Copy link
Copy Markdown

Summary

Requests that match no route are now recorded with an empty url label by default, instead of the raw request path.
The new UseRequestPathFor404 option restores the old behaviour. DoNotUseRequestPathFor404 still compiles, but is
deprecated and has no effect, since its behaviour is now the default. 404s returned by a matched route keep their
route pattern, as before.

This is a breaking change for anyone who reads per-path 404 metrics.

Why

The url label is meant to hold the route pattern (/users/:id), which has a small, fixed set of values. For a 404
with no matching route, Echo leaves the route path empty and the middleware falls back to the raw request path: a value
the client fully controls.

  • Unbounded series. Each distinct url value creates 41 series with the default metrics: 1 for requests_total,
    14 for request_duration_seconds, 13 each for request_size_bytes and response_size_bytes. A single scanner
    trying 5,000 paths adds about 205,000 series, more than most applications' useful metrics, and anyone who can reach
    the server can push this further. Prometheus middleware generates new metrics for every 404 echo-contrib#86 reported that this "can easily generate millions of
    timeseries".
  • Personal data in metrics. Paths can carry IDs, e-mail addresses or tokens (/users/[email protected]/profile,
    /reset/<token>). Metrics are usually kept longer and visible to more people than application logs.
  • Little value lost. Per-path detail for unknown routes is rarely what dashboards and alerts use. The 404 rate
    stays visible through code="404", and those who need the paths can opt in.

Why now

The opt-in flag was added in labstack/echo-contrib#111 to address labstack/echo-contrib#86, and the default was kept
for compatibility. This module starts fresh at v0.0.1, which makes it the least disruptive point to make the safe
behaviour the default.

Migration

You want Before After
404s grouped under one label DoNotUseRequestPathFor404: true nothing, it is the default (the field can be removed)
the request path for 404s nothing UseRequestPathFor404: true

Also

  • Removes the stale "as of Echo v4.10.1" comment. This module targets Echo v5, where the route path is still empty
    when no route matched.

Tests

  • Existing 404 tests now expect url=""; TestInvalidUTF8PathIsFixed opts into raw paths, which it tests.
  • New TestUseRequestPathFor404.
  • go vet, go test -race and staticcheck pass on Go 1.26.

If you'd rather not change the default in v0.x, I'm happy to turn this into a documentation change for
DoNotUseRequestPathFor404 instead.

Co-Authored-By: Claude Opus 5.5 [email protected]

…ault

Requests that match no route used to get the request path as the url
label. Every unknown path (scanners, bots) then created a new set of
series - over 40 per path with the default histograms - and request
paths can carry IDs or personal data into the metrics.

Now these 404s share the same empty url label by default. The new
UseRequestPathFor404 option restores the request path.
DoNotUseRequestPathFor404 is kept for compatibility, deprecated and
without effect, since its behaviour is now the default.

Also drops the stale "as of Echo v4.10.1" note: this module targets
Echo v5, where the route path is still empty when nothing matched.

BREAKING CHANGE: 404s without a matching route get url="" unless
UseRequestPathFor404 is set.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
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