Skip to content

fix(ddtrace/opentelemetry): propagate sampling decision to child spans #3673

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ddtrace/opentelemetry/tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ func (t *oteltracer) Start(ctx context.Context, spanName string, opts ...oteltra
// if the span doesn't originate from the Datadog tracer,
// use SpanContextW3C implementation struct to pass span context information
ddopts = append(ddopts, tracer.ChildOf(tracer.FromGenericCtx(&otelCtxToDDCtx{sctx})))
if sctx.IsSampled() {
ddopts = append(ddopts, tracer.Tag(ext.ManualKeep, true))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look right.

If the parent span is sampled, the new span shouldn't need to get force-sampled to get sampled. This will incorrectly set the ingestion_reason span metadata to manual instead of rule (relevant doc).

Also, this doesn't cover the case when the parent span is not sampled. In that case, the child span shouldn't be sampled either. However, with this code, the child span will independently decide its sampling decision, so it might be sampled.

}
}
}
if t := ssConfig.Timestamp(); !t.IsZero() {
Expand Down
25 changes: 25 additions & 0 deletions ddtrace/opentelemetry/tracer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,31 @@ func TestSpanContext(t *testing.T) {
assert.Equal(true, sctx.IsRemote())
}

func TestSamplingDecision(t *testing.T) {
assert := assert.New(t)
tp := NewTracerProvider(
tracer.WithSamplingRules([]tracer.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
}),
)
defer tp.Shutdown()
otel.SetTracerProvider(tp)
tr := otel.Tracer("")

parentSpanContext := oteltrace.NewSpanContext(oteltrace.SpanContextConfig{
TraceID: oteltrace.TraceID{0xAB},
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 := tr.Start(ctx, "test")
span.End()

childSpanContext := span.SpanContext()
assert.Equal(parentSpanContext.TraceID(), childSpanContext.TraceID())
assert.True(childSpanContext.IsSampled(), "parent span is sampled, but child span is not sampled")
}

func TestForceFlush(t *testing.T) {
const (
UNSET = iota
Expand Down
Loading