Skip to content

Commit fd78adf

Browse files
committed
ref: Add support for custom sampling context to span first
1 parent c614249 commit fd78adf

3 files changed

Lines changed: 74 additions & 0 deletions

File tree

sentry_sdk/scope.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,13 @@ def get_active_propagation_context(self) -> "PropagationContext":
696696
isolation_scope._propagation_context = PropagationContext()
697697
return isolation_scope._propagation_context
698698

699+
def set_custom_sampling_context(
700+
self, custom_sampling_context: "dict[str, Any]"
701+
) -> None:
702+
self.get_active_propagation_context()._set_custom_sampling_context(
703+
custom_sampling_context
704+
)
705+
699706
def clear(self) -> None:
700707
"""Clears the entire scope."""
701708
self._level: "Optional[LogLevelStr]" = None

sentry_sdk/tracing_utils.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ class PropagationContext:
417417
"parent_span_id",
418418
"parent_sampled",
419419
"baggage",
420+
"custom_sampling_context",
420421
)
421422

422423
def __init__(
@@ -450,6 +451,8 @@ def __init__(
450451
if baggage is None and dynamic_sampling_context is not None:
451452
self.baggage = Baggage(dynamic_sampling_context)
452453

454+
self.custom_sampling_context: "Optional[dict[str, Any]]" = None
455+
453456
@classmethod
454457
def from_incoming_data(
455458
cls, incoming_data: "Dict[str, Any]"
@@ -537,6 +540,11 @@ def update(self, other_dict: "Dict[str, Any]") -> None:
537540
except AttributeError:
538541
pass
539542

543+
def _set_custom_sampling_context(
544+
self, custom_sampling_context: "dict[str, Any]"
545+
) -> None:
546+
self.custom_sampling_context = custom_sampling_context
547+
540548
def __repr__(self) -> str:
541549
return "<PropagationContext _trace_id={} _span_id={} parent_span_id={} parent_sampled={} baggage={}>".format(
542550
self._trace_id,
@@ -1420,6 +1428,9 @@ def _make_sampling_decision(
14201428
"attributes": dict(attributes) if attributes else {},
14211429
}
14221430

1431+
if propagation_context.custom_sampling_context:
1432+
sampling_context.update(propagation_context.custom_sampling_context)
1433+
14231434
sample_rate = client.options["traces_sampler"](sampling_context)
14241435
else:
14251436
if propagation_context.parent_sampled is not None:

tests/tracing/test_span_streaming.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,62 @@ def traces_sampler(sampling_context):
233233
assert len(spans) == 1
234234

235235

236+
def test_custom_sampling_context(sentry_init):
237+
class MyClass: ...
238+
239+
my_class = MyClass()
240+
241+
def traces_sampler(sampling_context):
242+
assert "class" in sampling_context
243+
assert "string" in sampling_context
244+
assert sampling_context["class"] == my_class
245+
assert sampling_context["string"] == "my string"
246+
return 1.0
247+
248+
sentry_init(
249+
traces_sampler=traces_sampler,
250+
_experiments={"trace_lifecycle": "stream"},
251+
)
252+
253+
sentry_sdk.get_current_scope().set_custom_sampling_context(
254+
{
255+
"class": my_class,
256+
"string": "my string",
257+
}
258+
)
259+
260+
with sentry_sdk.traces.start_span(name="span"):
261+
...
262+
263+
264+
def test_new_custom_sampling_context(sentry_init):
265+
def traces_sampler(sampling_context):
266+
if sampling_context["attributes"]["first"] is True:
267+
assert sampling_context["custom_value"] == 1
268+
else:
269+
assert sampling_context["custom_value"] == 2
270+
return 1.0
271+
272+
sentry_init(
273+
traces_sampler=traces_sampler,
274+
_experiments={"trace_lifecycle": "stream"},
275+
)
276+
277+
sentry_sdk.traces.new_trace()
278+
279+
sentry_sdk.get_current_scope().set_custom_sampling_context({"custom_value": 1})
280+
281+
with sentry_sdk.traces.start_span(name="span", attributes={"first": True}):
282+
...
283+
284+
sentry_sdk.traces.new_trace()
285+
286+
sentry_sdk.get_current_scope().set_custom_sampling_context({"custom_value": 2})
287+
288+
with sentry_sdk.traces.start_span(name="span", attributes={"first": False}):
289+
...
290+
291+
236292
def test_span_attributes(sentry_init, capture_envelopes):
237293
sentry_init(
238294
traces_sample_rate=1.0,

0 commit comments

Comments
 (0)