diff --git a/sentry_sdk/tracing_utils.py b/sentry_sdk/tracing_utils.py index b1a9bec516..d75d94efd6 100644 --- a/sentry_sdk/tracing_utils.py +++ b/sentry_sdk/tracing_utils.py @@ -1575,20 +1575,6 @@ def add_sentry_baggage_to_headers( ) -def _get_effective_sample_rate( - client: "Any", propagation_context: "PropagationContext" -) -> "Union[float, bool]": - if propagation_context.parent_sampled is not None: - propagation_context_sample_rate = propagation_context._sample_rate() - - if propagation_context_sample_rate is not None: - return propagation_context_sample_rate - else: - return propagation_context.parent_sampled - else: - return client.options["traces_sample_rate"] - - def _make_sampling_decision( name: str, attributes: "Optional[Attributes]", @@ -1651,13 +1637,15 @@ def _make_sampling_decision( "[Tracing] traces_sampler raised; falling back to parent sample rate or traces_sample_rate", exc_info=True, ) - sample_rate = _get_effective_sample_rate( - client=client, propagation_context=propagation_context - ) + if propagation_context.parent_sampled is not None: + sample_rate = propagation_context.parent_sampled + else: + sample_rate = client.options["traces_sample_rate"] else: - sample_rate = _get_effective_sample_rate( - client=client, propagation_context=propagation_context - ) + if propagation_context.parent_sampled is not None: + sample_rate = propagation_context.parent_sampled + else: + sample_rate = client.options["traces_sample_rate"] # Validate whether the sample_rate we got is actually valid. Since # traces_sampler is user-provided, it could return anything. diff --git a/tests/integrations/stdlib/test_httplib.py b/tests/integrations/stdlib/test_httplib.py index dff91087f4..2282045e78 100644 --- a/tests/integrations/stdlib/test_httplib.py +++ b/tests/integrations/stdlib/test_httplib.py @@ -318,7 +318,7 @@ def getresponse(self, *args, **kwargs): expected_outgoing_baggage = ( "sentry-trace_id=771a43a4192642f0b136d5159a501700," "sentry-public_key=49d0f7386ad645858ae85020e393bef3," - "sentry-sample_rate=0.01337," + "sentry-sample_rate=1.0," "sentry-user_id=Am%C3%A9lie," "sentry-sample_rand=0.000005," "sentry-sampled=true" @@ -345,8 +345,6 @@ def getresponse(self, *args, **kwargs): sampled=1, ) - # Note: the sample rate here is actually wrong. It's fixed in the - # streaming path expected_outgoing_baggage = ( "sentry-trace_id=771a43a4192642f0b136d5159a501700," "sentry-public_key=49d0f7386ad645858ae85020e393bef3," diff --git a/tests/tracing/test_span_streaming.py b/tests/tracing/test_span_streaming.py index 669d15deaf..0637724c3e 100644 --- a/tests/tracing/test_span_streaming.py +++ b/tests/tracing/test_span_streaming.py @@ -988,10 +988,67 @@ def test_outgoing_traceparent_and_baggage_incoming_trace( traceparent == f"{trace_id}-{span_id}-{'1' if parent_sampled else '0'}" ) - # As we've received incoming baggage, we mustn't modify it ourselves and - # have to propagate it as-is baggage = sentry_sdk.get_baggage() baggage_items = dict(tuple(item.split("=")) for item in baggage.split(",")) + + # As we've received incoming baggage, we shouldn't modify it ourselves + # and should propagate it as-is. However, in the case where our + # effective sample rate overrides the parent sample rate, we update the + # sample rate in the baggage as a consequence of updating the sample rate + # in the DSC. + if traces_sample_rate is not None: + incoming_baggage["sentry-sample_rate"] = str(float(parent_sampled)) + + assert baggage_items == incoming_baggage + + +def test_outgoing_traceparent_and_baggage_inconsistent_incoming_trace( + sentry_init, +): + # We correctly propagate even if we get a sample_rate/sample_rand/sampled + # baggage combination from upstream that doesn't align with the parent + # sampling decision + sentry_init( + traces_sample_rate=1.0, + trace_lifecycle="stream", + ) + + trace_id = "0af7651916cd43dd8448eb211c80319c" + parent_span_id = "b7ad6b7169203331" + + # Baggage says sampled, sentry-trace says unsampled. sentry-trace takes + # precedence + incoming_sentry_trace = f"{trace_id}-{parent_span_id}-0" + incoming_baggage = { + "sentry-trace_id": trace_id, + "sentry-sample_rate": "0.75", + "sentry-sample_rand": "0.500000", + "sentry-sampled": "true", + } + + sentry_sdk.traces.continue_trace( + { + "sentry-trace": incoming_sentry_trace, + "baggage": ",".join( + sorted([f"{k}={v}" for k, v in incoming_baggage.items()]) + ), + } + ) + + with sentry_sdk.traces.start_span(name="span") as span: + assert span.sampled is False + + traceparent = sentry_sdk.get_traceparent() + + span_id = span.span_id + assert traceparent == f"{trace_id}-{span_id}-0" + + # We shouldn't be updating incoming baggage, but in the case where our + # effective sample rate overrides the parent sample rate, we do this as + # a consequence of updating the sample rate in the DSC. + baggage = sentry_sdk.get_baggage() + baggage_items = dict(tuple(item.split("=")) for item in baggage.split(",")) + incoming_baggage["sentry-sample_rate"] = "0.0" assert baggage_items == incoming_baggage