Documentation
¶
Overview ¶
Package tracing gives Atlas distributed traces (ADR-0142).
Metrics say *that* a request was slow; a trace says *where* the time went, and — once a caller propagates its context — across which services. This package owns the tracer provider, the export path, and the one HTTP wrapper that produces spans.
What is deliberately not traced ¶
The engine. The batch loop is the single writer (invariant I3) and must not allocate (invariant I1), and a span is an allocation, a clock read, and a lock. Nothing in engine/ imports this package and a test enforces that. Traces here cover the HTTP surface, which is where a request's latency is actually attributable and where the work is already per-request rather than per-batch.
Probes and scrapes are not traced either: /healthz, /readyz and /metrics run every few seconds forever and would drown a backend in spans nobody will ever read.
Why the exporter is written here ¶
The official OTLP exporter pulls in protobuf and — even in its HTTP form — gRPC: 66 gRPC packages and about 13MB of binary, for a service that speaks no gRPC anywhere else. ADR-0010 asks for few dependencies and ADR-0142 already declined the OTel *metrics* SDK on the same grounds. OTLP over HTTP has a documented JSON encoding, so this package takes the API and SDK — the parts that are hard and spec-bound: span model, sampling, batching, W3C context propagation — and writes the serializer, which is a schema, by hand. See otlpjson.go.
Index ¶
Constants ¶
const DefaultSampleRatio = 0.1
DefaultSampleRatio is what fraction of traces are recorded when tracing is turned on without a ratio. One in ten keeps a busy server's export affordable while still catching enough of the ordinary traffic to be worth reading; a caller that already decided to sample is always honored (see the sampler below).
const DefaultTimeout = 10 * time.Second
DefaultTimeout bounds one export attempt.
Variables ¶
This section is empty.
Functions ¶
func Handler ¶
Handler wraps h in a server span named for route.
route is the *pattern* — "GET /api/v1/instances/{key}" — not the URL that matched it. That is the whole cardinality discipline in one parameter: the set of span names is bounded by the route table, so it cannot grow with traffic. Callers pass the same string they registered with the mux, so there is nothing to derive and nothing to get wrong at runtime.
With tracing off this is the wrapped handler and one no-op span, which the API's no-op provider compiles down to a few nil checks.
Types ¶
type Config ¶
type Config struct {
// Endpoint is the base URL of an OTLP/HTTP receiver, e.g. http://collector:4318.
// Empty means tracing is off — nothing is sampled and no goroutine is started.
Endpoint string
// ServiceName and Version name this process on every exported resource. A backend
// groups by them; without a name spans arrive as "unknown_service".
ServiceName string
Version string
// SampleRatio is the fraction of new traces recorded, clamped to [0,1]. It is read
// literally: zero records nothing. DefaultSampleRatio is what the *flag* defaults
// to, so an operator who passes 0 gets the nothing they asked for rather than a
// default inferred behind their back.
SampleRatio float64
// Timeout bounds a single export attempt.
Timeout time.Duration
}
Config is how tracing is set up. The zero value is tracing turned off.
type Provider ¶
type Provider struct {
// contains filtered or unexported fields
}
Provider owns the tracer provider installed by Setup. A nil or disabled Provider is safe to use and does nothing, so a caller can defer Shutdown unconditionally.
func Setup ¶
Setup installs the global tracer provider and the W3C context propagator.
With no endpoint it installs nothing: the global provider stays the API's no-op, so Handler is a pass-through and an operator who has not asked for tracing pays for none of it.