@@ -67,7 +67,7 @@ impl Tracer {
67
67
#[ allow( clippy:: too_many_arguments) ]
68
68
fn make_sampling_decision (
69
69
& self ,
70
- parent_cx : Option < & Context > ,
70
+ parent_cx : & Context ,
71
71
trace_id : TraceId ,
72
72
name : & str ,
73
73
span_kind : & SpanKind ,
@@ -77,16 +77,22 @@ impl Tracer {
77
77
let provider = self . provider ( ) ?;
78
78
let sampler = & provider. config ( ) . default_sampler ;
79
79
80
- let sampling_result =
81
- sampler. should_sample ( parent_cx, trace_id, name, span_kind, attributes, links) ;
80
+ let sampling_result = sampler. should_sample (
81
+ Some ( parent_cx) ,
82
+ trace_id,
83
+ name,
84
+ span_kind,
85
+ attributes,
86
+ links,
87
+ ) ;
82
88
83
89
self . process_sampling_result ( sampling_result, parent_cx)
84
90
}
85
91
86
92
fn process_sampling_result (
87
93
& self ,
88
94
sampling_result : SamplingResult ,
89
- parent_cx : Option < & Context > ,
95
+ parent_cx : & Context ,
90
96
) -> Option < ( u8 , Vec < KeyValue > , TraceState ) > {
91
97
match sampling_result {
92
98
SamplingResult {
@@ -98,19 +104,15 @@ impl Tracer {
98
104
attributes,
99
105
trace_state,
100
106
} => {
101
- let trace_flags = parent_cx
102
- . map ( |ctx| ctx. span ( ) . span_context ( ) . trace_flags ( ) )
103
- . unwrap_or ( 0 ) ;
107
+ let trace_flags = parent_cx. span ( ) . span_context ( ) . trace_flags ( ) ;
104
108
Some ( ( trace_flags & !TRACE_FLAG_SAMPLED , attributes, trace_state) )
105
109
}
106
110
SamplingResult {
107
111
decision : SamplingDecision :: RecordAndSample ,
108
112
attributes,
109
113
trace_state,
110
114
} => {
111
- let trace_flags = parent_cx
112
- . map ( |ctx| ctx. span ( ) . span_context ( ) . trace_flags ( ) )
113
- . unwrap_or ( 0 ) ;
115
+ let trace_flags = parent_cx. span ( ) . span_context ( ) . trace_flags ( ) ;
114
116
Some ( ( trace_flags | TRACE_FLAG_SAMPLED , attributes, trace_state) )
115
117
}
116
118
}
@@ -174,24 +176,26 @@ impl crate::trace::Tracer for Tracer {
174
176
let mut flags = 0 ;
175
177
let mut span_trace_state = Default :: default ( ) ;
176
178
177
- let parent_cx = builder. parent_context . take ( ) . map ( |cx| {
178
- // Sampling expects to be able to access the parent span via `span` so wrap remote span
179
- // context in a wrapper span if necessary. Remote span contexts will be passed to
180
- // subsequent context's, so wrapping is only necessary if there is no active span.
181
- match cx. remote_span_context ( ) {
182
- Some ( remote_sc) if !cx. has_active_span ( ) => {
183
- cx. with_span ( Span :: new ( remote_sc. clone ( ) , None , self . clone ( ) ) )
179
+ let parent_cx = builder
180
+ . parent_context
181
+ . take ( )
182
+ . map ( |cx| {
183
+ // Sampling expects to be able to access the parent span via `span` so wrap remote span
184
+ // context in a wrapper span if necessary. Remote span contexts will be passed to
185
+ // subsequent context's, so wrapping is only necessary if there is no active span.
186
+ match cx. remote_span_context ( ) {
187
+ Some ( remote_sc) if !cx. has_active_span ( ) => {
188
+ cx. with_span ( Span :: new ( remote_sc. clone ( ) , None , self . clone ( ) ) )
189
+ }
190
+ _ => cx,
184
191
}
185
- _ => cx,
186
- }
187
- } ) ;
188
- let parent_span_context = parent_cx. as_ref ( ) . and_then ( |parent_cx| {
189
- if parent_cx. has_active_span ( ) {
190
- Some ( parent_cx. span ( ) . span_context ( ) )
191
- } else {
192
- None
193
- }
194
- } ) ;
192
+ } )
193
+ . unwrap_or_else ( Context :: current) ;
194
+ let parent_span_context = if parent_cx. has_active_span ( ) {
195
+ Some ( parent_cx. span ( ) . span_context ( ) )
196
+ } else {
197
+ None
198
+ } ;
195
199
// Build context for sampling decision
196
200
let ( no_parent, trace_id, parent_span_id, remote_parent, parent_trace_flags) =
197
201
parent_span_context
@@ -221,10 +225,10 @@ impl crate::trace::Tracer for Tracer {
221
225
// * There is no parent or a remote parent, in which case make decision now
222
226
// * There is a local parent, in which case defer to the parent's decision
223
227
let sampling_decision = if let Some ( sampling_result) = builder. sampling_result . take ( ) {
224
- self . process_sampling_result ( sampling_result, parent_cx. as_ref ( ) )
228
+ self . process_sampling_result ( sampling_result, & parent_cx)
225
229
} else if no_parent || remote_parent {
226
230
self . make_sampling_decision (
227
- parent_cx. as_ref ( ) ,
231
+ & parent_cx,
228
232
trace_id,
229
233
& builder. name ,
230
234
& span_kind,
@@ -288,7 +292,7 @@ impl crate::trace::Tracer for Tracer {
288
292
289
293
// Call `on_start` for all processors
290
294
for processor in provider. span_processors ( ) {
291
- processor. on_start ( & span, parent_cx . as_ref ( ) . unwrap_or ( & Context :: new ( ) ) )
295
+ processor. on_start ( & span, & parent_cx )
292
296
}
293
297
294
298
span
@@ -377,4 +381,19 @@ mod tests {
377
381
378
382
assert ! ( !span. span_context( ) . is_sampled( ) ) ;
379
383
}
384
+
385
+ #[ test]
386
+ fn uses_current_context_for_builders_if_unset ( ) {
387
+ let sampler = Sampler :: ParentBased ( Box :: new ( Sampler :: AlwaysOn ) ) ;
388
+ let config = Config :: default ( ) . with_default_sampler ( sampler) ;
389
+ let tracer_provider = sdk:: trace:: TracerProvider :: builder ( )
390
+ . with_config ( config)
391
+ . build ( ) ;
392
+
393
+ let _attached = Context :: current_with_span ( TestSpan ( SpanContext :: empty_context ( ) ) ) . attach ( ) ;
394
+ let tracer = tracer_provider. get_tracer ( "test" , None ) ;
395
+ let span = tracer. span_builder ( "must_not_be_sampled" ) . start ( & tracer) ;
396
+
397
+ assert ! ( !span. span_context( ) . is_sampled( ) ) ;
398
+ }
380
399
}
0 commit comments