Table of contents
Part of nurago, a collection of independent Go packages for backend services.
import "github.com/tecnickcom/nurago/pkg/grpcutil"
The shared helpers under grpcserver and grpcclient, exported for custom interceptors and for services that use plain grpc-go.
ctx, id := grpcutil.OutgoingContextWithTraceID(ctx, grpcutil.DefaultTraceIDMetadataKey, traceid.DefaultValue)
Trace IDs in metadata
gRPC carries request-scoped values in metadata, not HTTP headers. The helpers bridge metadata and the traceid context value:
| Function | Direction |
|---|---|
TraceIDFromIncomingContext | incoming metadata to a validated ID, or the default |
OutgoingContextWithTraceID | context value to outgoing metadata, replacing any existing value |
ValidTraceIDMetadataKey | whether a key can carry a trace ID at all |
Both directions validate the ID with traceid.Valid. A value arriving from a caller is input, and an unvalidated one ends up verbatim in every log line of the request.
DefaultTraceIDMetadataKey is x-request-id. gRPC metadata keys are case-insensitive and sent in lowercase, so it interoperates with HTTP services that use X-Request-ID, and a request keeps one ID across both transports.
One error, two transports
A service exposing REST and gRPC should report the same failure the same way on both.
HTTPStatusFromCodemaps a gRPC code to the HTTP status documented for it ingoogle.rpc.Code.CodeFromHTTPStatusmaps an HTTP status returned by application logic to the closest gRPC code.ErrorCodereturns the code of any error, including wrapped status errors and context errors.
The mapping is not symmetric, because the code sets are not the same size: several gRPC codes share one HTTP status. Map from your domain errors to each transport directly when the distinction matters, and use these where an existing classification has to cross over.
RPC logging helpers
SplitFullMethod and ParseFullMethod split /package.Service/Method into service and method; the second also rejects malformed names. DumpMessage renders a protobuf message as JSON for a log entry, capped by encoded size and passed through a RedactFn.
The instrumentation contract
ServerInstrumenter and ClientInstrumenter supply the server or dial options that add metrics or tracing. A server instrumenter that also implements ServerInitializer is handed the server once every service is registered, which is how prometheusgrpc creates its zero-valued series.
They exist as separate interfaces because metrics.Client is stable within v1 and cannot gain gRPC methods. Keeping them here also keeps gRPC out of the build of every metrics backend.
Dependencies
Reaches google.golang.org/grpc, google.golang.org/protobuf, google.golang.org/genproto/googleapis/rpc, and golang.org/x/net, x/sys and x/text.
Links
- Reference documentation
- Source code
- The guide: /docs/grpc-services/
- The HTTP counterpart: httputil
- All nurago packages