diff --git a/ddtrace/opentelemetry/span.go b/ddtrace/opentelemetry/span.go index 4f3bacdfa6..7109fd50d6 100644 --- a/ddtrace/opentelemetry/span.go +++ b/ddtrace/opentelemetry/span.go @@ -19,23 +19,23 @@ import ( "go.opentelemetry.io/otel/attribute" otelcodes "go.opentelemetry.io/otel/codes" oteltrace "go.opentelemetry.io/otel/trace" + "go.opentelemetry.io/otel/trace/noop" ) var _ oteltrace.Span = (*span)(nil) type span struct { - tracer.Span + noop.Span // https://pkg.go.dev/go.opentelemetry.io/otel/trace#hdr-API_Implementations + DD tracer.Span finished bool finishOpts []tracer.FinishOption statusInfo *oteltracer } -func (s *span) TracerProvider() oteltrace.TracerProvider { return s.oteltracer.provider } -func (s *span) AddEvent(_ string, _ ...oteltrace.EventOption) { /* no-op */ } -func (s *span) RecordError(_ error, _ ...oteltrace.EventOption) { /* no-op */ } +func (s *span) TracerProvider() oteltrace.TracerProvider { return s.oteltracer.provider } -func (s *span) SetName(name string) { s.SetOperationName(name) } +func (s *span) SetName(name string) { s.DD.SetOperationName(name) } func (s *span) End(options ...oteltrace.SpanEndOption) { if s.finished { @@ -45,7 +45,7 @@ func (s *span) End(options ...oteltrace.SpanEndOption) { var finishCfg = oteltrace.NewSpanEndConfig(options...) var opts []tracer.FinishOption if s.statusInfo.code == otelcodes.Error { - s.SetTag(ext.ErrorMsg, s.statusInfo.description) + s.DD.SetTag(ext.ErrorMsg, s.statusInfo.description) opts = append(opts, tracer.WithError(errors.New(s.statusInfo.description))) } if t := finishCfg.Timestamp(); !t.IsZero() { @@ -54,7 +54,7 @@ func (s *span) End(options ...oteltrace.SpanEndOption) { if len(s.finishOpts) != 0 { opts = append(opts, s.finishOpts...) } - s.Finish(opts...) + s.DD.Finish(opts...) } // EndOptions sets tracer.FinishOption on a given span to be executed when span is finished. @@ -68,7 +68,7 @@ func EndOptions(sp oteltrace.Span, options ...tracer.FinishOption) { // SpanContext returns implementation of the oteltrace.SpanContext. func (s *span) SpanContext() oteltrace.SpanContext { - ctx := s.Span.Context() + ctx := s.DD.Context() var traceID oteltrace.TraceID var spanID oteltrace.SpanID if w3cCtx, ok := ctx.(ddtrace.SpanContextW3C); ok { @@ -88,7 +88,7 @@ func (s *span) SpanContext() oteltrace.SpanContext { func (s *span) extractTraceData(c *oteltrace.SpanContextConfig) { headers := tracer.TextMapCarrier{} - if err := tracer.Inject(s.Context(), headers); err != nil { + if err := tracer.Inject(s.DD.Context(), headers); err != nil { return } state, err := oteltrace.ParseTraceState(headers["tracestate"]) @@ -143,7 +143,7 @@ func (s *span) SetStatus(code otelcodes.Code, description string) { // Every value is propagated as an interface. func (s *span) SetAttributes(kv ...attribute.KeyValue) { for _, attr := range kv { - s.SetTag(toSpecialAttributes(string(attr.Key), attr.Value)) + s.DD.SetTag(toSpecialAttributes(string(attr.Key), attr.Value)) } } diff --git a/ddtrace/opentelemetry/span_test.go b/ddtrace/opentelemetry/span_test.go index 5602319d22..b3f513ba82 100644 --- a/ddtrace/opentelemetry/span_test.go +++ b/ddtrace/opentelemetry/span_test.go @@ -253,7 +253,7 @@ func TestSpanContextWithStartOptions(t *testing.T) { ddChild := child.(*span) // this verifies that options passed to the parent, such as tracer.WithSpanID(spanID) // weren't passed down to the child - assert.NotEqual(spanID, ddChild.Context().SpanID()) + assert.NotEqual(spanID, ddChild.DD.Context().SpanID()) child.End() EndOptions(sp, tracer.FinishTime(startTime.Add(duration))) diff --git a/ddtrace/opentelemetry/tracer.go b/ddtrace/opentelemetry/tracer.go index 82a475980d..92d6634971 100644 --- a/ddtrace/opentelemetry/tracer.go +++ b/ddtrace/opentelemetry/tracer.go @@ -16,6 +16,7 @@ import ( "gopkg.in/DataDog/dd-trace-go.v1/internal/telemetry" oteltrace "go.opentelemetry.io/otel/trace" + "go.opentelemetry.io/otel/trace/noop" ) var _ oteltrace.Tracer = (*oteltracer)(nil) @@ -23,8 +24,9 @@ var _ oteltrace.Tracer = (*oteltracer)(nil) var telemetryTags = []string{`"integration_name":"otel"`} type oteltracer struct { - provider *TracerProvider - ddtrace.Tracer + noop.Tracer // https://pkg.go.dev/go.opentelemetry.io/otel/trace#hdr-API_Implementations + provider *TracerProvider + DD ddtrace.Tracer } func (t *oteltracer) Start(ctx context.Context, spanName string, opts ...oteltrace.SpanStartOption) (context.Context, oteltrace.Span) { @@ -56,7 +58,7 @@ func (t *oteltracer) Start(ctx context.Context, spanName string, opts ...oteltra telemetry.GlobalClient.Count(telemetry.NamespaceTracers, "spans_created", 1.0, telemetryTags, true) s := tracer.StartSpan(spanName, ddopts...) os := oteltrace.Span(&span{ - Span: s, + DD: s, oteltracer: t, }) // Erase the start span options from the context to prevent them from being propagated to children @@ -90,11 +92,3 @@ func (c *otelCtxToDDCtx) TraceID128() string { func (c *otelCtxToDDCtx) TraceID128Bytes() [16]byte { return c.oc.TraceID() } - -var _ oteltrace.Tracer = (*noopOteltracer)(nil) - -type noopOteltracer struct{} - -func (n *noopOteltracer) Start(_ context.Context, _ string, _ ...oteltrace.SpanStartOption) (context.Context, oteltrace.Span) { - return nil, nil -} diff --git a/ddtrace/opentelemetry/tracer_provider.go b/ddtrace/opentelemetry/tracer_provider.go index d8b906ef6b..f27d158853 100644 --- a/ddtrace/opentelemetry/tracer_provider.go +++ b/ddtrace/opentelemetry/tracer_provider.go @@ -19,7 +19,9 @@ // yourCode(ctx) // sp.End() // -// Not every feature provided by OpenTelemetry is supported with this wrapper today. +// Not every feature provided by OpenTelemetry is supported with this wrapper today, and any new API methods +// added to the OpenTelemetry API will default to being a no-op until implemented by this library. See the +// OpenTelemetry package docs for more details: https://pkg.go.dev/go.opentelemetry.io/otel/trace#hdr-API_Implementations. // This package seeks to implement a minimal set of functions within // the OpenTelemetry Tracing API (https://opentelemetry.io/docs/reference/specification/trace/api) // to allow users to send traces to Datadog using existing OpenTelemetry code with minimal changes to the application. @@ -36,6 +38,7 @@ import ( "gopkg.in/DataDog/dd-trace-go.v1/internal/log" oteltrace "go.opentelemetry.io/otel/trace" + "go.opentelemetry.io/otel/trace/noop" ) var _ oteltrace.TracerProvider = (*TracerProvider)(nil) @@ -45,8 +48,9 @@ var _ oteltrace.TracerProvider = (*TracerProvider)(nil) // trace computational workflows. // WithInstrumentationVersion and WithSchemaURL TracerOptions are not supported. type TracerProvider struct { - tracer *oteltracer - stopped uint32 // stopped indicates whether the tracerProvider has been shutdown. + noop.TracerProvider // https://pkg.go.dev/go.opentelemetry.io/otel/trace#hdr-API_Implementations + tracer *oteltracer + stopped uint32 // stopped indicates whether the tracerProvider has been shutdown. sync.Once } @@ -58,7 +62,7 @@ func NewTracerProvider(opts ...tracer.StartOption) *TracerProvider { tracer.Start(opts...) p := &TracerProvider{} t := &oteltracer{ - Tracer: internal.GetGlobalTracer(), + DD: internal.GetGlobalTracer(), provider: p, } p.tracer = t @@ -70,7 +74,7 @@ func NewTracerProvider(opts ...tracer.StartOption) *TracerProvider { // If the TracerProvider has already been shut down, this will return a no-op tracer. func (p *TracerProvider) Tracer(_ string, _ ...oteltrace.TracerOption) oteltrace.Tracer { if atomic.LoadUint32(&p.stopped) != 0 { - return &noopOteltracer{} + return noop.NewTracerProvider().Tracer("") } return p.tracer } diff --git a/ddtrace/opentelemetry/tracer_test.go b/ddtrace/opentelemetry/tracer_test.go index 2f9b87d37a..c9a6a3f91a 100644 --- a/ddtrace/opentelemetry/tracer_test.go +++ b/ddtrace/opentelemetry/tracer_test.go @@ -23,6 +23,7 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" oteltrace "go.opentelemetry.io/otel/trace" + "go.opentelemetry.io/otel/trace/noop" ) func TestGetTracer(t *testing.T) { @@ -32,7 +33,7 @@ func TestGetTracer(t *testing.T) { dd := internal.GetGlobalTracer() ott, ok := tr.(*oteltracer) assert.True(ok) - assert.Equal(ott.Tracer, dd) + assert.Equal(ott.DD, dd) } func TestGetTracerMultiple(t *testing.T) { @@ -52,7 +53,7 @@ func TestSpanWithContext(t *testing.T) { got, ok := tracer.SpanFromContext(ctx) assert.True(ok) - assert.Equal(got, sp.(*span).Span) + assert.Equal(got, sp.(*span).DD) assert.Equal(fmt.Sprintf("%016x", got.Context().SpanID()), sp.SpanContext().SpanID().String()) } @@ -66,7 +67,7 @@ func TestSpanWithNewRoot(t *testing.T) { otelCtx, child := tr.Start(ddCtx, "otel.child", oteltrace.WithNewRoot()) got, ok := tracer.SpanFromContext(otelCtx) assert.True(ok) - assert.Equal(got, child.(*span).Span) + assert.Equal(got, child.(*span).DD) var parentBytes oteltrace.TraceID uint64ToByte(noopParent.Context().TraceID(), parentBytes[:]) @@ -91,7 +92,7 @@ func TestTracerOptions(t *testing.T) { ctx, sp := tr.Start(context.Background(), "otel.test") got, ok := tracer.SpanFromContext(ctx) assert.True(ok) - assert.Equal(got, sp.(*span).Span) + assert.Equal(got, sp.(*span).DD) assert.Contains(fmt.Sprint(sp), "dd.env=wrapper_env") } @@ -187,12 +188,12 @@ func TestShutdownOnce(t *testing.T) { tp.Shutdown() // attempt to get the Tracer after shutdown and // start a span. The context and span returned - // from calling Start should be nil. + // should be no-op types. tr := otel.Tracer("") ctx, sp := tr.Start(context.Background(), "after_shutdown") assert.Equal(uint32(1), tp.stopped) - assert.Equal(sp, nil) - assert.Equal(ctx, nil) + assert.Equal(noop.Span{}, sp) + assert.Equal(oteltrace.ContextWithSpan(context.Background(), noop.Span{}), ctx) } func TestSpanTelemetry(t *testing.T) { diff --git a/go.mod b/go.mod index 989f702aad..0c8ab640cc 100644 --- a/go.mod +++ b/go.mod @@ -84,8 +84,8 @@ require ( github.com/zenazn/goji v1.0.1 go.mongodb.org/mongo-driver v1.12.1 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 - go.opentelemetry.io/otel v1.18.0 - go.opentelemetry.io/otel/trace v1.18.0 + go.opentelemetry.io/otel v1.20.0 + go.opentelemetry.io/otel/trace v1.20.0 go.uber.org/atomic v1.11.0 golang.org/x/net v0.17.0 golang.org/x/oauth2 v0.9.0 @@ -150,7 +150,7 @@ require ( github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-jose/go-jose/v3 v3.0.0 // indirect - github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-pg/zerochecker v0.2.0 // indirect github.com/go-playground/locales v0.14.1 // indirect @@ -163,7 +163,7 @@ require ( github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/s2a-go v0.1.5 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect @@ -246,7 +246,7 @@ require ( github.com/xdg-go/stringprep v1.0.4 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel/metric v1.18.0 // indirect + go.opentelemetry.io/otel/metric v1.20.0 // indirect go4.org/intern v0.0.0-20230525184215-6c62f75575cb // indirect go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2 // indirect golang.org/x/arch v0.4.0 // indirect diff --git a/go.sum b/go.sum index dc095761f6..d1886b1572 100644 --- a/go.sum +++ b/go.sum @@ -1166,8 +1166,8 @@ github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= @@ -1307,8 +1307,9 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -2114,16 +2115,16 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0/go.mod h1: go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs= go.opentelemetry.io/otel v1.6.3/go.mod h1:7BgNga5fNlF/iZjG06hM3yofffp0ofKCDwSXx1GC4dI= -go.opentelemetry.io/otel v1.18.0 h1:TgVozPGZ01nHyDZxK5WGPFB9QexeTMXEH7+tIClWfzs= -go.opentelemetry.io/otel v1.18.0/go.mod h1:9lWqYO0Db579XzVuCKFNPDl4s73Voa+zEck3wHaAYQI= +go.opentelemetry.io/otel v1.20.0 h1:vsb/ggIY+hUjD/zCAQHpzTmndPqv/ml2ArbsbfBYTAc= +go.opentelemetry.io/otel v1.20.0/go.mod h1:oUIGj3D77RwJdM6PPZImDpSZGDvkD9fhesHny69JFrs= go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0/go.mod h1:hO1KLR7jcKaDDKDkvI9dP/FIhpmna5lkqPUQdEjFAM8= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0/go.mod h1:keUU7UfnwWTWpJ+FWnyqmogPa82nuU5VUANFq49hlMY= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0/go.mod h1:QNX1aly8ehqqX1LEa6YniTU7VY9I6R3X/oPxhGdTceE= go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/metric v1.18.0 h1:JwVzw94UYmbx3ej++CwLUQZxEODDj/pOuTCvzhtRrSQ= -go.opentelemetry.io/otel/metric v1.18.0/go.mod h1:nNSpsVDjWGfb7chbRLUNW+PBNdcSTHD4Uu5pfFMOI0k= +go.opentelemetry.io/otel/metric v1.20.0 h1:ZlrO8Hu9+GAhnepmRGhSU7/VkpjrNowxRN9GyKR4wzA= +go.opentelemetry.io/otel/metric v1.20.0/go.mod h1:90DRw3nfK4D7Sm/75yQ00gTJxtkBxX+wu6YaNymbpVM= go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs= @@ -2132,8 +2133,8 @@ go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4 go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk= go.opentelemetry.io/otel/trace v1.6.3/go.mod h1:GNJQusJlUgZl9/TQBPKU/Y/ty+0iVB5fjhKeJGZPGFs= -go.opentelemetry.io/otel/trace v1.18.0 h1:NY+czwbHbmndxojTEKiSMHkG2ClNH2PwmcHrdo0JY10= -go.opentelemetry.io/otel/trace v1.18.0/go.mod h1:T2+SGJGuYZY3bjj5rgh/hN7KIrlpWC5nS8Mjvzckz+0= +go.opentelemetry.io/otel/trace v1.20.0 h1:+yxVAPZPbQhbC3OfAkeIVTky6iTFpcr4SiY9om7mXSQ= +go.opentelemetry.io/otel/trace v1.20.0/go.mod h1:HJSK7F/hA5RlzpZ0zKDCHCDHm556LCDtKaAo6JmBFUU= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=