metrics

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 7, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package metrics defines a provider-neutral metrics abstraction used by kernel modules that emit counters and histograms without importing any specific backend (Prometheus, OTel, …). Concrete providers live in adapters/; runtime/ modules pick one and inject it via configuration.

ref: opentelemetry-go metric/meter.go@main — API/SDK split pattern. ref: prometheus/client_golang prometheus/counter.go@main CounterVec.With() — pre-declared label names bound at record time. GoCell uses the Prom shape (LabelNames at registration, Labels map at record) over OTel's variadic attribute.KeyValue because a map makes callers name their dimensions and makes label-set drift a detectable error rather than a silent mismatch.

Counter/Histogram/Gauge 方法都接受 context.Context 首参,对齐 OTel 原生 ctx-bearing 形态:OTel adapter 把 ctx 转发给底层 instrument 以支持 exemplar / baggage 关联(需传请求级 ctx,含 active span 才有意义);Prometheus adapter 不 消费 ctx。约定两条:(1) 实现禁止因 ctx 已取消/超时而跳过记录——指标发射是 best-effort,ctx 取消不得导致数据丢失;(2) 无请求 ctx 的后台路径(如 hook dispatcher worker)显式传 context.Background() 并就近注释说明。

Index

Constants

This section is empty.

Variables

View Source
var ErrLabelMismatch = errcode.New(errcode.KindInvalid, errcode.ErrMetricsLabelMismatch,
	"metrics: label keys do not match registered LabelNames")

ErrLabelMismatch is returned / panic-wrapped by ValidateLabels / MustValidateLabels when the supplied Labels do not exactly cover the registered LabelNames. Callers can errors.Is against this sentinel when converting label-validation errors into structured diagnostics.

View Source
var ErrLabelValueIllegal = errcode.New(errcode.KindInvalid, errcode.ErrMetricsLabelValueIllegal,
	"metrics: label value contains reserved separator")

ErrLabelValueIllegal is returned when a label value contains a separator reserved by the OTel-provider cache key (`|` or `=`). A collision here causes silently-misattributed data points — we prefer a panic at registration time over a wrong-but-present time-series in production.

Functions

func MustValidateLabels

func MustValidateLabels(expected []string, got Labels)

MustValidateLabels panics with a wrapped ErrLabelMismatch when labels do not match. Adapter With() implementations call this as the first line so a programmer bug surfaces immediately with a precise message. Uses errcode.Wrap (not errcode.Assertion) so consumers can errors.Is(panic, metrics.ErrLabelMismatch) through the *errcode.Error.Cause chain.

func ValidateLabels

func ValidateLabels(expected []string, got Labels) error

ValidateLabels returns a descriptive error when labels do not exactly cover expected. It compares as sets: any missing, extra, or wrong key is an error. Both nil or empty inputs are considered a match. Values containing characters from labelSeparators (`|` or `=`) are rejected because the OTel adapter's per-label-set cache keys them positionally; a value with a separator would collide silently.

Types

type Collector

type Collector interface {
	// Registered is a compile-time type-membership marker, not a runtime
	// state probe. It always returns true for vecs returned by a Provider;
	// after Unregister, implementations may still return true because the
	// collector value itself remains valid — the change is only in the
	// Provider's registry state, not the vec's identity.
	//
	// All concrete vec types (prom, otel, nop, test spy) implement this
	// method; external code must not implement Collector directly.
	Registered() bool
}

Collector is a handle to a registered metric family (counter, histogram, or gauge vec). It is returned by CounterVec/HistogramVec/GaugeVec and accepted by Unregister.

Callers obtain Collector values only via Provider.CounterVec and Provider.HistogramVec; passing other values to Unregister is undefined behavior (implementations may silently no-op or return an error).

CounterVec, HistogramVec, and GaugeVec all embed Collector so that the return values of CounterVec/HistogramVec/GaugeVec can be passed directly to Unregister without explicit type assertions.

ref: prometheus/client_golang prometheus/collector.go — Collector is the registration unit. GoCell's Collector is a thinner typed handle that keeps kernel code free of Prometheus imports.

type Counter

type Counter interface {
	Inc(ctx context.Context)
	Add(ctx context.Context, delta float64)
}

Counter is a monotonically increasing counter, pre-bound to a label set.

type CounterOpts

type CounterOpts struct {
	Name       string
	Help       string
	LabelNames []string // Order-sensitive; used by adapters to compose the underlying vec.
}

CounterOpts declares a counter metric family.

type CounterVec

type CounterVec interface {
	Collector
	With(Labels) Counter
}

CounterVec returns a pre-bound Counter given a label set. Implementations panic (via MustValidateLabels) when Labels does not exactly match the LabelNames set at registration.

CounterVec embeds Collector so that callers can pass it directly to Provider.Unregister without an explicit type cast.

type Gauge

type Gauge interface {
	Set(ctx context.Context, value float64)
	Inc(ctx context.Context)
	Dec(ctx context.Context)
	Add(ctx context.Context, delta float64)
}

Gauge is an arbitrary-valued instrument that can move up or down, pre-bound to a label set. Use Set for point-in-time snapshots (queue depth, active workers); Inc/Dec/Add for delta updates.

Sub is deliberately omitted: Add(-delta) expresses the same semantics and keeps the method set symmetric with Counter.

ref: prometheus/client_golang prometheus/gauge.go — Gauge interface.

type GaugeOpts

type GaugeOpts struct {
	Name       string
	Help       string
	LabelNames []string // Order-sensitive; used by adapters to compose the underlying vec.
}

GaugeOpts declares a gauge metric family. Shape mirrors CounterOpts — Name + Help + LabelNames. No bucket field (gauges are not aggregated histograms).

High-cardinality warning: every unique label tuple creates a separate time series held in the Provider's registry; for dimensions with unbounded value spaces (request id, user id), prefer pre-currying with fixed dimensions or use a different metric type.

type GaugeVec

type GaugeVec interface {
	Collector
	With(Labels) Gauge
}

GaugeVec returns a pre-bound Gauge given a label set. Implementations panic (via MustValidateLabels) when Labels does not exactly match the LabelNames set at registration.

GaugeVec embeds Collector so that callers can pass it directly to Provider.Unregister without an explicit type cast.

type Histogram

type Histogram interface {
	Observe(ctx context.Context, value float64)
}

Histogram records observations into predeclared buckets, pre-bound to a label set.

type HistogramOpts

type HistogramOpts struct {
	Name       string
	Help       string
	LabelNames []string
	// Buckets lists upper bounds in seconds (or whatever unit the histogram
	// records). Empty slice means "use adapter default". Callers should
	// supply explicit buckets for any metric that leaves kernel, to keep
	// cardinality predictable across backends.
	Buckets []float64
}

HistogramOpts declares a histogram metric family.

type HistogramVec

type HistogramVec interface {
	Collector
	With(Labels) Histogram
}

HistogramVec returns a pre-bound Histogram given a label set.

HistogramVec embeds Collector so that callers can pass it directly to Provider.Unregister without an explicit type cast.

type Labels

type Labels map[string]string

Labels carries label values at record time. Keys MUST exactly match the LabelNames declared at registration. With() panics on mismatch because label drift is a programmer bug, not a runtime condition, and a silent mismatch would produce misattributed or dropped data points that are extremely hard to debug in production.

type NopProvider

type NopProvider struct{}

NopProvider is a no-op Provider used when no metrics backend is injected. It validates label sets (so label-drift bugs surface in test) but records nothing.

ref: opentelemetry-go metric/noop/noop.go@main — null-object pattern. GoCell's Nop still enforces label validation so a misbehaving caller is caught in unit tests whose wire has not yet been extended with a real Provider, preventing silent drift into production.

func (NopProvider) CounterVec

func (NopProvider) CounterVec(opts CounterOpts) (CounterVec, error)

CounterVec returns a no-op CounterVec that still enforces label correctness at With() time.

func (NopProvider) GaugeVec

func (NopProvider) GaugeVec(opts GaugeOpts) (GaugeVec, error)

GaugeVec returns a no-op GaugeVec that still enforces label correctness at With() time.

func (NopProvider) HistogramVec

func (NopProvider) HistogramVec(opts HistogramOpts) (HistogramVec, error)

HistogramVec returns a no-op HistogramVec that still enforces label correctness at With() time.

func (NopProvider) Unregister

func (NopProvider) Unregister(_ Collector) error

Unregister is a no-op; the NopProvider does not maintain a registry. Returns nil (idempotent, as per the Unregister contract).

type Provider

type Provider interface {
	CounterVec(opts CounterOpts) (CounterVec, error)
	HistogramVec(opts HistogramOpts) (HistogramVec, error)
	// GaugeVec registers a gauge metric family. Gauges are arbitrary-valued
	// instruments that can move up or down (Set / Inc / Dec / Add). Typical
	// uses: queue depth, active workers, in-flight requests — point-in-time
	// snapshots where Counter monotonicity is unsuitable.
	//
	// ref: prometheus/client_golang prometheus/gauge.go — Gauge interface
	// methods (Set / Inc / Dec / Add) adopted; Sub omitted (use Add(-delta));
	// SetToCurrentTime omitted (no business need; introduces implicit clock
	// dependency at kernel layer).
	GaugeVec(opts GaugeOpts) (GaugeVec, error)
	// Unregister removes a previously registered collector from the provider's
	// registry. It is safe for concurrent use and idempotent — unregistering a
	// collector that was never registered (or already unregistered) returns nil
	// without error.
	//
	// Implementations must maintain the invariant that a collector successfully
	// Unregistered can be re-registered via CounterVec/HistogramVec/GaugeVec
	// under the same name without conflict.
	//
	// ref: prometheus/client_golang Registry.Unregister — bool return simplified
	// to error for GoCell consistency (nil = success or not-found; non-nil =
	// hard failure).
	Unregister(c Collector) error
}

Provider registers metric instruments. Implementations are provided by adapters/ (prometheus, otel). Kernel code accepts a Provider interface value; at wire time (runtime/bootstrap, cmd/*), a concrete backend is chosen and passed through.

Registration is failable (duplicate names, invalid options) so both factory methods return (vec, error). Callers are expected to register at start-up and treat errors as fatal.

Directories

Path Synopsis
Package metricstest provides the cross-implementation conformance harness for the kernel metrics no-skip-on-cancel contract.
Package metricstest provides the cross-implementation conformance harness for the kernel metrics no-skip-on-cancel contract.

Jump to

Keyboard shortcuts

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