Skip to content

Commit

Permalink
otelgrpc: Add SpanStartOptions (#3768)
Browse files Browse the repository at this point in the history
  • Loading branch information
dubonzi committed Aug 11, 2023
1 parent e439286 commit 2ccb63e
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Add the new `go.opentelemetry.io/contrib/instrgen` package to provide auto-generated source code instrumentation. (#3068, #3108)
- The `go.opentelemetry.io/contrib/exporters/autoexport` package to provide configuration of trace exporters with useful defaults and envar support. (#2753, #4100, #4129, #4132, #4134)
- `WithRouteTag` in `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp` adds HTTP route attribute to metrics. (#615)
- Add `WithSpanOptions` option in `go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc`. (#3768)

### Fixed

Expand Down
21 changes: 17 additions & 4 deletions instrumentation/google.golang.org/grpc/otelgrpc/config.go
Expand Up @@ -37,10 +37,11 @@ type Filter func(*InterceptorInfo) bool

// config is a group of options for this instrumentation.
type config struct {
Filter Filter
Propagators propagation.TextMapPropagator
TracerProvider trace.TracerProvider
MeterProvider metric.MeterProvider
Filter Filter
Propagators propagation.TextMapPropagator
TracerProvider trace.TracerProvider
MeterProvider metric.MeterProvider
SpanStartOptions []trace.SpanStartOption

ReceivedEvent bool
SentEvent bool
Expand Down Expand Up @@ -169,3 +170,15 @@ func (m messageEventsProviderOption) apply(c *config) {
func WithMessageEvents(events ...Event) Option {
return messageEventsProviderOption{events: events}
}

type spanStartOption struct{ opts []trace.SpanStartOption }

func (o spanStartOption) apply(c *config) {
c.SpanStartOptions = append(c.SpanStartOptions, o.opts...)
}

// WithSpanOptions configures an additional set of
// trace.SpanOptions, which are applied to each new span.
func WithSpanOptions(opts ...trace.SpanStartOption) Option {
return spanStartOption{opts}
}
48 changes: 34 additions & 14 deletions instrumentation/google.golang.org/grpc/otelgrpc/interceptor.go
Expand Up @@ -84,12 +84,17 @@ func UnaryClientInterceptor(opts ...Option) grpc.UnaryClientInterceptor {
}

name, attr := spanInfo(method, cc.Target())
var span trace.Span
ctx, span = tracer.Start(

startOpts := append([]trace.SpanStartOption{
trace.WithSpanKind(trace.SpanKindClient),
trace.WithAttributes(attr...)},
cfg.SpanStartOptions...,
)

ctx, span := tracer.Start(
ctx,
name,
trace.WithSpanKind(trace.SpanKindClient),
trace.WithAttributes(attr...),
startOpts...,
)
defer span.End()

Expand Down Expand Up @@ -274,12 +279,17 @@ func StreamClientInterceptor(opts ...Option) grpc.StreamClientInterceptor {
}

name, attr := spanInfo(method, cc.Target())
var span trace.Span
ctx, span = tracer.Start(

startOpts := append([]trace.SpanStartOption{
trace.WithSpanKind(trace.SpanKindClient),
trace.WithAttributes(attr...)},
cfg.SpanStartOptions...,
)

ctx, span := tracer.Start(
ctx,
name,
trace.WithSpanKind(trace.SpanKindClient),
trace.WithAttributes(attr...),
startOpts...,
)

ctx = inject(ctx, cfg.Propagators)
Expand Down Expand Up @@ -336,13 +346,18 @@ func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor {
}

ctx = extract(ctx, cfg.Propagators)

name, attr := spanInfo(info.FullMethod, peerFromCtx(ctx))

startOpts := append([]trace.SpanStartOption{
trace.WithSpanKind(trace.SpanKindServer),
trace.WithAttributes(attr...)},
cfg.SpanStartOptions...,
)

ctx, span := tracer.Start(
trace.ContextWithRemoteSpanContext(ctx, trace.SpanContextFromContext(ctx)),
name,
trace.WithSpanKind(trace.SpanKindServer),
trace.WithAttributes(attr...),
startOpts...,
)
defer span.End()

Expand Down Expand Up @@ -454,13 +469,18 @@ func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor {
}

ctx = extract(ctx, cfg.Propagators)

name, attr := spanInfo(info.FullMethod, peerFromCtx(ctx))

startOpts := append([]trace.SpanStartOption{
trace.WithSpanKind(trace.SpanKindServer),
trace.WithAttributes(attr...)},
cfg.SpanStartOptions...,
)

ctx, span := tracer.Start(
trace.ContextWithRemoteSpanContext(ctx, trace.SpanContextFromContext(ctx)),
name,
trace.WithSpanKind(trace.SpanKindServer),
trace.WithAttributes(attr...),
startOpts...,
)
defer span.End()

Expand Down
Expand Up @@ -8,6 +8,7 @@ require (
go.opentelemetry.io/otel v1.16.0
go.opentelemetry.io/otel/sdk v1.16.0
go.opentelemetry.io/otel/sdk/metric v0.39.0
go.opentelemetry.io/otel/trace v1.16.0
go.uber.org/goleak v1.2.1
google.golang.org/grpc v1.57.0
)
Expand All @@ -24,7 +25,6 @@ require (
github.com/kr/text v0.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
go.opentelemetry.io/otel/metric v1.16.0 // indirect
go.opentelemetry.io/otel/trace v1.16.0 // indirect
golang.org/x/net v0.14.0 // indirect
golang.org/x/oauth2 v0.7.0 // indirect
golang.org/x/sys v0.11.0 // indirect
Expand Down
Expand Up @@ -29,6 +29,7 @@ import (
"go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/sdk/trace/tracetest"
semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
oteltrace "go.opentelemetry.io/otel/trace"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -91,6 +92,7 @@ func TestUnaryClientInterceptor(t *testing.T) {
unaryInterceptor := otelgrpc.UnaryClientInterceptor(
otelgrpc.WithTracerProvider(tp),
otelgrpc.WithMessageEvents(otelgrpc.ReceivedEvents, otelgrpc.SentEvents),
otelgrpc.WithSpanOptions(oteltrace.WithAttributes(attribute.Bool("custom", true))),
)
unaryInterceptorOnlySentEvents := otelgrpc.UnaryClientInterceptor(
otelgrpc.WithTracerProvider(tp),
Expand Down Expand Up @@ -128,6 +130,7 @@ func TestUnaryClientInterceptor(t *testing.T) {
otelgrpc.GRPCStatusCodeKey.Int64(0),
semconv.NetPeerName("fake"),
semconv.NetPeerPort(8906),
attribute.Bool("custom", true),
},
eventsAttr: []map[attribute.Key]attribute.Value{
{
Expand All @@ -151,6 +154,7 @@ func TestUnaryClientInterceptor(t *testing.T) {
otelgrpc.GRPCStatusCodeKey.Int64(0),
semconv.NetPeerName("fake"),
semconv.NetPeerPort(8906),
attribute.Bool("custom", true),
},
eventsAttr: []map[attribute.Key]attribute.Value{
{
Expand Down Expand Up @@ -226,6 +230,7 @@ func TestUnaryClientInterceptor(t *testing.T) {
otelgrpc.GRPCStatusCodeKey.Int64(int64(grpc_codes.OK)),
semconv.NetPeerName("fake"),
semconv.NetPeerPort(8906),
attribute.Bool("custom", true),
},
eventsAttr: []map[attribute.Key]attribute.Value{
{
Expand All @@ -250,6 +255,7 @@ func TestUnaryClientInterceptor(t *testing.T) {
otelgrpc.GRPCStatusCodeKey.Int64(int64(grpc_codes.Internal)),
semconv.NetPeerName("fake"),
semconv.NetPeerPort(8906),
attribute.Bool("custom", true),
},
eventsAttr: []map[attribute.Key]attribute.Value{
{
Expand All @@ -272,6 +278,7 @@ func TestUnaryClientInterceptor(t *testing.T) {
otelgrpc.GRPCStatusCodeKey.Int64(0),
semconv.NetPeerName("fake"),
semconv.NetPeerPort(8906),
attribute.Bool("custom", true),
},
eventsAttr: []map[attribute.Key]attribute.Value{
{
Expand All @@ -295,6 +302,7 @@ func TestUnaryClientInterceptor(t *testing.T) {
semconv.RPCMethod("method"),
semconv.NetPeerName("fake"),
semconv.NetPeerPort(8906),
attribute.Bool("custom", true),
},
eventsAttr: []map[attribute.Key]attribute.Value{
{
Expand Down Expand Up @@ -389,6 +397,7 @@ func createInterceptedStreamClient(t *testing.T, method string, opts clientStrea
tp := trace.NewTracerProvider(trace.WithSpanProcessor(sr))
interceptorOpts := []otelgrpc.Option{
otelgrpc.WithTracerProvider(tp),
otelgrpc.WithSpanOptions(oteltrace.WithAttributes(attribute.Bool("custom", true))),
}
if len(opts.Events) > 0 {
interceptorOpts = append(interceptorOpts, otelgrpc.WithMessageEvents(opts.Events...))
Expand Down Expand Up @@ -454,6 +463,7 @@ func TestStreamClientInterceptorOnBIDIStream(t *testing.T) {
semconv.RPCMethod("bar"),
semconv.NetPeerName("fake"),
semconv.NetPeerPort(8906),
attribute.Bool("custom", true),
}
assert.ElementsMatch(t, expectedAttr, span.Attributes())

Expand Down Expand Up @@ -593,6 +603,7 @@ func TestStreamClientInterceptorOnUnidirectionalClientServerStream(t *testing.T)
semconv.RPCMethod("bar"),
semconv.NetPeerName("fake"),
semconv.NetPeerPort(8906),
attribute.Bool("custom", true),
}
assert.ElementsMatch(t, expectedAttr, span.Attributes())

Expand Down

0 comments on commit 2ccb63e

Please sign in to comment.