Expand description
Request metrics for every surface on the unified listener (D69).
One layer, applied to the merged router in notedthat-server after WebDAV
and MCP are merged onto it. Applied inside crate::router::build_router’s
own ServiceBuilder it would cover the API and the root routes only, since
the other two surfaces are merged afterwards.
§Why the route label is the pattern
route is axum’s MatchedPath — the pattern, …/{kb_slug}/{*object_path},
not the path that matched it. This is the whole of the label-safety story:
the object route and every WebDAV route carry an object key in their path,
and a key in a label would put customer data in an exposition that is
retained for months by whoever scrapes it. A request that matched no route
has no pattern, and its URI is attacker-chosen, so all of them share the one
constant notedthat_core::metrics::ROUTE_UNMATCHED.
§Why the method label is an allow-list
http::Method accepts arbitrary extension tokens, and this layer records
before any 405, so req.method().as_str() would let a client mint
unbounded series by looping over invented verbs. Only the methods this
server actually answers are labelled; anything else is other.
§What the duration means
Time to response head, not to last byte: next.run returns as soon as a
handler produces a Response. That is deliberate. The events route returns
instantly and then streams for hours, so body-completion timing would put
hour-long observations in this histogram and pin the in-flight gauge at the
subscriber count. A live stream’s cost is notedthat_events_subscribers,
and a large read’s backend cost is notedthat_storage_*. Anyone “fixing”
this to measure body completion would silently destroy both.
Functions§
- track_
requests - Count and time every request on every surface.