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 |
routeis the matched route template, read fromhttp.Request.Pattern, and underhttp.ServeMuxit 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 withWithUnmatchedRouteLabel.statusis the response code as a string ("200","418"). A handler that writes a body without callingWriteHeaderrecords200.WithStatusClassrecords the class instead ("4xx").- Buckets default to
prometheus.DefBuckets(.005 .01 .025 .05 .1 .25 .5 1 2.5 5 10seconds). http_request_duration_secondscarries atrace_idexemplar when anExemplarSourceis 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_methodis the full method name,/pkg.Service/Method, bounded by your service definition.grpc_codeisstatus.Code(err).String()—OK,NotFound, and so on. An error that is not a gRPC status becomesUnknown.grpc_server_in_flightcounts 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:
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 |
no — ObserveWait 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_totalanddb_query_errors_totalareCounterVecs: 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,NewDBand 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
promautoorprometheus.MustRegisterland on the global default registry, which this module never serves. UseWithRegistry,WithCollectors, orm.Registry().Register(...). - You are looking at a different
Metrics. TwoNewcalls mean two private registries and two disjoint sets of series.
Related¶
- Options reference — the constructors and options that register these.
- Failure modes — the errors, warnings and panics.
- Cardinality safety — why the label sets are shaped the way they are.