Skip to content

Instrument gRPC servers

The opt-in metrics/grpc subpackage records RED metrics per RPC via gRPC server interceptors, on the same registry that serves /metrics. Importing it is the only thing that pulls google.golang.org/grpc into your build — the core metrics package never does.

Import it aliased, to avoid the clash with the google.golang.org/grpc package:

import (
    ggrpc "google.golang.org/grpc"
    metrics "gitlab.com/phpboyscout/go/transport-metrics"
    mgrpc "gitlab.com/phpboyscout/go/transport-metrics/grpc"
)

Wire the interceptors

m, _ := metrics.New()

sm, err := mgrpc.NewServerMetrics(m)
if err != nil {
    return err
}

srv := ggrpc.NewServer(
    ggrpc.ChainUnaryInterceptor(sm.UnaryInterceptor()),
    ggrpc.ChainStreamInterceptor(sm.StreamInterceptor()),
)

Expose /metrics as usual (m.MountOn(mux) on your HTTP server, or the standalone server) and the gRPC metrics appear there alongside everything else.

The metrics produced

Metric Type Labels
grpc_server_handled_total counter grpc_method, grpc_code
grpc_server_handling_seconds histogram grpc_method
grpc_server_in_flight gauge

grpc_method is the full method name (/pkg.Service/Method), bounded by your service definition. grpc_code is the gRPC status code (OK, NotFound, …), derived from the handler's returned error.

Options

Option Effect
WithNamespace("myapp") prefix the metric names
WithDurationBuckets(...) override the handling-duration buckets
WithConstLabels{...} stamp constant labels (e.g. version)

Exemplars

If m was built with an exemplar source, the grpc_server_handling_seconds observations carry the trace id — exactly as the HTTP instrumentation does — so a slow RPC on a dashboard links to its trace.