diff --git a/dynamic_sampling_context_test.go b/dynamic_sampling_context_test.go index ab39e8399..b176ca4da 100644 --- a/dynamic_sampling_context_test.go +++ b/dynamic_sampling_context_test.go @@ -2,8 +2,9 @@ package sentry import ( "context" - "strings" "testing" + + "github.com/getsentry/sentry-go/internal/testutils" ) func TestDynamicSamplingContextFromHeader(t *testing.T) { @@ -177,7 +178,5 @@ func TestString(t *testing.T) { "sample_rate": "1", }, } - assertEqual(t, strings.Contains(dsc.String(), "sentry-trace_id=d49d9bf66f13450b81f65bc51cf49c03"), true) - assertEqual(t, strings.Contains(dsc.String(), "sentry-public_key=public"), true) - assertEqual(t, strings.Contains(dsc.String(), "sentry-sample_rate=1"), true) + testutils.AssertBaggageStringsEqual(t, dsc.String(), "sentry-trace_id=d49d9bf66f13450b81f65bc51cf49c03,sentry-public_key=public,sentry-sample_rate=1") } diff --git a/otel/propagator.go b/otel/propagator.go index faf56be2a..f53b3b796 100644 --- a/otel/propagator.go +++ b/otel/propagator.go @@ -46,11 +46,7 @@ func (p sentryPropagator) Inject(ctx context.Context, carrier propagation.TextMa // Propagate baggage header sentryBaggageStr := "" if sentrySpan != nil { - // Finalize/freeze the baggage - containingTransaction := sentrySpan.GetTransaction() - dynamicSamplingContext := sentry.DynamicSamplingContextFromTransaction(containingTransaction) - containingTransaction.SetDynamicSamplingContext(dynamicSamplingContext) - sentryBaggageStr = containingTransaction.ToBaggage() + sentryBaggageStr = sentrySpan.GetTransaction().ToBaggage() } // FIXME: We're basically reparsing the header again, because internally in sentry-go // we currently use a vendored version of "otel/baggage" package. diff --git a/otel/span_processor_test.go b/otel/span_processor_test.go index 2aa9a376e..7dd11a382 100644 --- a/otel/span_processor_test.go +++ b/otel/span_processor_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/getsentry/sentry-go" + "github.com/getsentry/sentry-go/internal/testutils" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" otelSdkTrace "go.opentelemetry.io/otel/sdk/trace" @@ -129,9 +130,14 @@ func TestOnStartRootSpan(t *testing.T) { assertEqual(t, sentrySpan.TraceID.String(), otelTraceId.String()) assertEqual(t, sentrySpan.ParentSpanID, sentry.SpanID{}) assertTrue(t, sentrySpan.IsTransaction()) - assertEqual(t, sentrySpan.ToBaggage(), "") assertEqual(t, sentrySpan.Sampled, sentry.SampledTrue) assertEqual(t, transactionName(sentrySpan), "spanName") + + testutils.AssertBaggageStringsEqual( + t, + sentrySpan.ToBaggage(), + "sentry-transaction=spanName,sentry-environment=testing,sentry-public_key=abc,sentry-release=1.2.3,sentry-sample_rate=1,sentry-trace_id="+otelTraceId.String(), + ) } func TestOnStartWithTraceParentContext(t *testing.T) { @@ -178,11 +184,16 @@ func TestOnStartWithTraceParentContext(t *testing.T) { assertEqual(t, sentrySpan.TraceID.String(), "bc6d53f15eb88f4320054569b8c553d4") assertEqual(t, sentrySpan.ParentSpanID, SpanIDFromHex("b72fa28504b07285")) assertTrue(t, sentrySpan.IsTransaction()) - assertEqual(t, sentrySpan.ToBaggage(), "sentry-environment=dev") assertEqual(t, sentrySpan.Sampled, sentry.SampledFalse) assertEqual(t, transactionName(sentrySpan), "spanName") assertEqual(t, sentrySpan.Status, sentry.SpanStatusUndefined) assertEqual(t, sentrySpan.Source, sentry.SourceCustom) + + testutils.AssertBaggageStringsEqual( + t, + sentrySpan.ToBaggage(), + "sentry-environment=dev", + ) } func TestOnStartWithExistingParentSpan(t *testing.T) { diff --git a/tracing.go b/tracing.go index 802f6e8de..e18325dd2 100644 --- a/tracing.go +++ b/tracing.go @@ -270,8 +270,9 @@ func (s *Span) GetTransaction() *Span { // func (s *Span) TransactionName() string // func (s *Span) SetTransactionName(name string) -// ToSentryTrace returns the trace propagation value used with the sentry-trace -// HTTP header. +// ToSentryTrace returns the seralized TraceParentContext from a transaction/sapn. +// Use this function to propagate the TraceParentContext to a downstream SDK, +// either as the value of the "sentry-trace" HTTP header, or as an html "sentry-trace" meta tag. func (s *Span) ToSentryTrace() string { // TODO(tracing): add instrumentation for outgoing HTTP requests using // ToSentryTrace. @@ -286,9 +287,18 @@ func (s *Span) ToSentryTrace() string { return b.String() } -// ToBaggage returns the serialized dynamic sampling context in the baggage format. +// ToBaggage returns the serialized DynamicSamplingContext from a transaction. +// Use this function to propagate the DynamicSamplingContext to a downstream SDK, +// either as the value of the "baggage" HTTP header, or as an html "baggage" meta tag. func (s *Span) ToBaggage() string { if containingTransaction := s.GetTransaction(); containingTransaction != nil { + // In case there is currently no frozen DynamicSamplingContext attached to the transaction, + // create one from the properties of the transaction. + if !s.dynamicSamplingContext.IsFrozen() { + // This will return a frozen DynamicSamplingContext. + s.dynamicSamplingContext = DynamicSamplingContextFromTransaction(containingTransaction) + } + return containingTransaction.dynamicSamplingContext.String() } return "" diff --git a/tracing_test.go b/tracing_test.go index be2adff40..432b3df12 100644 --- a/tracing_test.go +++ b/tracing_test.go @@ -811,32 +811,22 @@ func TestGetTransactionReturnsNilOnManuallyCreatedSpans(t *testing.T) { } } -func TestSpanToBaggage(t *testing.T) { +func TestToBaggage(t *testing.T) { ctx := NewTestContext(ClientOptions{ EnableTracing: true, SampleRate: 1.0, Release: "test-release", }) - - // Should work transaction transaction := StartTransaction(ctx, "transaction-name") transaction.TraceID = TraceIDFromHex("f1a4c5c9071eca1cdf04e4132527ed16") - // Before finalizing - assertBaggageStringsEqual( - t, - transaction.ToBaggage(), - "", - ) - dsc := DynamicSamplingContextFromTransaction(transaction) - transaction.SetDynamicSamplingContext(dsc) - // After finalizing + assertBaggageStringsEqual( t, transaction.ToBaggage(), "sentry-trace_id=f1a4c5c9071eca1cdf04e4132527ed16,sentry-release=test-release,sentry-transaction=transaction-name", ) - // Should work on child span + // Calling ToBaggage() on a child span should return the same result child := transaction.StartChild("op-name") assertBaggageStringsEqual( t,