feat(metrics): expose HTTP RED metrics (request rate + duration)#709
Merged
Conversation
Add http_requests_total{method,route,status} and an
http_request_duration_seconds histogram (per route) to /api/metrics,
recorded by a global RequestMetricsInterceptor. The interceptor listens
for response finish/close (so it sees the final status set by exception
filters, not the pre-filter 200), records once per request, and skips
/api/health + /api/metrics. Route labels use the Express route pattern
(bounded) with a Controller#handler fallback. Dependency-free (no
prom-client), extending the existing bespoke Prometheus-text layer;
conventional unprefixed names so a generic RED dashboard or 5xx
error-rate alert matches them.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
/api/metricsnow exposes HTTP RED metrics:http_requests_total{method,route,status}(counter) andhttp_request_duration_seconds(histogram, per route), recorded by a new globalRequestMetricsInterceptor.Why
The metrics surface had business gauges/counters (sessions, messages, webhook failures) but no request rate/error/latency — so an SLO, an error-rate alert, or a latency dashboard had nothing to read. This adds the standard RED signals.
Design
prom-client), mirroringwebhook-delivery-metrics.ts. Conventional unprefixed names (http_requests_total,http_request_duration_seconds) so a generic RED dashboard/alert matches.resfinish/close, not the handler observable'stap, because exception filters set the finalstatusCodeafter the interceptor's observable chain. One observation per request (arecordedguard handles both events firing)./api/sessions/:id, not the raw URL); falls back toController#handlerwhen no Express route./api/healthand/api/metricsare not counted.Test plan
request-metrics.spec.ts(6 cases) — counter aggregation, cumulative histogram buckets, HELP/TYPE emitted once, label escaping, reset. TDD: written first against a stub, watched fail, then implemented.request-metrics.interceptor.spec.ts(5 cases) — records on finish with method/route/status/duration, skips health/metrics, records filter-set 5xx, Controller#handler fallback, single record across finish+close.tsc -p tsconfig.json(full program), format,nest build, 2301 tests.