Skip to main content
theauth-go ships with a pluggable tracing + metrics surface. The library imports zero observability vendors: consumers wire their own Tracer and Metrics adapters via theauth.Config.Observability.

Why an adapter

OpenTelemetry, Prometheus, OpenCensus, Datadog, and friends all want to be the one true client. Picking one inside the library would push a 5+ MB transitive dependency on every consumer, even on the ones who use a different stack or no stack at all. Worse, the OpenTelemetry Go SDK has had multiple breaking 1.x bumps; pinning to one version locks every consumer to the same. The adapter sidesteps that. The library knows the spans it wants to emit and the metrics it wants to record; the consumer knows the backend it wants to send them to. Two narrow interfaces (Tracer, Metrics) bridge the two. mcpresource/go.mod stays zero-dep. The observability surface lives entirely in the main theauth-go module; the MCP SDK never touches it.

Wiring

Either field MAY be nil. The library substitutes per-field no-op adapters so existing deployments that do not configure Observability get exactly the pre-2026-06-21 behavior.

Span catalog

Every instrumented operation opens a span at its entry point and closes it at return. The span name and the attributes it carries are listed below. On error the span receives RecordError plus a status="error" attribute and an error_code="<stable code>" attribute matching models.TheAuthError.Code. Span names are exported as theauth.SpanOAuthToken etc. so dashboards reference them by symbol.

Metric catalog

LatencyBuckets is [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5] seconds. Consumers pre-registering Prometheus histograms MUST use the exact same slice. Every metric name is exported as theauth.MetricOAuthTokenRequestsTotal etc.

Cardinality discipline

High-cardinality identifiers (client_id, user_id, session_id, IP) go on spans as attributes, NEVER on metric labels. The library enforces this at the call site by review; the public Labels type does not stop you putting a high-cardinality value in by hand. Prometheus operators should validate label sets via promtool check rules. The fixed label sets the library uses:
  • grant_type: one of authorization_code, refresh_token, client_credentials, token-exchange
  • status: success or error
  • rule: one of ip, email
  • kind: one of oauth_client
  • tenant_id: organization ULID or empty string

Adding a new instrument

  1. Add the name constant to internal/observability/hooks.go.
  2. Add the matching re-export in observability.go.
  3. Update this document with the metric / span row.
  4. Add the emit call at the service surface.
  5. Update the PR description’s span+metric matrix.
The catalog is exhaustively re-exported so consumers building dashboards can grep theauth.Metric in their config to find every name the library emits.
Last modified on October 7, 2026