Instrument resources (DB, cache, breakers, queues)¶
Databases, caches, circuit breakers and work queues are the resources whose
USE signals — Utilization, Saturation, Errors — tell you whether a service is
healthy under load. transport-metrics ships ready-made helpers for each, so you
instrument them without hand-rolling Prometheus. All register on the same registry
that serves /metrics, and each carries a constant identifying label.
Database¶
Query RED plus connection-pool USE:
db, err := m.NewDB("orders")
if err != nil { return err }
// Query RED — labelled by a bounded query name (never a raw SQL string):
err = db.Query(ctx, "get_order", func() error {
return sqldb.QueryRowContext(ctx, q, id).Scan(&o)
})
// Pool USE — scraped from database/sql on each collect:
_ = db.RegisterPool(func() metrics.PoolStats {
s := sqldb.Stats()
return metrics.PoolStats{
MaxOpen: s.MaxOpenConnections, Open: s.OpenConnections,
InUse: s.InUse, Idle: s.Idle,
WaitCount: s.WaitCount, WaitSeconds: s.WaitDuration.Seconds(),
}
})
Metrics (const label db="orders"): db_queries_total, db_query_errors_total,
db_query_duration_seconds, db_queries_in_flight (label query); and
db_pool_{max_open,open,in_use,idle}, db_pool_wait_count_total,
db_pool_wait_seconds_total.
Cache¶
c, _ := m.NewCache("sessions")
if hit { c.Hit() } else { c.Miss() }
c.Eviction(1)
c.SetSize(cache.Len())
c.SetCapacity(cache.Cap())
Metrics (const label cache="sessions"): cache_hits_total,
cache_misses_total, cache_evictions_total, cache_size, cache_capacity. Hit
ratio is rate(cache_hits_total[5m]) / (rate(cache_hits_total[5m]) + rate(cache_misses_total[5m])).
Circuit breaker¶
cb, _ := m.NewCircuitBreaker("payments")
cb.SetState(metrics.BreakerClosed) // 0 closed, 1 half-open, 2 open
cb.Success() // or cb.Failure()
cb.Trip() // increments trips and sets state open
cb.ShortCircuit() // a request rejected while open
Metrics (const label name="payments"): circuit_breaker_state (gauge 0/½),
circuit_breaker_trips_total, circuit_breaker_short_circuits_total,
circuit_breaker_successes_total, circuit_breaker_failures_total.
Queue¶
q, _ := m.NewQueue("jobs")
q.Enqueue(); q.SetDepth(queue.Len())
// on dequeue:
q.Dequeue(); q.ObserveWait(waited)
q.ObserveProcessing(ctx, took) // exemplar-aware
Metrics (const label queue="jobs"): queue_depth, queue_enqueued_total,
queue_dequeued_total, queue_wait_seconds, queue_processing_seconds.
Options¶
Every helper (and NewOperations) takes the same HelperOption set:
| Option | Effect |
|---|---|
WithNamespace("app") |
prefix the metric names (app_cache_hits_total) |
WithBuckets(...) |
duration-histogram buckets (default prometheus.DefBuckets) |
WithConstLabels{...} |
extra constant labels, merged with the identifying label |
Multiple instances¶
Call the constructor once per resource (NewDB("orders"), NewDB("billing")) — the
identifying label distinguishes them and they share metric names. A repeated name is
a duplicate-registration error. Keep those names bounded, as always.