@@ -50,6 +50,19 @@ def get_parent_sampled(parent_context, trace_id):
50
50
return None
51
51
52
52
53
+ def get_parent_sample_rate (parent_context , trace_id ):
54
+ # type: (Optional[SpanContext], int) -> Optional[bool]
55
+ if parent_context is None :
56
+ return None
57
+
58
+ is_span_context_valid = parent_context is not None and parent_context .is_valid
59
+
60
+ if is_span_context_valid and parent_context .trace_id == trace_id :
61
+ return parent_context .trace_state .get (TRACESTATE_SAMPLE_RATE_KEY )
62
+
63
+ return None
64
+
65
+
53
66
def _update_sample_rate (sample_rate : float , trace_state : TraceState ) -> TraceState :
54
67
if TRACESTATE_SAMPLE_RATE_KEY in trace_state :
55
68
trace_state = trace_state .update (TRACESTATE_SAMPLE_RATE_KEY , str (sample_rate ))
@@ -168,22 +181,26 @@ def should_sample(
168
181
# Check if there is a traces_sampler
169
182
# Traces_sampler is responsible to check parent sampled to have full transactions.
170
183
has_traces_sampler = callable (client .options .get ("traces_sampler" ))
171
- inherited_parent_sampled = False
184
+
185
+ sample_rate_to_propagate = None
172
186
173
187
if is_root_span and has_traces_sampler :
174
188
sampling_context = create_sampling_context (
175
189
name , attributes , parent_span_context , trace_id
176
190
)
177
191
sample_rate = client .options ["traces_sampler" ](sampling_context )
192
+ sample_rate_to_propagate = sample_rate
178
193
else :
179
194
# Check if there is a parent with a sampling decision
180
195
parent_sampled = get_parent_sampled (parent_span_context , trace_id )
196
+ parent_sample_rate = get_parent_sample_rate (parent_span_context , trace_id )
181
197
if parent_sampled is not None :
182
- sample_rate = parent_sampled
183
- inherited_parent_sampled = True
198
+ sample_rate = bool ( parent_sampled )
199
+ sample_rate_to_propagate = parent_sample_rate
184
200
else :
185
201
# Check if there is a traces_sample_rate
186
202
sample_rate = client .options .get ("traces_sample_rate" )
203
+ sample_rate_to_propagate = sample_rate
187
204
188
205
# If the sample rate is invalid, drop the span
189
206
if not is_valid_sample_rate (sample_rate , source = self .__class__ .__name__ ):
@@ -195,22 +212,20 @@ def should_sample(
195
212
# Down-sample in case of back pressure monitor says so
196
213
if is_root_span and client .monitor :
197
214
sample_rate /= 2 ** client .monitor .downsample_factor
215
+ if client .monitor .downsample_factor > 0 :
216
+ sample_rate_to_propagate = sample_rate
198
217
199
218
# Roll the dice on sample rate
200
219
sample_rate = float (cast ("Union[bool, float, int]" , sample_rate ))
201
220
sampled = random .random () < sample_rate
202
221
203
222
if sampled :
204
223
return sampled_result (
205
- parent_span_context ,
206
- attributes ,
207
- sample_rate = sample_rate if not inherited_parent_sampled else None ,
224
+ parent_span_context , attributes , sample_rate = sample_rate_to_propagate
208
225
)
209
226
else :
210
227
return dropped_result (
211
- parent_span_context ,
212
- attributes ,
213
- sample_rate = sample_rate if not inherited_parent_sampled else None ,
228
+ parent_span_context , attributes , sample_rate = sample_rate_to_propagate
214
229
)
215
230
216
231
def get_description (self ) -> str :
0 commit comments