httpsnoop
Captures HTTP status code, duration, and bytes written from Go handlers without breaking ResponseWriter's optional interfaces.
Repository Health
Technical Analysis
httpsnoop is a small Go library for capturing HTTP handler metrics — status code, response duration, and bytes written — without the interface-breaking side effects that come from naively wrapping http.ResponseWriter. Many response writers implement extra interfaces such as http.Flusher, http.Hijacker, http.CloseNotifier, http.Pusher, or io.ReaderFrom, and a wrapper that fails to preserve them can silently break streaming, websocket upgrades, or connection hijacking in production.
The package solves this with CaptureMetrics and Wrap, a generated, allocation-light dispatcher that detects exactly which optional interfaces the underlying ResponseWriter implements and returns a wrapped writer exposing that exact same combination, routing calls through user-supplied hook functions. The result is a drop-in instrumentation layer that’s safe to use inside reverse proxies, middleware chains, and observability tooling.
What You Get
- CaptureMetrics / CaptureMetricsFn helpers that wrap a handler or a ResponseWriter directly and return Code, Duration, and Written for a single request/response cycle
- Wrap(w, Hooks) — a generic, hook-based ResponseWriter wrapper for building custom instrumentation or middleware
- Full interface-preserving support for http.Flusher, http.Hijacker, http.CloseNotifier, http.Pusher, io.ReaderFrom, io.StringWriter, and the Go 1.20+/1.21+ deadline, FlushError, and EnableFullDuplex interfaces
- Unwrap helper to recover the original ResponseWriter through any number of stacked httpsnoop wrapper layers
Common Use Cases
- Logging middleware that needs an accurate status code and response size per request
- Prometheus or OpenTelemetry HTTP instrumentation built on top of Hooks
- Reverse proxies and API gateways that must preserve streaming and hijacking behavior
- Building custom request/response observability tooling on top of the standard library’s http.Handler
Under The Hood
Architecture
The package is organized around three parts: capture_metrics.go (the public API — CaptureMetrics, CaptureMetricsFn, and Metrics.CaptureMetrics), wrap_generated.go (a large generated file implementing hundreds of combinatorial ResponseWriter wrapper variant types over a shared rwState struct via zero-cost pointer conversion), and codegen/main.go (the generator that defines the interface list — http.ResponseWriter, http.Flusher, httpFlushError, http.CloseNotifier, http.Hijacker, io.ReaderFrom, deadliner, fullDuplexEnabler, http.Pusher, io.StringWriter — and emits per-combination types, do<Method> dispatch funcs, and the hook-wiring logic inside Wrap). Rather than reflection or a runtime type-switch on every call, Wrap computes a combo bitmask once by type-asserting the input ResponseWriter, then returns a pointer cast to one of the pre-generated combination types whose method set exactly matches what the original writer supports — so every subsequent method call dispatches directly through rwState.do<Method> with no reflection in the hot path. Changing the core abstraction (the Hooks struct or the interface list in codegen/main.go) requires regenerating both wrap_generated.go and its matching test file via go generate.
Tech Stack
Go 1.25, standard library only — go.mod declares zero third-party dependencies. The package uses net/http, io, net, bufio, and time in the generated wrapper, and bytes/errors/testing in tests. Build and verification run through a Makefile (go test, go vet, gofmt checks) and a GitHub Actions workflow (.github/workflows/main.yaml); code generation is driven by //go:generate go run codegen/main.go in docs.go, keeping generation and consumption in the same module rather than a separate build step.
Code Quality
Tests exist and are extensive: capture_metrics_test.go, wrap_test.go, unwrap_test.go, plus a generated wrap_generated_test.go that exhaustively exercises every supported interface combination against a synthetic ResponseWriter, verifying both the interface set exposed by Wrap and correct Unwrap behavior. Benchmarks (wrap_bench_test.go, capture_metrics_bench_test.go) track the overhead CaptureMetrics adds over a bare handler. Error handling favors explicit returns; the one panic("unreachable") in the generated Wrap switch is a defensive guard against a combination that should be impossible to reach given the preceding type assertions. Naming and structure are idiomatic stdlib-style Go, with CI wired via GitHub Actions and no assertion library or mocking framework beyond testing and hand-written fakes.
What Makes It Unique
The distinguishing choice is generating a combinatorial set of concrete wrapper types at build time instead of using a single fat wrapper struct with reflection-based interface checks per call, or the naive single-struct approach the README explicitly warns readers away from. This trades extra generated code for compile-time-exhaustive interface preservation and reflection-free dispatch, directly targeting a documented, easy-to-get-wrong problem: a ResponseWriter wrapper silently dropping Flusher, Hijacker, or CloseNotifier support and breaking streaming or hijacking in production. The package also carries targeted compatibility fallbacks — routing WriteString through a configured Write hook, and FlushError through a configured Flush hook — so newer optional interfaces don’t change behavior for callers who only configured the older hooks.
Used by 5 apps in this directory
Authgear
Authentication
Open-source, self-hostable authentication platform with passkeys, biometric login, SSO, MFA, and GraphQL admin API — a full Auth0/Clerk/Firebase alternative for SaaS and mobile apps.
Convoy
Developer Tools · Devops
Convoy is an open-source, cloud-native webhooks gateway that ingests events over HTTP or straight from Kafka, SQS, Google Pub/Sub, and RabbitMQ, then reliably delivers them to subscriber endpoints with signed payloads, automatic retries, circuit breaking, and JavaScript-based transformations.
Nakama
Developer Tools · Game Development
Open-source game backend server with built-in multiplayer, matchmaking, leaderboards, chat, authentication, and storage — deploy anywhere via Docker or binary.
Pyroscope
Monitoring · Devops · Developer Tools
An open-source, horizontally scalable continuous profiling platform that pinpoints CPU, memory, and I/O bottlenecks down to the exact line of code, built by Grafana Labs alongside Loki, Tempo, and Mimir.
Weaviate
Databases · Search
Open-source vector database combining semantic search, hybrid queries, RAG, and image search in a single cloud-native system built for production scale.