Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

otelgrpc: Add SpanStartOptions #3768

Merged
merged 9 commits into from Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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