prometheus

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: 14 Imported by: 0

Documentation

Overview

Package prometheus provides a Prometheus backend for the provider-neutral metrics abstraction defined in kernel/observability/metrics, plus a direct cell.LifecycleHookObserver implementation for assembly hook metrics.

Use MetricProvider to register counters/histograms that flow through runtime/observability/metrics (HTTP collector) and kernel/outbox (relay collector). Use HookObserver for lifecycle hook metrics on an assembly.

Exposed surface:

  • NewMetricProvider — registers instruments on a *prom.Registry
  • NewHookObserver — direct cell lifecycle observer (sync per-event)
  • RegisterOrReuseCounter — idempotent register-or-reuse helper for bare counters
  • NewCounter — public passthrough wrapper for adapters outside the prometheus subtree (e.g. adapters/vault) blocked by Go internal/ closure
  • NewGauge — public passthrough wrapper (same rationale as NewCounter)
  • NewGaugeFunc — public passthrough wrapper (same rationale as NewCounter)
  • NewCounterVec — vault-only LABELED carve-out, NOT a sanctioned path: bypasses metrics.Provider label/cardinality governance; debt pending removal (vault loginOutcome → metrics.Provider.CounterVec, issue #885). New labeled metrics MUST use metrics.Provider — do not add callers.

ref: github.com/prometheus/client_golang — Registry, CounterVec, HistogramVec. Adopted: isolated Registry per provider, promhttp exposition owned by caller.

Index

Constants

View Source
const (
	// ErrAdapterPromConfig indicates an invalid Prometheus configuration.
	ErrAdapterPromConfig errcode.Code = "ERR_ADAPTER_PROM_CONFIG"

	// ErrAdapterPromRegister indicates a failure to register Prometheus metrics.
	ErrAdapterPromRegister errcode.Code = "ERR_ADAPTER_PROM_REGISTER"
)

Prometheus adapter error codes.

Variables

View Source
var DefaultHookDurationBuckets = []float64{
	.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10, 30,
}

DefaultHookDurationBuckets covers the range expected for cell lifecycle hooks: from sub-millisecond in-process init up to the 30s default HookTimeout so timeout-adjacent latency remains observable.

Functions

func NewCounter

func NewCounter(opts prom.CounterOpts) prom.Counter

NewCounter is the public adapter-level entry point for creating a bare prom.Counter without registering it. Adapter packages outside the prometheus subtree (e.g. adapters/vault) that cannot import adapters/prometheus/internal/promwrap directly due to Go internal/ closure must use this function instead of calling prom.NewCounter directly.

Does NOT register the collector with any Registerer; callers must Register it themselves to expose it in /metrics.

Callers that also need to register the counter should use RegisterOrReuseCounter.

func NewCounterVec

func NewCounterVec(opts prom.CounterOpts, labelNames []string) *prom.CounterVec

NewCounterVec is a vault-only legacy carve-out, NOT a general labeled-metric entry point — see the file-level doc and issue #885. It returns an unregistered *prom.CounterVec for adapters/vault's loginOutcome, which still uses the register-at-composition-root model and so cannot route through metrics.Provider.CounterVec yet. It deliberately bypasses the Provider's label/cardinality governance; new labeled metrics MUST use metrics.Provider instead. Callers must Register the returned collector themselves.

Pending removal: vault migrates loginOutcome to metrics.Provider.CounterVec (issue #885), after which this function is deleted.

func NewGauge

func NewGauge(opts prom.GaugeOpts) prom.Gauge

NewGauge is the public adapter-level entry point for creating a bare prom.Gauge without registering it. Adapter packages outside the prometheus subtree (e.g. adapters/vault) that cannot import adapters/prometheus/internal/promwrap directly due to Go internal/ closure must use this function instead of calling prom.NewGauge directly.

Does NOT register the collector with any Registerer; callers must Register it themselves to expose it in /metrics.

func NewGaugeFunc

func NewGaugeFunc(opts prom.GaugeOpts, function func() float64) prom.GaugeFunc

NewGaugeFunc is the public adapter-level entry point for creating a callback-style prom.GaugeFunc without registering it. Adapter packages outside the prometheus subtree (e.g. adapters/vault) that cannot import adapters/prometheus/internal/promwrap directly due to Go internal/ closure must use this function instead of calling prom.NewGaugeFunc directly.

Does NOT register the collector with any Registerer; callers must Register it themselves to expose it in /metrics.

func RegisterOrReuseCounter

func RegisterOrReuseCounter(reg prom.Registerer, opts prom.CounterOpts) (prom.Counter, error)

RegisterOrReuseCounter registers a new counter on the given Registerer with the given opts. If the counter is already registered (AlreadyRegisteredError), it reuses the existing collector. Non-AlreadyRegisteredError failures are returned unwrapped. If the registered collector is not a prom.Counter, an error is returned wrapping the original AlreadyRegisteredError with the prefix "existing collector is not a Counter:".

This is the only sanctioned entry point for creating a bare prom.Counter outside the metrics.Provider abstraction — adapter-internal idempotent register-or-reuse pattern, originally lifted from cmd/corebundle.

Note: as of #1413 there is no production caller — configcore's stale-cipher counter (its sole consumer) migrated to the kernel MetricsProvider. The export is retained as the sanctioned bare-counter helper for future adapter-internal use; its caller-allowlist (METRICS-ADAPTERPROM-CALLER-ALLOWLIST-01) is empty, so a new caller must add its file there with justification.

ref: kubernetes component-base/metrics/counter.go (idempotent registration pattern)

Types

type HookObserver

type HookObserver struct {
	// contains filtered or unexported fields
}

HookObserver implements cell.LifecycleHookObserver by emitting Prometheus metrics on every hook event.

Metrics:

{namespace}_cell_hook_total{cell_id,hook,outcome}         — counter
{namespace}_cell_hook_duration_seconds{cell_id,hook}      — histogram

Cardinality budget: (number of cells) × 4 hooks × 4 outcomes = small. Assumes static cell registration at assembly build time — dynamic or per-tenant cells (e.g. a cell-per-customer topology) would require cardinality budgeting and likely a label aggregation strategy. Duration histogram intentionally omits `outcome` label to keep bucket count bounded — failures and successes share the same time distribution bucket set.

ref: uber-go/fx fxevent/logger.go@master — single-method observer pattern. ref: adapters/prometheus/metric_provider.go — shares the CounterVec / HistogramVec style this observer predates; any new adapter-level Prometheus metric should go through MetricProvider instead.

func NewHookObserver

func NewHookObserver(cfg HookObserverConfig) (*HookObserver, error)

NewHookObserver constructs a HookObserver and registers its metrics on cfg.Registry. Returns an error if registration fails (e.g., duplicate registration on the same registry).

func (*HookObserver) OnHookEvent

func (o *HookObserver) OnHookEvent(e cell.HookEvent)

OnHookEvent records the event. Safe for concurrent use (Prometheus vec types are goroutine-safe).

cell_id is routed through promCellLabel — the single typed-function funnel that enforces metadata.CellIDPattern. Upstream invariants (schemas/cell.schema.json + FMT-C1) already guarantee every event in flight has a valid cell id; promCellLabel is the A-class unreachable defense backstop required by PROM-CELL-LABEL-FUNNEL-01.

type HookObserverConfig

type HookObserverConfig struct {
	// Registry is the Prometheus registry to use. Must be non-nil; the caller
	// owns the lifecycle so multiple observers (hook + HTTP + adapter pools)
	// can share one exposition endpoint.
	Registry *prom.Registry

	// Namespace prefixes metric names. Default: "gocell".
	Namespace string

	// DurationBuckets configures the histogram bucket boundaries in seconds.
	// Default: DefaultHookDurationBuckets.
	DurationBuckets []float64
}

HookObserverConfig configures the Prometheus implementation of cell.LifecycleHookObserver.

type MetricProvider

type MetricProvider struct {
	// contains filtered or unexported fields
}

MetricProvider implements metrics.Provider by wrapping a Prometheus *prom.Registry. Every CounterVec/HistogramVec returned is registered on the configured registry; duplicate registration surfaces as an ErrAdapterPromRegister error, not a panic.

Unregister is safe for concurrent use: it uses a RWMutex to protect the internal registry-to-collector map so rollback from NewProviderRelayCollector can be called from any goroutine.

func NewMetricProvider

func NewMetricProvider(cfg MetricProviderConfig) (*MetricProvider, error)

NewMetricProvider constructs a MetricProvider.

Errors:

  • ErrAdapterPromConfig if Registry is nil (required).

func (*MetricProvider) CounterVec

func (p *MetricProvider) CounterVec(opts metrics.CounterOpts) (metrics.CounterVec, error)

CounterVec registers and returns a CounterVec bound to the provider's registry. If the same metric name has already been registered (e.g. when multiple cells share a single MetricProvider), the existing collector is returned — matching the standard prometheus AlreadyRegisteredError pattern. Any other registration error surfaces as ErrAdapterPromRegister.

CounterVec / HistogramVec / GaugeVec share intentional shape; the registerOrReuse generic factors the common path, so further collapse would obscure the per-metric-type construction details.

func (*MetricProvider) GaugeVec

func (p *MetricProvider) GaugeVec(opts metrics.GaugeOpts) (metrics.GaugeVec, error)

GaugeVec registers and returns a GaugeVec bound to the provider's registry. Gauges can be Set/Inc/Dec/Add-ed and represent point-in-time values (queue depth, active workers). If the same metric name has already been registered, the existing collector is returned — same AlreadyRegisteredError pattern as CounterVec.

func (*MetricProvider) HistogramVec

func (p *MetricProvider) HistogramVec(opts metrics.HistogramOpts) (metrics.HistogramVec, error)

HistogramVec registers and returns a HistogramVec bound to the provider's registry. Empty Buckets uses Prometheus default (DefBuckets). If the same metric name has already been registered, the existing collector is returned (same AlreadyRegisteredError pattern as CounterVec). See CounterVec godoc for the shared-shape rationale; dupl does not flag HistogramVec because its Buckets field differentiates it from the Counter/Gauge shapes.

func (*MetricProvider) Unregister

func (p *MetricProvider) Unregister(c metrics.Collector) error

Unregister removes a previously registered collector from the Prometheus registry. It is idempotent — passing an unknown Collector (or one already unregistered) returns nil. Concurrent calls are safe.

ref: prometheus/client_golang prometheus/registry.go — Registry.Unregister returns bool; we convert "not found" to nil so callers treat it as a no-op.

type MetricProviderConfig

type MetricProviderConfig struct {
	// Registry is the destination for all CounterVec/HistogramVec. Required.
	Registry *prom.Registry

	// Namespace prefixes every metric name (e.g. "gocell" → "gocell_foo_total").
	// Empty namespace emits bare names; useful when the surrounding exposition
	// already groups by job.
	Namespace string
}

MetricProviderConfig configures a Prometheus-backed metrics.Provider.

ref: prometheus/client_golang prometheus/registry.go@main — NewRegistry is preferred over the global default so multiple providers can coexist in one process (e.g. one per test, or one per sub-system exposition).

Directories

Path Synopsis
internal
promwrap
Package promwrap is the sole sanctioned funnel for constructing Prometheus client_golang instruments.
Package promwrap is the sole sanctioned funnel for constructing Prometheus client_golang instruments.

Jump to

Keyboard shortcuts

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