Documentation
¶
Index ¶
- Variables
- func HTTPMetricsMiddleware(m *Metrics) func(http.Handler) http.Handler
- func HashToken(key, token string) string
- func Init(ctx context.Context, serviceName string) (func(), error)
- func Logger(ctx context.Context) *slog.Logger
- func NewRedactHandler(inner slog.Handler) slog.Handler
- func PanicMiddleware(next http.Handler) http.Handler
- func RequestIDFromContext(ctx context.Context) (string, bool)
- func RequestMiddleware(skipPaths ...string) func(http.Handler) http.Handler
- func SecurityEvent(ctx context.Context, event string, attrs ...any)
- func SourceIPFromContext(ctx context.Context) string
- func SourceIPMiddleware(next http.Handler) http.Handler
- func SourceIPMiddlewareWithTrustedCIDRs(trustedCIDRs []*net.IPNet) func(http.Handler) http.Handler
- func TraceMiddleware(next http.Handler) http.Handler
- func UserAgentFromContext(ctx context.Context) string
- type DBTracer
- type InstrumentedMux
- type Metrics
Constants ¶
This section is empty.
Variables ¶
var LevelVar = &slog.LevelVar{}
LevelVar is the runtime-adjustable log level for the process. External code (e.g. a debug endpoint) may call LevelVar.Set(slog.LevelDebug).
Functions ¶
func HTTPMetricsMiddleware ¶
HTTPMetricsMiddleware records http_requests_total and http_request_duration_seconds for every request. It must run outside PanicMiddleware so that panics are recorded with status 500: PanicMiddleware writes its 500 response through the responseWriter captured here.
It injects a *routeContainer into context; InstrumentedMux fills it with the matched route pattern so the defer can use it as a label value.
func HashToken ¶
HashToken returns the HMAC-SHA256 of token keyed with key, encoded as hex. Returns "" when key is empty so callers can omit the attr gracefully rather than leak raw tokens when SESSION_HMAC_KEY is not configured.
func Init ¶
Init configures the global slog logger and OTel TracerProvider:
- JSON output to stdout, UTC timestamps, PII redaction
- Log level from LOG_LEVEL env var (DEBUG/INFO/WARN/ERROR; default INFO)
- "service.name" attr on every log record (OTel semantic convention)
- OTLP/gRPC TracerProvider reading OTEL_EXPORTER_OTLP_* from env
- W3C TraceContext propagator
If OTEL_EXPORTER_OTLP_ENDPOINT is not set, tracing is disabled (no-op provider) and a warning is logged. This allows local dev without a collector.
The shutdown func flushes pending spans with a 5-second timeout and must be called before the process exits (wire it to SIGTERM).
func Logger ¶
Logger returns the default slog logger pre-decorated with trace_id, span_id, request_id, and user.id extracted from ctx. Call this in handlers and services instead of bare slog.Info so every log line carries request context.
func NewRedactHandler ¶
NewRedactHandler wraps inner with the default deny-list and regex patterns.
func PanicMiddleware ¶
PanicMiddleware recovers from panics in downstream handlers, logs the stack trace, marks the active span as an error, and returns 500.
func RequestIDFromContext ¶
RequestIDFromContext returns the request ID stored in ctx, if any.
func RequestMiddleware ¶
RequestMiddleware assigns a request ID (trace ID when a span is active, UUIDv7 otherwise), sets X-Request-ID on the response, and logs a canonical request line at completion. It must run inside TraceMiddleware (span active) and after the auth middleware (user in context).
func SecurityEvent ¶
SecurityEvent logs a security-relevant event at WARN level with log_type=security. It automatically attaches trace_id, span_id, request_id, source_ip, and user.id from ctx (via Logger). Callers supply event-specific attrs as key-value pairs.
Session tokens must be hashed before passing as attr values; use HashToken.
func SourceIPFromContext ¶
SourceIPFromContext returns the client IP injected by SourceIPMiddleware.
func SourceIPMiddleware ¶
SourceIPMiddleware extracts the client IP and injects it into context. X-Forwarded-For is only trusted when the connecting IP is in trustedCIDRs. Pass nil or empty slice to always use RemoteAddr (safe default, no proxy). Place this inside TraceMiddleware so the span is already active.
func SourceIPMiddlewareWithTrustedCIDRs ¶
SourceIPMiddlewareWithTrustedCIDRs is like SourceIPMiddleware but only trusts X-Forwarded-For when the connecting IP matches one of the trusted CIDR ranges.
func TraceMiddleware ¶
TraceMiddleware wraps next with otelhttp, starting an OTel span for every request and propagating W3C traceparent headers. It must be the outermost middleware so the span is active for all downstream code.
func UserAgentFromContext ¶
UserAgentFromContext returns the User-Agent injected by SourceIPMiddleware.
Types ¶
type DBTracer ¶
type DBTracer struct {
// contains filtered or unexported fields
}
DBTracer is a composite pgx.QueryTracer that:
- delegates to otelpgx for OTel span creation (one span per sqlc query)
- records db_query_duration_seconds Prometheus histogram observations
Wire it into the pgxpool config before creating the pool:
config.ConnConfig.Tracer = obs.NewDBTracer(metrics.DBDuration)
func NewDBTracer ¶
func NewDBTracer(hist *prometheus.HistogramVec) *DBTracer
NewDBTracer creates a DBTracer. Parameter capture is intentionally OFF (otelpgx default): query parameters include session tokens, user IDs, and PII. Enabling capture via otelpgx.WithIncludeQueryParameters() would leak them into the OTLP backend.
func (*DBTracer) TraceQueryEnd ¶
TraceQueryEnd is called after the query completes (success or error).
type InstrumentedMux ¶
type InstrumentedMux struct {
// contains filtered or unexported fields
}
InstrumentedMux wraps *http.ServeMux so that each dispatch uses mux.Handler to resolve the matched pattern and injects it as an otelhttp route tag. otelhttp will then rename the span to "{method} {pattern}" after the handler returns.
No changes to module Register functions are required.
func NewInstrumentedMux ¶
func NewInstrumentedMux(mux *http.ServeMux) *InstrumentedMux
NewInstrumentedMux wraps mux with route-pattern tagging for OTel spans.
func (*InstrumentedMux) ServeHTTP ¶
func (m *InstrumentedMux) ServeHTTP(w http.ResponseWriter, r *http.Request)
type Metrics ¶
type Metrics struct {
// HTTPRequests counts completed HTTP requests.
HTTPRequests *prometheus.CounterVec
// HTTPDuration measures HTTP request latency end-to-end.
HTTPDuration *prometheus.HistogramVec
// DBDuration measures individual DB query latency by sqlc method name.
DBDuration *prometheus.HistogramVec
}
Metrics holds the three core Prometheus instrumentation vectors. All label values must be bounded: use route patterns, HTTP methods, and status codes only. Never use raw URLs, user IDs, or resource IDs as label values — unbounded cardinality will cause Prometheus memory exhaustion.
func NewMetrics ¶
func NewMetrics(reg prometheus.Registerer) *Metrics
NewMetrics creates and registers the three core metric vectors against reg.