Skip to content

Commit 8ee7dd4

Browse files
authored
Respect parent_sampled decision in propagation_context sentry-trace header (#4356)
Since we don't automatically have unsampled spans running, this caused a change in behavior when an upstream sampling decision needs to be propagated further downstream. ### Explanation of problem When an incoming trace has `sampled` set to 0 (`trace_id-span_id-0`), in the past we would propagate this since we would have an active span/transaction running but just not sampled, so downstream would also receive `trace_id-span_id-0` from that active span. Now, we actually don't have an active span since we don't sample (just how otel works), so instead of sending the `trace_id-span_id-0` as before, we would have sent `trace_id-other_span_id` from the `propagation_context` instead. This would cause the downstream service to not receive the `-0` flag and would thus sample independently, which is a regression.
1 parent 112c28f commit 8ee7dd4

File tree

2 files changed

+16
-5
lines changed

2 files changed

+16
-5
lines changed

sentry_sdk/scope.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -505,11 +505,7 @@ def get_traceparent(self, *args, **kwargs):
505505

506506
# If this scope has a propagation context, return traceparent from there
507507
if self._propagation_context is not None:
508-
traceparent = "%s-%s" % (
509-
self._propagation_context.trace_id,
510-
self._propagation_context.span_id,
511-
)
512-
return traceparent
508+
return self._propagation_context.to_traceparent()
513509

514510
# Fall back to isolation scope's traceparent. It always has one
515511
return self.get_isolation_scope().get_traceparent()

sentry_sdk/tracing_utils.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,21 @@ def span_id(self, value):
432432
# type: (str) -> None
433433
self._span_id = value
434434

435+
def to_traceparent(self):
436+
# type: () -> str
437+
if self.parent_sampled is True:
438+
sampled = "1"
439+
elif self.parent_sampled is False:
440+
sampled = "0"
441+
else:
442+
sampled = None
443+
444+
traceparent = "%s-%s" % (self.trace_id, self.span_id)
445+
if sampled is not None:
446+
traceparent += "-%s" % (sampled,)
447+
448+
return traceparent
449+
435450
def update(self, other_dict):
436451
# type: (Dict[str, Any]) -> None
437452
"""

0 commit comments

Comments
 (0)