feat: automatic HTTP/gRPC request metrics#4
Merged
Conversation
…dleware seam The prometheus bundle exposed RecordHTTPRequest/RecordGRPCRequest but nothing called them outside the example, so "automatic metrics" weren't automatic. Add a bundle-time extension seam on framework.App — AddUnaryInterceptor, AddStreamInterceptor, and AddHTTPMiddleware — that bundles can call from Initialize (which always runs before the gRPC/HTTP servers are built), with safe no-ops if called after server construction. AddHTTPMiddleware wraps the full handler built by startHTTPServer (health, metrics, pprof, and user HTTPRegistrar routes). Wire the prometheus bundle's Initialize to register a gRPC interceptor pair (status derived from google.golang.org/grpc/status) and an HTTP middleware that records duration/status against RecordGRPCRequest/RecordHTTPRequest for every call, with no per-handler code required. The HTTP endpoint label prefers the low-cardinality r.Pattern (Go 1.22+ ServeMux route template), falling back to the raw path only for unmatched requests. Manual RecordHTTPRequest/RecordGRPCRequest calls remain fully supported.
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.
Closes the review's "automatic metrics aren't automatic" gap (M4). Adding the prometheus bundle now records request metrics with zero per-handler code.
New framework seam
Bundles receive
*AppinInitialize(which runs before servers are built) but previously had no way to add interceptors or middleware post-construction. Added:AddUnaryInterceptor/AddStreamInterceptor— append to the gRPC interceptor chainsAddHTTPMiddleware(func(http.Handler) http.Handler)— ordered middleware applied around the HTTP mux (health, metrics, pprof, and user routes)All three are no-ops if called after the relevant server is built, and append under the app lock.
Prometheus wiring
Initializeregisters a gRPC unary+stream interceptor (status label fromstatus.Code(err).String()) whenEnableGRPCMetrics, and an HTTP middleware whenEnableHTTPMetrics. ManualRecordHTTPRequest/RecordGRPCRequeststill work — purely additive.Cardinality: the HTTP endpoint label uses
r.Pattern(Go 1.22+ matched route template, e.g.GET /users/{id}), falling back to the raw path only for unmatched 404s.Tests
New framework seam tests (real gRPC call + real HTTP request through seam-added interceptor/middleware; no-op-after-build) and prometheus wiring tests (end-to-end counter increments via prometheus testutil, status derivation, pattern-vs-path labeling).
Full
-racesuite green, lint 0 issues.Note: a follow-up docs pass will document this new API and the now-true automatic-metrics claims.
🤖 Generated with Claude Code