Skip to content

Commit cefb27c

Browse files
committed
reword and support parent_sampled
1 parent 1d77484 commit cefb27c

File tree

5 files changed

+24
-14
lines changed

5 files changed

+24
-14
lines changed

MIGRATION_GUIDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh
1111
- The SDK now supports Python 3.7 and higher.
1212
- `sentry_sdk.start_span` now only takes keyword arguments.
1313
- `sentry_sdk.start_span` no longer takes an explicit `span` argument.
14-
- `sentry_sdk.start_span` now accepts the `sampled` argument. It is however taken into account for root spans (previously known as transactions).
14+
- `sentry_sdk.start_span` now accepts the `sampled` argument. It is however only taken into account for root spans (previously known as transactions).
1515
- The `Span()` constructor does not accept a `hub` parameter anymore.
1616
- `Span.finish()` does not accept a `hub` parameter anymore.
1717
- The `Profile()` constructor does not accept a `hub` parameter anymore.

sentry_sdk/integrations/opentelemetry/consts.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,6 @@ class SentrySpanAttribute:
3131
SOURCE = "sentry.source"
3232
CONTEXT = "sentry.context"
3333
CUSTOM_SAMPLED = "sentry.custom_sampled" # used for saving start_span(sampled=X)
34+
CUSTOM_PARENT_SAMPLED = (
35+
"sentry.custom_parent_sampled" # used for saving start_span(parent_sampled=X)
36+
)

sentry_sdk/integrations/opentelemetry/sampler.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,11 @@ def should_sample(
154154

155155
else:
156156
# Check if there is a parent with a sampling decision
157-
parent_sampled = get_parent_sampled(parent_span_context, trace_id)
157+
parent_sampled = attributes.get(SentrySpanAttribute.CUSTOM_PARENT_SAMPLED)
158+
159+
if parent_sampled is None:
160+
parent_sampled = get_parent_sampled(parent_span_context, trace_id)
161+
158162
if parent_sampled is not None:
159163
sample_rate = parent_sampled
160164
else:

sentry_sdk/tracing.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,7 @@ def __init__(
12121212
attributes=None, # type: OTelSpanAttributes
12131213
only_if_parent=False, # type: bool
12141214
otel_span=None, # type: Optional[OtelSpan]
1215+
parent_sampled=None, # type: Optional[bool]
12151216
**_, # type: dict[str, object]
12161217
):
12171218
# type: (...) -> None
@@ -1252,6 +1253,10 @@ def __init__(
12521253
attributes[SentrySpanAttribute.OP] = op
12531254
if sampled is not None:
12541255
attributes[SentrySpanAttribute.CUSTOM_SAMPLED] = sampled
1256+
if parent_sampled is not None:
1257+
attributes[SentrySpanAttribute.CUSTOM_PARENT_SAMPLED] = (
1258+
parent_sampled
1259+
)
12551260

12561261
self._otel_span = tracer.start_span(
12571262
span_name, start_time=start_timestamp, attributes=attributes

tests/tracing/test_sampling.py

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,16 @@ def test_sampling_decided_only_for_transactions(sentry_init, capture_events):
2424

2525

2626
@pytest.mark.parametrize("sampled", [True, False])
27-
def test_nested_transaction_sampling_override(sentry_init, sampled):
27+
def test_nested_span_sampling_override(sentry_init, sampled):
2828
sentry_init(traces_sample_rate=1.0)
2929

30-
with start_transaction(name="outer", sampled=sampled) as outer_transaction:
31-
assert outer_transaction.sampled is sampled
32-
with start_transaction(
33-
name="inner", sampled=(not sampled)
34-
) as inner_transaction:
35-
assert inner_transaction.sampled is not sampled
36-
assert outer_transaction.sampled is sampled
30+
with start_span(name="outer", sampled=sampled) as outer_span:
31+
assert outer_span.sampled is sampled
32+
with start_span(name="inner", sampled=(not sampled)) as inner_span:
33+
# won't work because the child span inherits the sampling decision
34+
# from the parent
35+
assert inner_span.sampled is sampled
36+
assert outer_span.sampled is sampled
3737

3838

3939
def test_no_double_sampling(sentry_init, capture_events):
@@ -177,10 +177,8 @@ def test_inherits_parent_sampling_decision_when_traces_sampler_undefined(
177177
mock_random_value = 0.25 if parent_sampling_decision is False else 0.75
178178

179179
with mock.patch.object(random, "random", return_value=mock_random_value):
180-
transaction = start_transaction(
181-
name="dogpark", parent_sampled=parent_sampling_decision
182-
)
183-
assert transaction.sampled is parent_sampling_decision
180+
span = start_span(name="dogpark", parent_sampled=parent_sampling_decision)
181+
assert span.sampled is parent_sampling_decision
184182

185183

186184
@pytest.mark.parametrize("parent_sampling_decision", [True, False])

0 commit comments

Comments
 (0)