Skip to content

Metrics reference: every series this module exposes

Every metric name transport-metrics can put on /metrics, what emits it, its type, and its labels. Names are shown without a namespace prefix — WithNamespace / WithHTTPNamespace prepends one (myapp_db_queries_total), and the namespace applies to the metric name only, never to the labels.

Nothing here is on by default except the always-on group; every other family appears only once you call the constructor that registers it.

Always on, with no configuration

New (and therefore Register) registers these before returning.

Metric Type Labels Meaning
build_info gauge version, revision, goversion, and name when set Constant 1. Join any other series to the build that produced it.
go_* mixed The client_golang Go collector: heap, GC, goroutines, threads, GOMAXPROCS. Suppressed by WithoutRuntimeCollectors.
process_* mixed The client_golang process collector: RSS, CPU, file descriptors, start time. Suppressed by WithoutRuntimeCollectors.
promhttp_metric_handler_errors_total counter cause Errors the exposition handler hit while encoding a scrape. Registered by client_golang, not by this module, and not suppressed by WithoutRuntimeCollectors.

build_info is registered unconditionally. WithoutRuntimeCollectors drops go_* and process_* only; there is no option that removes build_info.

The Go runtime series worth knowing

The full go_* set is client_golang's, not this module's, so it tracks whatever your client_golang version exposes. These are the ones most support questions land on:

Metric Type What it tells you
go_goroutines gauge Live goroutines. A climbing value with a flat heap is a goroutine leak.
go_memstats_heap_alloc_bytes gauge Live heap bytes. The leak signal.
go_memstats_heap_inuse_bytes gauge Heap bytes in spans currently in use.
go_memstats_next_gc_bytes gauge Heap size that will trigger the next collection.
go_gc_duration_seconds summary Stop-the-world pause quantiles.
go_gc_gogc_percent gauge Effective GOGC.
go_gc_gomemlimit_bytes gauge Effective GOMEMLIMIT; math.MaxInt64 when unset.
go_sched_gomaxprocs_threads gauge Effective GOMAXPROCS.
go_threads gauge OS threads created.
go_info gauge Constant 1, labelled version with the Go toolchain version.

The process series worth knowing

Metric Type What it tells you
process_resident_memory_bytes gauge RSS as the OS sees it. Lags the heap — the runtime does not return pages immediately.
process_virtual_memory_bytes gauge Virtual size.
process_cpu_seconds_total counter User + system CPU seconds.
process_open_fds / process_max_fds gauge Open file descriptors against the limit.
process_start_time_seconds gauge Unix start time; uptime is time() - process_start_time_seconds.

Linux, Darwin and Windows each have a native implementation in client_golang. On wasip1, js and ios the collector is a no-op and these series are absent, while go_* and build_info still work.

HTTP request metrics

Registered by Metrics.HTTPMiddleware. Labels are method, route, status.

Metric Type Labels
http_requests_total counter method, route, status
http_request_duration_seconds histogram method, route, status
http_requests_in_flight gauge none
  • route is the matched route template, read from http.Request.Pattern, and under http.ServeMux it includes the method: GET /users/{id}. When no template matched — a non-stdlib router, or a middleware invoked outside a mux — the label is <other>, configurable with WithUnmatchedRouteLabel.
  • status is the response code as a string ("200", "418"). A handler that writes a body without calling WriteHeader records 200. WithStatusClass records the class instead ("4xx").
  • Buckets default to prometheus.DefBuckets (.005 .01 .025 .05 .1 .25 .5 1 2.5 5 10 seconds).
  • http_request_duration_seconds carries a trace_id exemplar when an ExemplarSource is configured — see Exemplars.

gRPC server metrics

Registered by grpc.NewServerMetrics from the metrics/grpc subpackage.

Metric Type Labels
grpc_server_handled_total counter grpc_method, grpc_code
grpc_server_handling_seconds histogram grpc_method
grpc_server_in_flight gauge none
  • grpc_method is the full method name, /pkg.Service/Method, bounded by your service definition.
  • grpc_code is status.Code(err).String()OK, NotFound, and so on. An error that is not a gRPC status becomes Unknown.
  • grpc_server_in_flight counts unary and streaming RPCs together; there is no per-method breakdown.
  • There are no client-side interceptors and no grpc_client_* metrics.

Business-logic metrics (Operations)

Registered by Metrics.NewOperations. Every series is labelled operation.

Metric Type
operations_total counter
operation_errors_total counter
operation_duration_seconds histogram
operations_in_flight gauge

operations_total counts every call including failures, so the error ratio is rate(operation_errors_total[5m]) / rate(operations_total[5m]).

NewOperations may be called only once per Metrics unless you give the second call a different WithNamespace — a second registration under the same names is a duplicate-registration error.

Database metrics

Registered by Metrics.NewDB(name). Every series carries the constant label db="<name>".

Metric Type Labels
db_queries_total counter db, query
db_query_errors_total counter db, query
db_query_duration_seconds histogram db, query
db_queries_in_flight gauge db, query

The pool gauges below appear only after DB.RegisterPool is called, and are read from your callback on every scrape, so keep the callback cheap.

Metric Type Labels
db_pool_max_open gauge db
db_pool_open gauge db
db_pool_in_use gauge db
db_pool_idle gauge db
db_pool_wait_count_total counter db
db_pool_wait_seconds_total counter db

db_pool_max_open is 0 when the pool is unlimited, so saturation queries need to guard against dividing by zero.

Cache metrics

Registered by Metrics.NewCache(name). Constant label cache="<name>", and no variable labels at all — one instrument set per cache instance.

Metric Type
cache_hits_total counter
cache_misses_total counter
cache_evictions_total counter
cache_size gauge
cache_capacity gauge

cache_size and cache_capacity are values you push with SetSize/SetCapacity — nothing reads your cache for you, so a gauge you never set stays at 0. cache_capacity of 0 means unbounded by convention. Hit ratio:

rate(cache_hits_total[5m])
  / (rate(cache_hits_total[5m]) + rate(cache_misses_total[5m]))

Circuit-breaker metrics

Registered by Metrics.NewCircuitBreaker(name). Constant label name="<name>" — note that it is name, not breaker.

Metric Type
circuit_breaker_state gauge
circuit_breaker_trips_total counter
circuit_breaker_short_circuits_total counter
circuit_breaker_successes_total counter
circuit_breaker_failures_total counter

circuit_breaker_state is 0 closed, 1 open, 2 half-open — the same numeric ordering as go/transit's resilience.State. Convert with metrics.FromResilienceState(int(state)) rather than casting; an unrecognised value maps to closed (0) rather than erroring, so a future state added upstream would silently read as healthy.

The breaker does not observe itself. Trip(), Success(), Failure() and ShortCircuit() are calls your code makes; nothing is inferred from the state gauge.

Queue metrics

Registered by Metrics.NewQueue(name). Constant label queue="<name>".

Metric Type
queue_depth gauge
queue_enqueued_total counter
queue_dequeued_total counter
queue_wait_seconds histogram
queue_processing_seconds histogram

queue_depth is set by SetDepth, not derived from the enqueue/dequeue counters, so it is only as accurate as your calls to it.

Which metrics carry exemplars

An exemplar attaches a trace id to a single histogram sample. It is recorded only where the observation path runs through Metrics.Observe, and only when an ExemplarSource is configured:

Metric Exemplar
http_request_duration_seconds yes
grpc_server_handling_seconds yes
operation_duration_seconds yes
db_query_duration_seconds yes
queue_processing_seconds yes
queue_wait_seconds noObserveWait takes no context
every counter and gauge no

Exemplars are only rendered when the scraper asks for OpenMetrics. A plain curl localhost:8080/metrics sends no Accept header, gets the Prometheus text format back, and shows no exemplars even when they are being recorded. To see them:

curl -s -H 'Accept: application/openmetrics-text; version=1.0.0' \
  localhost:8080/metrics | grep trace_id
http_request_duration_seconds_bucket{method="GET",route="GET /x",status="200",le="0.005"} 1 # {trace_id="0102030405060708090a0b0c0d0e0f10"} 2.2e-07 1.7856969705221822e+09

Why a metric you expect is missing

  • A labelled counter with no observations yet. operation_errors_total and db_query_errors_total are CounterVecs: no child series exists until a label combination is first incremented. Nothing appears until the first error. Unlabelled counters (cache_hits_total) do appear at zero.
  • The constructor was never called. Only the always-on group is automatic; the HTTP, gRPC and RED/USE families exist because you called HTTPMiddleware, NewServerMetrics, NewDB and so on.
  • The constructor returned an error you ignored. Every one of them returns (T, error), and a duplicate registration returns instead of panicking. See Failure modes.
  • The collector went onto a different registry. Metrics created with promauto or prometheus.MustRegister land on the global default registry, which this module never serves. Use WithRegistry, WithCollectors, or m.Registry().Register(...).
  • You are looking at a different Metrics. Two New calls mean two private registries and two disjoint sets of series.