metrics

package
v0.5.0 Latest Latest
Warning

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

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

Documentation

Overview

Package metrics provides a Prometheus registry, a scrape handler, an HTTP request middleware, and the building block for extensible, conflict-free metrics across the SDK and the application.

One shared registry

The model is a single registry, dependency-injected. The application builds one Metrics (which owns a *prometheus.Registry) at startup and passes that registry to every component that exposes metrics — SDK subsystems and the application's own business metrics alike. One registry means one /metrics endpoint and one place series can collide, so collisions are caught at startup rather than going silently unscraped.

m := metrics.New("myapp")        // app-wide registry + HTTP collectors
http.Handle("/metrics", m.Handler())

Each package owns its metrics

A subsystem defines its own collectors next to its code and registers them on the injected registry. It never reaches for the global default registry, so importing it has no global side effects and two subsystems never fight over registration. The outbox package is the model: outbox.NewMetrics(reg) builds servicekit_outbox_* collectors; the application just hands it m.Registry.

om := outbox.NewMetrics(m.Registry)               // SDK subsystem metrics
relay := outbox.NewRelay(log, store, pub, outbox.RelayConfig{Metrics: om})
m.Registry.MustRegister(outbox.NewBacklogCollector(store, log)) // a custom collector

Adding your own metrics

Application metrics use the same registry; distinct namespaces/subsystems keep names from colliding with the SDK's:

ordersTotal := metrics.Register(m.Registry, prometheus.NewCounterVec(
    prometheus.CounterOpts{Namespace: "myapp", Subsystem: "orders", Name: "created_total"},
    []string{"channel"}))
ordersTotal.WithLabelValues("web").Inc()

Conflict-free registration

Register is the primitive that makes this safe and ergonomic: it registers a collector and returns it, returns the already-registered equivalent instead of panicking on a duplicate (so constructing a subsystem's metrics twice — in tests, or across workers sharing a registry — is idempotent), and panics only on a genuine name clash between *different* collectors, surfacing the wiring bug at startup. A nil registry disables registration while leaving the collector's methods as safe no-ops, so a component can take an optional registry and stay metrics-agnostic.

Naming

Use Namespace + Subsystem + Name on every collector. Convention here: the SDK uses the "servicekit" namespace with a per-subsystem Subsystem (e.g. servicekit_outbox_*); the application uses its own namespace. Distinct (namespace, subsystem, name) tuples are what guarantee no conflicts on the shared registry.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Register added in v0.5.0

func Register[C prometheus.Collector](reg prometheus.Registerer, c C) C

Register registers c on reg and returns it. If an identical collector is already registered (same fully-qualified name and labels) it returns the existing one instead of panicking; if a *different* collector clashes on the name it panics, surfacing the wiring bug at startup.

This is the building block for conflict-free, extensible metrics: each package (SDK or application) defines its own collectors and registers them on the one shared registry through Register. Distinct namespaces/subsystems keep names from colliding; the register-or-get behavior makes constructing a subsystem's metrics idempotent, so building it twice against the same registry (e.g. in tests, or two workers sharing a registry) reuses the collectors rather than crashing.

A nil reg disables registration: c is returned unregistered, so its methods (Inc/Observe/…) remain safe no-ops from the scrape's perspective. This lets a component accept an optional registry and stay metrics-agnostic.

Types

type Metrics

type Metrics struct {
	Registry *prometheus.Registry
	// contains filtered or unexported fields
}

Metrics bundles a registry with the standard HTTP request collectors.

func New

func New(namespace string) *Metrics

New builds a Metrics with a fresh registry and registers Go runtime and process collectors plus HTTP request collectors.

func (*Metrics) Handler

func (m *Metrics) Handler() http.Handler

Handler returns the scrape handler for /metrics.

func (*Metrics) Middleware

func (m *Metrics) Middleware() func(http.Handler) http.Handler

Middleware records count and latency for each request. routePattern should be the matched route template (low cardinality), not the raw path.

Jump to

Keyboard shortcuts

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