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
- Variables
- func NewCounter(opts prom.CounterOpts) prom.Counter
- func NewCounterVec(opts prom.CounterOpts, labelNames []string) *prom.CounterVec
- func NewGauge(opts prom.GaugeOpts) prom.Gauge
- func NewGaugeFunc(opts prom.GaugeOpts, function func() float64) prom.GaugeFunc
- func RegisterOrReuseCounter(reg prom.Registerer, opts prom.CounterOpts) (prom.Counter, error)
- type HookObserver
- type HookObserverConfig
- type MetricProvider
- func (p *MetricProvider) CounterVec(opts metrics.CounterOpts) (metrics.CounterVec, error)
- func (p *MetricProvider) GaugeVec(opts metrics.GaugeOpts) (metrics.GaugeVec, error)
- func (p *MetricProvider) HistogramVec(opts metrics.HistogramOpts) (metrics.HistogramVec, error)
- func (p *MetricProvider) Unregister(c metrics.Collector) error
- type MetricProviderConfig
Constants ¶
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 ¶
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 ¶
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 ¶
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 ¶
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).