Skip to content

Commit 8a94824

Browse files
committed
do not override if using parent sampled
1 parent f66429d commit 8a94824

File tree

1 file changed

+35
-20
lines changed

1 file changed

+35
-20
lines changed

sentry_sdk/integrations/opentelemetry/sampler.py

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -50,31 +50,33 @@ def get_parent_sampled(parent_context, trace_id):
5050
return None
5151

5252

53+
def _update_sample_rate(sample_rate: float, trace_state: TraceState) -> TraceState:
54+
if TRACESTATE_SAMPLE_RATE_KEY in trace_state:
55+
trace_state = trace_state.update(TRACESTATE_SAMPLE_RATE_KEY, str(sample_rate))
56+
else:
57+
trace_state = trace_state.add(TRACESTATE_SAMPLE_RATE_KEY, str(sample_rate))
58+
59+
return trace_state
60+
61+
5362
def dropped_result(parent_span_context, attributes, sample_rate=None):
5463
# type: (SpanContext, Attributes, Optional[float]) -> SamplingResult
5564
# these will only be added the first time in a root span sampling decision
65+
# if sample_rate is provided, it'll be updated in trace state
5666
trace_state = parent_span_context.trace_state
5767

5868
if TRACESTATE_SAMPLED_KEY not in trace_state:
5969
trace_state = trace_state.add(TRACESTATE_SAMPLED_KEY, "false")
6070
elif trace_state.get(TRACESTATE_SAMPLED_KEY) == "deferred":
6171
trace_state = trace_state.update(TRACESTATE_SAMPLED_KEY, "false")
6272

73+
if sample_rate is not None:
74+
trace_state = _update_sample_rate(sample_rate, trace_state)
75+
6376
is_root_span = not (
6477
parent_span_context.is_valid and not parent_span_context.is_remote
6578
)
6679
if is_root_span:
67-
# Update the sample rate in the trace state
68-
if sample_rate is not None:
69-
if TRACESTATE_SAMPLE_RATE_KEY in trace_state:
70-
trace_state = trace_state.update(
71-
TRACESTATE_SAMPLE_RATE_KEY, str(sample_rate)
72-
)
73-
else:
74-
trace_state = trace_state.add(
75-
TRACESTATE_SAMPLE_RATE_KEY, str(sample_rate)
76-
)
77-
7880
# Tell Sentry why we dropped the transaction/root-span
7981
client = sentry_sdk.get_client()
8082
if client.monitor and client.monitor.downsample_factor > 0:
@@ -96,19 +98,18 @@ def dropped_result(parent_span_context, attributes, sample_rate=None):
9698

9799

98100
def sampled_result(span_context, attributes, sample_rate):
99-
# type: (SpanContext, Attributes, float) -> SamplingResult
101+
# type: (SpanContext, Attributes, Optional[float]) -> SamplingResult
100102
# these will only be added the first time in a root span sampling decision
103+
# if sample_rate is provided, it'll be updated in trace state
101104
trace_state = span_context.trace_state
102105

103106
if TRACESTATE_SAMPLED_KEY not in trace_state:
104107
trace_state = trace_state.add(TRACESTATE_SAMPLED_KEY, "true")
105108
elif trace_state.get(TRACESTATE_SAMPLED_KEY) == "deferred":
106109
trace_state = trace_state.update(TRACESTATE_SAMPLED_KEY, "true")
107110

108-
if TRACESTATE_SAMPLE_RATE_KEY in trace_state:
109-
trace_state = trace_state.update(TRACESTATE_SAMPLE_RATE_KEY, str(sample_rate))
110-
else:
111-
trace_state = trace_state.add(TRACESTATE_SAMPLE_RATE_KEY, str(sample_rate))
111+
if sample_rate is not None:
112+
trace_state = _update_sample_rate(sample_rate, trace_state)
112113

113114
return SamplingResult(
114115
Decision.RECORD_AND_SAMPLE,
@@ -152,9 +153,13 @@ def should_sample(
152153
if is_root_span:
153154
sample_rate = float(custom_sampled)
154155
if sample_rate > 0:
155-
return sampled_result(parent_span_context, attributes, sample_rate)
156+
return sampled_result(
157+
parent_span_context, attributes, sample_rate=sample_rate
158+
)
156159
else:
157-
return dropped_result(parent_span_context, attributes, sample_rate)
160+
return dropped_result(
161+
parent_span_context, attributes, sample_rate=sample_rate
162+
)
158163
else:
159164
logger.debug(
160165
f"[Tracing] Ignoring sampled param for non-root span {name}"
@@ -163,6 +168,7 @@ def should_sample(
163168
# Check if there is a traces_sampler
164169
# Traces_sampler is responsible to check parent sampled to have full transactions.
165170
has_traces_sampler = callable(client.options.get("traces_sampler"))
171+
inherited_parent_sampled = False
166172

167173
if is_root_span and has_traces_sampler:
168174
sampling_context = create_sampling_context(
@@ -174,6 +180,7 @@ def should_sample(
174180
parent_sampled = get_parent_sampled(parent_span_context, trace_id)
175181
if parent_sampled is not None:
176182
sample_rate = parent_sampled
183+
inherited_parent_sampled = True
177184
else:
178185
# Check if there is a traces_sample_rate
179186
sample_rate = client.options.get("traces_sample_rate")
@@ -194,9 +201,17 @@ def should_sample(
194201
sampled = random.random() < sample_rate
195202

196203
if sampled:
197-
return sampled_result(parent_span_context, attributes, sample_rate)
204+
return sampled_result(
205+
parent_span_context,
206+
attributes,
207+
sample_rate=sample_rate if not inherited_parent_sampled else None,
208+
)
198209
else:
199-
return dropped_result(parent_span_context, attributes, sample_rate)
210+
return dropped_result(
211+
parent_span_context,
212+
attributes,
213+
sample_rate=sample_rate if not inherited_parent_sampled else None,
214+
)
200215

201216
def get_description(self) -> str:
202217
return self.__class__.__name__

0 commit comments

Comments
 (0)