telemetry

package
v1.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 7, 2026 License: MIT Imports: 28 Imported by: 0

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

View Source
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.

View Source
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

func Init(ctx context.Context, c Config) (*Telemetry, error)

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

func (t *Telemetry) AdminErr() <-chan error

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

func (t *Telemetry) ScrapeHandler() http.Handler

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

func (t *Telemetry) ScrapeURL() string

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

func (t *Telemetry) Shutdown(ctx context.Context) error

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL