From ed78826dd7d36d4a3423e40fff58d511eb7b6ef8 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Wed, 11 Jun 2025 14:33:07 -0400 Subject: [PATCH 1/4] Lock sampling priority when inheriting from parent --- ddtrace/opentelemetry/tracer_test.go | 7 +++++-- ddtrace/tracer/tracer.go | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ddtrace/opentelemetry/tracer_test.go b/ddtrace/opentelemetry/tracer_test.go index b79e9f00cd5..1684dc1f2a4 100644 --- a/ddtrace/opentelemetry/tracer_test.go +++ b/ddtrace/opentelemetry/tracer_test.go @@ -98,9 +98,12 @@ func TestTracerOptions(t *testing.T) { assert.Contains(fmt.Sprint(sp), "dd.env=wrapper_env") } -func TestSpanContext(t *testing.T) { +func TestExtractSpanContext(t *testing.T) { assert := assert.New(t) - tp := NewTracerProvider() + // Start tracer with trace sample rules, which should be ignored in favor of the sampling priority inherited from tracer.Extract + tp := NewTracerProvider(tracer.WithSamplingRules([]tracer.SamplingRule{ + {Rate: 0}, // This should be applied only when a brand new root span is started + })) defer tp.Shutdown() otel.SetTracerProvider(tp) tr := otel.Tracer("") diff --git a/ddtrace/tracer/tracer.go b/ddtrace/tracer/tracer.go index ddb2b1bbd32..7f2aac27f7d 100644 --- a/ddtrace/tracer/tracer.go +++ b/ddtrace/tracer/tracer.go @@ -627,6 +627,8 @@ func (t *tracer) StartSpan(operationName string, options ...ddtrace.StartSpanOpt span.ParentID = context.spanID if p, ok := context.SamplingPriority(); ok { span.setMetric(keySamplingPriority, float64(p)) + // TODO: Check whether prio is trace rules or span rules? + context.trace.setLocked(true) } if context.span != nil { // local parent, inherit service From c436906e07db1967c43ccc954df2d730d2a78968 Mon Sep 17 00:00:00 2001 From: Mikayla Toffler Date: Thu, 12 Jun 2025 11:23:26 -0400 Subject: [PATCH 2/4] Add test for ddtrace/tracer case --- ddtrace/opentelemetry/tracer_test.go | 2 +- ddtrace/tracer/spancontext.go | 3 ++- ddtrace/tracer/tracer_test.go | 20 ++++++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/ddtrace/opentelemetry/tracer_test.go b/ddtrace/opentelemetry/tracer_test.go index 1684dc1f2a4..22186b744cd 100644 --- a/ddtrace/opentelemetry/tracer_test.go +++ b/ddtrace/opentelemetry/tracer_test.go @@ -98,7 +98,7 @@ func TestTracerOptions(t *testing.T) { assert.Contains(fmt.Sprint(sp), "dd.env=wrapper_env") } -func TestExtractSpanContext(t *testing.T) { +func TestParentContext(t *testing.T) { assert := assert.New(t) // Start tracer with trace sample rules, which should be ignored in favor of the sampling priority inherited from tracer.Extract tp := NewTracerProvider(tracer.WithSamplingRules([]tracer.SamplingRule{ diff --git a/ddtrace/tracer/spancontext.go b/ddtrace/tracer/spancontext.go index 8ba1729ce20..a77fece2e59 100644 --- a/ddtrace/tracer/spancontext.go +++ b/ddtrace/tracer/spancontext.go @@ -469,7 +469,8 @@ func (t *trace) finishedOne(s *span) { // we won't be able to make changes to a span after finishing // without causing a race condition. t.root.setMetric(keySamplingPriority, *t.priority) - t.locked = true + t.setLocked(true) + // t.locked = true } if len(t.spans) > 0 && s == t.spans[0] { // first span in chunk finished, lock down the tags diff --git a/ddtrace/tracer/tracer_test.go b/ddtrace/tracer/tracer_test.go index c91240a9648..12213719841 100644 --- a/ddtrace/tracer/tracer_test.go +++ b/ddtrace/tracer/tracer_test.go @@ -890,6 +890,26 @@ func TestStartSpanOrigin(t *testing.T) { assert.Equal("synthetics", carrier2[originHeader]) } +func TestInjectNotOverwriteSampling(t *testing.T) { + + assert := assert.New(t) + + tracer := newTracer(WithSamplingRules([]SamplingRule{ + {Rate: 0}, + })) + defer tracer.Stop() + root := tracer.StartSpan("web.request").(*span) + root.SetBaggageItem("x", "y") + root.setMetric(keySamplingPriority, float64(2)) + ctx := root.Context().(*spanContext) + headers := http.Header{} + carrier := HTTPHeadersCarrier(headers) + tracer.Inject(ctx, carrier) + + assert.Equal("2", headers.Get(DefaultPriorityHeader)) + +} + func TestPropagationDefaults(t *testing.T) { t.Setenv(headerPropagationStyleExtract, "datadog") t.Setenv(headerPropagationStyleInject, "datadog") From 4af64e2acc454f3f24a32dc3bc10a8481902bb52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dario=20Casta=C3=B1=C3=A9?= Date: Fri, 20 Jun 2025 08:20:30 +0200 Subject: [PATCH 3/4] fix(ddtrace/tracer): revert t.setLocked usage in finishedOne to avoid deadlock --- ddtrace/tracer/spancontext.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ddtrace/tracer/spancontext.go b/ddtrace/tracer/spancontext.go index a77fece2e59..8ba1729ce20 100644 --- a/ddtrace/tracer/spancontext.go +++ b/ddtrace/tracer/spancontext.go @@ -469,8 +469,7 @@ func (t *trace) finishedOne(s *span) { // we won't be able to make changes to a span after finishing // without causing a race condition. t.root.setMetric(keySamplingPriority, *t.priority) - t.setLocked(true) - // t.locked = true + t.locked = true } if len(t.spans) > 0 && s == t.spans[0] { // first span in chunk finished, lock down the tags From 21ca316d521da22cc7cd0863b2b776b16cc74fad Mon Sep 17 00:00:00 2001 From: Mikayla Toffler <46911781+mtoffl01@users.noreply.github.com> Date: Wed, 2 Jul 2025 13:27:20 -0400 Subject: [PATCH 4/4] Update ddtrace/tracer/tracer_test.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Dario Castañé --- ddtrace/tracer/tracer_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/ddtrace/tracer/tracer_test.go b/ddtrace/tracer/tracer_test.go index 12213719841..ff906d0106f 100644 --- a/ddtrace/tracer/tracer_test.go +++ b/ddtrace/tracer/tracer_test.go @@ -891,7 +891,6 @@ func TestStartSpanOrigin(t *testing.T) { } func TestInjectNotOverwriteSampling(t *testing.T) { - assert := assert.New(t) tracer := newTracer(WithSamplingRules([]SamplingRule{ @@ -907,7 +906,6 @@ func TestInjectNotOverwriteSampling(t *testing.T) { tracer.Inject(ctx, carrier) assert.Equal("2", headers.Get(DefaultPriorityHeader)) - } func TestPropagationDefaults(t *testing.T) {