Open
Description
Tracer Version(s)
2.0.0
Go Version(s)
go version go1.23.4 darwin/arm64
Bug Report
The OpenTelemetry tracer implementation in dd-trace-go doesn't seem to use the sampling decision from the parent span context when the parent span doesn't originate from the Datadog tracer.
https://github.com/DataDog/dd-trace-go/blob/v2.0.0/ddtrace/opentelemetry/tracer.go#L46
As can be seen in the code linked above, the trace ID and the parent span ID are read from the context, so there is no issue with stitching spans together. However, since the sampling decision is ignored, head-based sampling doesn't work correctly. The span's sampling decision ends up being made independently of the parent span's sampling decision.
Reproduction Code
import (
"context"
"testing"
"github.com/stretchr/testify/require"
oteltrace "go.opentelemetry.io/otel/trace"
ddotel "github.com/DataDog/dd-trace-go/v2/ddtrace/opentelemetry"
ddtracer "github.com/DataDog/dd-trace-go/v2/ddtrace/tracer"
)
func Test_DDOpenTelemetryTracer(t *testing.T) {
ddOTelTracer := ddotel.NewTracerProvider(
ddtracer.WithSamplingRules([]ddtracer.SamplingRule{
{Rate: 0}, // This should be applied only when a brand new root span is started and should be ignored for a non-root span
}),
).Tracer("")
parentSpanContext := oteltrace.NewSpanContext(oteltrace.SpanContextConfig{
TraceID: oteltrace.TraceID{0xAA},
SpanID: oteltrace.SpanID{0x01},
TraceFlags: oteltrace.FlagsSampled, // the parent span is sampled, so its child spans should be sampled too
})
ctx := oteltrace.ContextWithSpanContext(context.Background(), parentSpanContext)
_, span := ddOTelTracer.Start(ctx, "test")
span.End()
childSpanContext := span.SpanContext()
require.Equal(t, parentSpanContext.TraceID(), childSpanContext.TraceID())
require.True(t, childSpanContext.IsSampled(), "parent span is sampled, but child span is not sampled") // this test fails
}
require (
github.com/DataDog/dd-trace-go/v2 v2.0.0
github.com/stretchr/testify v1.10.0
go.opentelemetry.io/otel/trace v1.35.0
)
Error Logs
No response
Go Env Output
No response