Skip to content

Commit 027aa6e

Browse files
authored
Make PropagationContext hold baggage instead of dynamic_sampling_context (#5156)
### Description The `Transaction.continue_from_headers` and the `Transaction` constructor take a `Baggage` object so this was inconsistent with how I originally designed the baggage handling and created spaghetti loops between the two concepts.
1 parent 80ba8fb commit 027aa6e

File tree

2 files changed

+31
-35
lines changed

2 files changed

+31
-35
lines changed

sentry_sdk/scope.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -530,9 +530,7 @@ def get_dynamic_sampling_context(self):
530530

531531
baggage = self.get_baggage()
532532
if baggage is not None:
533-
self._propagation_context.dynamic_sampling_context = (
534-
baggage.dynamic_sampling_context()
535-
)
533+
self._propagation_context.baggage = baggage
536534

537535
return self._propagation_context.dynamic_sampling_context
538536

@@ -573,13 +571,7 @@ def get_baggage(self, *args, **kwargs):
573571

574572
# If this scope has a propagation context, return baggage from there
575573
if self._propagation_context is not None:
576-
dynamic_sampling_context = (
577-
self._propagation_context.dynamic_sampling_context
578-
)
579-
if dynamic_sampling_context is None:
580-
return Baggage.from_options(self)
581-
else:
582-
return Baggage(dynamic_sampling_context)
574+
return self._propagation_context.baggage or Baggage.from_options(self)
583575

584576
# Fall back to isolation scope's baggage. It always has one
585577
return self.get_isolation_scope().get_baggage()
@@ -1099,9 +1091,9 @@ def start_transaction(
10991091
if transaction.sample_rate is not None:
11001092
propagation_context = self.get_active_propagation_context()
11011093
if propagation_context:
1102-
dsc = propagation_context.dynamic_sampling_context
1103-
if dsc is not None:
1104-
dsc["sample_rate"] = str(transaction.sample_rate)
1094+
baggage = propagation_context.baggage
1095+
if baggage is not None:
1096+
baggage.sentry_items["sample_rate"] = str(transaction.sample_rate)
11051097
if transaction._baggage:
11061098
transaction._baggage.sentry_items["sample_rate"] = str(
11071099
transaction.sample_rate

sentry_sdk/tracing_utils.py

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ class PropagationContext:
411411
"_span_id",
412412
"parent_span_id",
413413
"parent_sampled",
414-
"dynamic_sampling_context",
414+
"baggage",
415415
)
416416

417417
def __init__(
@@ -421,6 +421,7 @@ def __init__(
421421
parent_span_id=None, # type: Optional[str]
422422
parent_sampled=None, # type: Optional[bool]
423423
dynamic_sampling_context=None, # type: Optional[Dict[str, str]]
424+
baggage=None, # type: Optional[Baggage]
424425
):
425426
# type: (...) -> None
426427
self._trace_id = trace_id
@@ -438,8 +439,12 @@ def __init__(
438439
Important when the parent span originated in an upstream service,
439440
because we want to sample the whole trace, or nothing from the trace."""
440441

441-
self.dynamic_sampling_context = dynamic_sampling_context
442-
"""Data that is used for dynamic sampling decisions."""
442+
self.baggage = baggage
443+
"""Parsed baggage header that is used for dynamic sampling decisions."""
444+
445+
"""DEPRECATED this only exists for backwards compat of constructor."""
446+
if baggage is None and dynamic_sampling_context is not None:
447+
self.baggage = Baggage(dynamic_sampling_context)
443448

444449
@classmethod
445450
def from_incoming_data(cls, incoming_data):
@@ -456,9 +461,7 @@ def from_incoming_data(cls, incoming_data):
456461

457462
baggage_header = normalized_data.get(BAGGAGE_HEADER_NAME)
458463
if baggage_header:
459-
propagation_context.dynamic_sampling_context = Baggage.from_incoming_header(
460-
baggage_header
461-
).dynamic_sampling_context()
464+
propagation_context.baggage = Baggage.from_incoming_header(baggage_header)
462465

463466
propagation_context._fill_sample_rand()
464467

@@ -493,6 +496,11 @@ def span_id(self, value):
493496
# type: (str) -> None
494497
self._span_id = value
495498

499+
@property
500+
def dynamic_sampling_context(self):
501+
# type: () -> Optional[Dict[str, Any]]
502+
return self.baggage.dynamic_sampling_context() if self.baggage else None
503+
496504
def update(self, other_dict):
497505
# type: (Dict[str, Any]) -> None
498506
"""
@@ -506,20 +514,20 @@ def update(self, other_dict):
506514

507515
def __repr__(self):
508516
# type: (...) -> str
509-
return "<PropagationContext _trace_id={} _span_id={} parent_span_id={} parent_sampled={} dynamic_sampling_context={}>".format(
517+
return "<PropagationContext _trace_id={} _span_id={} parent_span_id={} parent_sampled={} baggage={}>".format(
510518
self._trace_id,
511519
self._span_id,
512520
self.parent_span_id,
513521
self.parent_sampled,
514-
self.dynamic_sampling_context,
522+
self.baggage,
515523
)
516524

517525
def _fill_sample_rand(self):
518526
# type: () -> None
519527
"""
520-
Ensure that there is a valid sample_rand value in the dynamic_sampling_context.
528+
Ensure that there is a valid sample_rand value in the baggage.
521529
522-
If there is a valid sample_rand value in the dynamic_sampling_context, we keep it.
530+
If there is a valid sample_rand value in the baggage, we keep it.
523531
Otherwise, we generate a sample_rand value according to the following:
524532
525533
- If we have a parent_sampled value and a sample_rate in the DSC, we compute
@@ -532,23 +540,19 @@ def _fill_sample_rand(self):
532540
533541
The sample_rand is deterministically generated from the trace_id, if present.
534542
535-
This function does nothing if there is no dynamic_sampling_context.
543+
This function does nothing if there is no baggage.
536544
"""
537-
if self.dynamic_sampling_context is None:
545+
if self.baggage is None:
538546
return
539547

540-
sample_rand = try_convert(
541-
float, self.dynamic_sampling_context.get("sample_rand")
542-
)
548+
sample_rand = try_convert(float, self.baggage.sentry_items.get("sample_rand"))
543549
if sample_rand is not None and 0 <= sample_rand < 1:
544550
# sample_rand is present and valid, so don't overwrite it
545551
return
546552

547553
# Get the sample rate and compute the transformation that will map the random value
548554
# to the desired range: [0, 1), [0, sample_rate), or [sample_rate, 1).
549-
sample_rate = try_convert(
550-
float, self.dynamic_sampling_context.get("sample_rate")
551-
)
555+
sample_rate = try_convert(float, self.baggage.sentry_items.get("sample_rate"))
552556
lower, upper = _sample_rand_range(self.parent_sampled, sample_rate)
553557

554558
try:
@@ -564,15 +568,15 @@ def _fill_sample_rand(self):
564568
)
565569
return
566570

567-
self.dynamic_sampling_context["sample_rand"] = f"{sample_rand:.6f}" # noqa: E231
571+
self.baggage.sentry_items["sample_rand"] = f"{sample_rand:.6f}" # noqa: E231
568572

569573
def _sample_rand(self):
570574
# type: () -> Optional[str]
571-
"""Convenience method to get the sample_rand value from the dynamic_sampling_context."""
572-
if self.dynamic_sampling_context is None:
575+
"""Convenience method to get the sample_rand value from the baggage."""
576+
if self.baggage is None:
573577
return None
574578

575-
return self.dynamic_sampling_context.get("sample_rand")
579+
return self.baggage.sentry_items.get("sample_rand")
576580

577581

578582
class Baggage:

0 commit comments

Comments
 (0)