Documentation
¶
Overview ¶
Package telemetry wires a service's traces and metrics as one stack.
The two signals must agree on three facts: the `service.name` both report under, whether the HTTP layer is instrumented at all (one otelhttp wrapper emits both), and shutdown. Init returns a value that owns all three, plus the Prometheus registry and scrape listener, so two stacks can coexist in one process. The stack initialised last also becomes the process-wide default: `otel.Tracer` / `otel.Meter` in application code report through it.
Index ¶
- Constants
- type Config
- type MetricsConfig
- type OTelConfig
- type Telemetry
- func (t *Telemetry) AdminErr() <-chan error
- func (t *Telemetry) HTTPMiddleware() server.Middleware
- func (t *Telemetry) MeterProvider() otelmetric.MeterProvider
- func (t *Telemetry) Registerer() prom.Registerer
- func (t *Telemetry) ScrapeHandler() http.Handler
- func (t *Telemetry) ScrapeURL() string
- func (t *Telemetry) Shutdown(ctx context.Context) error
- func (t *Telemetry) TracerProvider() oteltrace.TracerProvider
Constants ¶
const ( ExporterNone = "none" ExporterStdout = "stdout" ExporterPrometheus = "prometheus" ExporterOTLPgRPC = "otlp_grpc" ExporterOTLPHTTP = "otlp_http" )
Exporter selector values for OTelConfig.Exporter and MetricsConfig.Exporter. Stdout is traces-only, Prometheus metrics-only.
const ( DefaultAdminAddr = ":9090" DefaultMetricsPath = "/metrics" )
DefaultAdminAddr is the conventional Prometheus scrape port; DefaultMetricsPath is the route the listener serves when MetricsConfig.Path is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
ServiceName string `yaml:"serviceName"`
OTel OTelConfig `yaml:"otel"`
Metrics MetricsConfig `yaml:"metrics"`
}
Config is the telemetry block of a project's config.yaml. ServiceName sits above both signals and fills in for an empty per-signal name.
type MetricsConfig ¶
type MetricsConfig struct {
// Enabled installs the meter, the metrics side of the HTTP wrapper
// and, for the prometheus exporter, the scrape listener. False is a
// complete no-op.
Enabled bool `yaml:"enabled"`
// Exporter selects the data path:
// - "prometheus" / "" - pull on AdminAddr (the default; any unknown
// value scrapes too, so a typo never silently turns metrics off)
// - "otlp_grpc" - push via OTLP gRPC
// - "otlp_http" - push via OTLP HTTP/protobuf
// - "none" - meter installed without exporter (testing)
Exporter string `yaml:"exporter"`
// Endpoint is the collector address for the OTLP exporters, in the
// same forms as [OTelConfig.Endpoint]. Ignored for "prometheus" / "none".
Endpoint string `yaml:"endpoint"`
// ServiceName is the `service.name` stamped on every metric. Empty
// inherits the top-level serviceName; set it only to report metrics
// under a different identity from traces.
ServiceName string `yaml:"serviceName"`
// AdminAddr is the bind address of the Prometheus scrape listener
// (`:9090`, `127.0.0.1:9090`, ...). Empty starts no listener - serve
// [Telemetry.ScrapeHandler] on a route of the public server instead.
// Ignored unless the exporter scrapes.
AdminAddr string `yaml:"adminAddr"`
// Path is the scrape route, [DefaultMetricsPath] when empty. Override
// when a reverse proxy already claims that path.
Path string `yaml:"path"`
}
MetricsConfig is the `metrics:` block: whether metrics are on, where they go, and the scrape listener for the Prometheus path.
type OTelConfig ¶
type OTelConfig struct {
// Enabled installs the tracer and the trace side of the HTTP wrapper.
// False is a complete no-op.
Enabled bool `yaml:"enabled"`
// ServiceName is the `service.name` stamped on every span. Empty
// inherits the top-level serviceName; set it only to report spans
// under a different identity from metrics. With both empty the SDK
// default `unknown_service:<binary>` applies.
ServiceName string `yaml:"serviceName"`
// Exporter selects the destination for spans:
// - "none" / "" - in-process spans only (ids in logs, no export)
// - "stdout" - JSON spans on stdout (debugging)
// - "otlp_grpc" - push to an OTLP collector via gRPC
// - "otlp_http" - push to an OTLP collector via HTTP/protobuf
Exporter string `yaml:"exporter"`
// Endpoint is the collector address for the OTLP exporters, ignored
// for "none" / "stdout":
// - otlp_http: a full URL WITH scheme - the scheme picks transport
// security: `http://collector:4318` (plaintext) or
// `https://collector.example.com` (TLS).
// - otlp_grpc: a bare `host:port` (e.g. `collector:4317`, plaintext)
// OR a full URL whose scheme picks security
// (`https://collector:4317` for TLS).
Endpoint string `yaml:"endpoint"`
}
OTelConfig is the `otel:` block: whether traces are on and where spans go.
type Telemetry ¶
type Telemetry struct {
// contains filtered or unexported fields
}
Telemetry is a live stack: providers, the registry the scrape gathers, and the listener serving it. A nil *Telemetry is usable - every method degrades to a no-op, so callers never branch on it.
func Init ¶
Init builds the stack described by c. Either signal, both, or neither may be enabled. The Prometheus scrape gets its own listener (`metrics.adminAddr`), not the public API port, so it can be firewalled separately.
func (*Telemetry) AdminErr ¶
AdminErr surfaces a bind or post-startup failure of the scrape listener, or nil when none runs. Callers must check for nil: receiving from a nil channel blocks forever.
func (*Telemetry) HTTPMiddleware ¶
func (t *Telemetry) HTTPMiddleware() server.Middleware
HTTPMiddleware instruments every request against this stack's providers, never the global slots: one otelhttp wrapper emits the span and the http.server.* instruments, and a traced stack injects the W3C trace context (`traceparent`, plus `tracestate` when set) onto the response so clients can attach to the same trace. A signal that is off uses the no-op provider, and with both off the middleware is a plain pass-through, so an unconfigured process pays nothing.
func (*Telemetry) MeterProvider ¶
func (t *Telemetry) MeterProvider() otelmetric.MeterProvider
func (*Telemetry) Registerer ¶
func (t *Telemetry) Registerer() prom.Registerer
Registerer exposes the registry backing the scrape, for attaching your own client_golang collectors. Nil when this stack has no scrape.
func (*Telemetry) ScrapeHandler ¶ added in v1.7.0
ScrapeHandler serves this stack's scrape in Prometheus exposition, for deployments that route `/metrics` on the public server instead of a dedicated listener (`metrics.adminAddr` empty). Without a scrape it serves an empty, valid exposition, so probes still see 200.
func (*Telemetry) ScrapeURL ¶
ScrapeURL is the `host:port/path` the listener bound to, or "" when none started or the bind failed (see Telemetry.AdminErr). The port is the resolved one, so a `:0` bind is loggable.
func (*Telemetry) Shutdown ¶
Shutdown closes everything this stack owns, listener first, then the providers - whose Shutdown flushes any pending push batch. Errors are collected, not short-circuited, so one failure cannot skip the rest.
func (*Telemetry) TracerProvider ¶
func (t *Telemetry) TracerProvider() oteltrace.TracerProvider
TracerProvider / MeterProvider expose the stack's providers for code that wants its own spans or instruments. Both return the OTel no-op when that signal is off, so call sites never nil-check.