observe package provides optional, dependency-free observability hooks:
a low-cardinality metrics counter interface (with a no-op default and a slog
adapter) and structured-logging helpers for security events. There is no
Prometheus or other metrics dependency — your application bridges the
Metrics interface to its own registry. log/slog is stdlib, so this package
adds nothing to go.mod.
Import
Metrics
Metrics is a single-method interface — one fixed, low-cardinality Event
enum, no label map:
Low-cardinality discipline
The only label is the fixedEvent enum. Never add a username, client IP,
session ID, or token as a label or log field — that’s both a
metrics-cardinality-explosion DoS and a PII leak.
Bundled sinks
Wiring into securityhttp
observe.Hooks bundles a Metrics sink and an optional *slog.Logger; securityhttp.New/NewHandler thread it through the assembled chain (an authz denial
increments EventAccessDenied/EventAuthFailure, a 429 increments
EventRateLimited). Wire observe.Hooks.Metrics to whatever registry your
service already exports to — Prometheus (see the bridge above) or
OpenTelemetry both work the same way: implement Inc(Event) and forward it
to a Counter/CounterVec in that registry.
observe.Hooks{}.WithDefaults() fills in NopMetrics and slog.Default()
where unset, so a zero-value Hooks is safe to pass around.
Wiring authn events directly
observe has no publisher of its own — authn.Manager publishes success/
failure through core/event.Publisher, whose only two methods are
PublishAuthSuccess / PublishAuthFailure:
event.FuncPublisher and bump your Metrics sink
from them:
auth passed to PublishAuthFailure is already sanitized (any plaintext
password cleared), so it’s safe to key on auth.Name().
