Utility library for gRPC in Go — provides duplex serving (gRPC + grpc-gateway), Prometheus metrics, OpenTelemetry tracing, client identity propagation, and pre-configured dial options.
Serves both gRPC and gRPC Gateway on the same port. Supports graceful shutdown via context cancellation.
d := duplex.New(8080,
grpc.ChainUnaryInterceptor(metrics.UnaryServerInterceptor()),
)
pb.RegisterTypeServer(d.Server, impl.NewTypeServer())
if err := d.RegisterHandler(ctx, pb.RegisterTypeHandlerFromEndpoint); err != nil {
log.Panicf("Failed to register gateway endpoint: %v", err)
}
if err := d.ListenAndServe(ctx); err != nil {
log.Panicf("ListenAndServe() = %v", err)
}duplex.New accepts grpc.ServerOption, runtime.ServeMuxOption, and
grpc.DialOption (for the internal loopback connection).
Pre-configured gRPC dial options for production use:
GRPCOptions(url)— Returns target address and dial options for a URL. Handleshttp,https,bufnet, and test listener schemes.GRPCDialOptions()— Standard dial options with OTEL tracing, Prometheus client metrics, client identity propagation, and retry support.LoopbackDialOptions()— Minimal dial options for grpc-gateway loopback connections, omitting metrics/tracing to avoid double-counting.ClientOptions()— WrapsGRPCDialOptions()asgoogle.golang.org/api/option.ClientOption.
Configuration via environment variables:
| Variable | Default | Description |
|---|---|---|
ENABLE_CLIENT_HANDLING_TIME_HISTOGRAM |
true |
Enable client handling time histogram |
ENABLE_CLIENT_STREAM_RECEIVE_TIME_HISTOGRAM |
true |
Enable client stream receive histogram |
ENABLE_CLIENT_STREAM_SEND_TIME_HISTOGRAM |
true |
Enable client stream send histogram |
GRPC_CLIENT_MAX_RETRY |
0 |
Max retries (0 disables) |
UnaryServerInterceptor()/StreamServerInterceptor()— gRPC server interceptors that record Prometheus metrics withcgclientidlabels.SetupTracer(ctx)— Initializes OpenTelemetry tracing with OTLP gRPC exporter. Returns a shutdown function.RegisterListenAndServe(server, addr, enablePprof)— Starts a metrics HTTP server in the background serving/metricsand optionally/debug/pprof/.
Cloud Run may replace the traceparent header, losing span context. This
package provides stats handlers to work around this:
PreserveTraceParentHandler— Client-side handler that copies the outgoingtraceparenttooriginal-traceparent.RestoreTraceParentHandler— Server-side handler that restorestraceparentfromoriginal-traceparentif Cloud Run replaced it.
Prometheus counters for observability:
grpc_traceparent_preserved_total, grpc_traceparent_restore_attempted_total,
grpc_traceparent_restored_total.
Automatically propagates caller identity via gRPC metadata:
UnaryClientInterceptor()/StreamClientInterceptor()— Addscgclientid(service identity) andcgrequestid(unique per-call UUID) to outgoing metadata.
Client ID resolution: K_SERVICE env → CG_CLIENT_ID env → executable path.