diff --git a/go/otgrpc/client.go b/go/otgrpc/client.go index e7dbb48..bbc8178 100644 --- a/go/otgrpc/client.go +++ b/go/otgrpc/client.go @@ -63,6 +63,9 @@ func OpenTracingClientInterceptor(tracer opentracing.Tracer, optFuncs ...Option) clientSpan.LogEventWithPayload("gRPC error", err) ext.Error.Set(clientSpan, true) } + if otgrpcOpts.decorator != nil { + otgrpcOpts.decorator(clientSpan, method, req, resp, err) + } return err } } diff --git a/go/otgrpc/options.go b/go/otgrpc/options.go index 7c494d0..2b8dcec 100644 --- a/go/otgrpc/options.go +++ b/go/otgrpc/options.go @@ -1,5 +1,7 @@ package otgrpc +import "github.com/opentracing/opentracing-go" + // Option instances may be used in OpenTracing(Server|Client)Interceptor // initialization. // @@ -15,11 +17,28 @@ func LogPayloads() Option { } } +// SpanDecoratorFunc provides an (optional) mechanism for otgrpc users to add +// arbitrary tags/logs/etc to the opentracing.Span associated with client +// and/or server RPCs. +type SpanDecoratorFunc func( + span opentracing.Span, + method string, + req, resp interface{}, + grpcError error) + +// SpanDecorator binds a function that decorates gRPC Spans. +func SpanDecorator(decorator SpanDecoratorFunc) Option { + return func(o *options) { + o.decorator = decorator + } +} + // The internal-only options struct. Obviously overkill at the moment; but will // scale well as production use dictates other configuration and tuning // parameters. type options struct { logPayloads bool + decorator SpanDecoratorFunc } // newOptions returns the default options. diff --git a/go/otgrpc/package.go b/go/otgrpc/package.go index 5c0431c..dd4ea45 100644 --- a/go/otgrpc/package.go +++ b/go/otgrpc/package.go @@ -1,4 +1,4 @@ -// otgrpc provides OpenTracing support for any gRPC client or server in Go. +// Package otgrpc provides OpenTracing support for any gRPC client or server. // // See [go/otgrpc/README.md](https://github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/README.md) package otgrpc diff --git a/go/otgrpc/server.go b/go/otgrpc/server.go index 8b4b98f..0c3a3d7 100644 --- a/go/otgrpc/server.go +++ b/go/otgrpc/server.go @@ -42,25 +42,28 @@ func OpenTracingServerInterceptor(tracer opentracing.Tracer, optFuncs ...Option) // don't know where to put such an error and must rely on Tracer // implementations to do something appropriate for the time being. } - span := tracer.StartSpan( + serverSpan := tracer.StartSpan( info.FullMethod, ext.RPCServerOption(spanContext), gRPCComponentTag, ) - defer span.Finish() + defer serverSpan.Finish() - ctx = opentracing.ContextWithSpan(ctx, span) + ctx = opentracing.ContextWithSpan(ctx, serverSpan) if otgrpcOpts.logPayloads { - span.LogEventWithPayload("gRPC request", req) + serverSpan.LogEventWithPayload("gRPC request", req) } resp, err = handler(ctx, req) if err == nil { if otgrpcOpts.logPayloads { - span.LogEventWithPayload("gRPC response", resp) + serverSpan.LogEventWithPayload("gRPC response", resp) } } else { - ext.Error.Set(span, true) - span.LogEventWithPayload("gRPC error", err) + ext.Error.Set(serverSpan, true) + serverSpan.LogEventWithPayload("gRPC error", err) + } + if otgrpcOpts.decorator != nil { + otgrpcOpts.decorator(serverSpan, info.FullMethod, req, resp, err) } return resp, err }