@@ -264,33 +264,37 @@ impl TraceSampler {
264264 }
265265 }
266266
267- /// Main sampling pipeline - mirrors datadog-agent's runSamplers flow
268- /// Returns (keep_decision, priority, decision_maker_tag, should_add_prob_rate, root_span_index)
269- fn run_samplers ( & mut self , trace : & mut Trace ) -> ( bool , i32 , & ' static str , bool , Option < usize > ) {
267+ /// Evaluates the given trace against all configured samplers.
268+ ///
269+ /// Return a tuple containing whether or not the trace should be kept, the decision maker tag (which sampler is responsible),
270+ /// and the index of the root span used for evaluation.
271+ fn run_samplers ( & mut self , trace : & mut Trace ) -> ( bool , i32 , & ' static str , Option < usize > ) {
270272 // logic taken from: https://github.com/DataDog/datadog-agent/blob/main/pkg/trace/agent/agent.go#L1066
271273 let now = std:: time:: SystemTime :: now ( ) ;
272274 // Empty trace check
273275 if trace. spans ( ) . is_empty ( ) {
274- return ( false , PRIORITY_AUTO_DROP , "" , false , None ) ;
276+ return ( false , PRIORITY_AUTO_DROP , "" , None ) ;
275277 }
276278 let contains_error = self . trace_contains_error ( trace, false ) ;
277279 let Some ( root_span_idx) = self . get_root_span_index ( trace) else {
278- return ( false , PRIORITY_AUTO_DROP , "" , false , None ) ;
280+ return ( false , PRIORITY_AUTO_DROP , "" , None ) ;
279281 } ;
280282
281283 // Modern path: ProbabilisticSamplerEnabled = true
282284 if self . probabilistic_sampler_enabled {
283285 let mut prob_keep = false ;
284286 let mut decision_maker = "" ;
285- let mut should_add_prob_rate = false ;
286287
287288 // Run probabilistic sampler - use root span's trace ID
288-
289289 let root_trace_id = trace. spans ( ) [ root_span_idx] . trace_id ( ) ;
290290 if self . sample_probabilistic ( root_trace_id) {
291291 decision_maker = DECISION_MAKER_PROBABILISTIC ; // probabilistic sampling
292- should_add_prob_rate = true ;
293292 prob_keep = true ;
293+
294+ if let Some ( root_span) = trace. spans_mut ( ) . get_mut ( root_span_idx) {
295+ let metrics = root_span. metrics_mut ( ) ;
296+ metrics. insert ( MetaString :: from ( PROB_RATE_KEY ) , self . sampling_rate ) ;
297+ }
294298 } else if self . error_sampling_enabled && contains_error {
295299 prob_keep = self . error_sampler . sample_error ( now, trace, root_span_idx) ;
296300 }
@@ -301,58 +305,39 @@ impl TraceSampler {
301305 PRIORITY_AUTO_DROP
302306 } ;
303307
304- return (
305- prob_keep,
306- priority,
307- decision_maker,
308- should_add_prob_rate,
309- Some ( root_span_idx) ,
310- ) ;
308+ return ( prob_keep, priority, decision_maker, Some ( root_span_idx) ) ;
311309 }
312310
313311 if let Some ( user_priority) = self . get_user_priority ( trace, root_span_idx) {
314312 if user_priority > 0 {
315313 // User wants to keep this trace
316- return (
317- true ,
318- user_priority,
319- DECISION_MAKER_MANUAL_PRIORITY ,
320- false ,
321- Some ( root_span_idx) ,
322- ) ;
314+ return ( true , user_priority, DECISION_MAKER_MANUAL_PRIORITY , Some ( root_span_idx) ) ;
323315 }
324316 }
325317
326318 if self . error_sampling_enabled && self . trace_contains_error ( trace, false ) {
327319 let keep = self . error_sampler . sample_error ( now, trace, root_span_idx) ;
328320 if keep {
329- return ( true , PRIORITY_AUTO_KEEP , "" , false , Some ( root_span_idx) ) ;
321+ return ( true , PRIORITY_AUTO_KEEP , "" , Some ( root_span_idx) ) ;
330322 }
331323 }
332324
333325 // Default: drop the trace
334- ( false , PRIORITY_AUTO_DROP , "" , false , Some ( root_span_idx) )
326+ ( false , PRIORITY_AUTO_DROP , "" , Some ( root_span_idx) )
335327 }
336328
337329 /// Apply sampling metadata to the trace in-place.
338330 ///
339331 /// The `root_span_id` parameter identifies which span should receive the sampling metadata.
340332 /// This avoids recalculating the root span since it was already found in `run_samplers`.
341333 fn apply_sampling_metadata (
342- & self , trace : & mut Trace , keep : bool , priority : i32 , decision_maker : & str , add_prob_rate : bool ,
343- root_span_idx : usize ,
334+ & self , trace : & mut Trace , keep : bool , priority : i32 , decision_maker : & str , root_span_idx : usize ,
344335 ) {
345336 let root_span_value = match trace. spans_mut ( ) . get_mut ( root_span_idx) {
346337 Some ( span) => span,
347338 None => return ,
348339 } ;
349340
350- // Add the probabilistic sampling rate if requested
351- if add_prob_rate {
352- let metrics = root_span_value. metrics_mut ( ) ;
353- metrics. insert ( MetaString :: from ( PROB_RATE_KEY ) , self . sampling_rate ) ;
354- }
355-
356341 // Add tag for the decision maker
357342 let meta = root_span_value. meta_mut ( ) ;
358343 if priority > 0 && !decision_maker. is_empty ( ) {
@@ -393,18 +378,15 @@ impl Transform for TraceSampler {
393378 // keep is a boolean that indicates if the trace should be kept or dropped
394379 // priority is the sampling priority
395380 // decision_maker is the tag that indicates the decision maker (probabilistic, error, etc.)
396- // add_prob_rate is a boolean that indicates if the PROB_RATE_KEY should be added to the the root span
397381 // root_span_idx is the index of the root span of the trace
398- let ( keep, priority, decision_maker, add_prob_rate, root_span_idx) =
399- self . run_samplers( & mut trace) ;
382+ let ( keep, priority, decision_maker, root_span_idx) = self . run_samplers( & mut trace) ;
400383 if keep {
401384 if let Some ( root_idx) = root_span_idx {
402385 self . apply_sampling_metadata(
403386 & mut trace,
404387 keep,
405388 priority,
406389 decision_maker,
407- add_prob_rate,
408390 root_idx,
409391 ) ;
410392 }
@@ -629,7 +611,7 @@ mod tests {
629611 let mut trace = create_test_trace ( vec ! [ span] ) ;
630612 trace. set_sampling ( Some ( TraceSampling :: new ( false , Some ( PRIORITY_USER_KEEP ) , None , None ) ) ) ;
631613
632- let ( keep, priority, decision_maker, _, _ ) = sampler. run_samplers ( & mut trace) ;
614+ let ( keep, priority, decision_maker, _) = sampler. run_samplers ( & mut trace) ;
633615 assert ! ( keep) ;
634616 assert_eq ! ( priority, PRIORITY_USER_KEEP ) ;
635617 assert_eq ! ( decision_maker, DECISION_MAKER_MANUAL_PRIORITY ) ;
@@ -639,7 +621,7 @@ mod tests {
639621 let mut trace = create_test_trace ( vec ! [ span] ) ;
640622 trace. set_sampling ( Some ( TraceSampling :: new ( false , Some ( PRIORITY_USER_DROP ) , None , None ) ) ) ;
641623
642- let ( keep, priority, _, _, _ ) = sampler. run_samplers ( & mut trace) ;
624+ let ( keep, priority, _, _) = sampler. run_samplers ( & mut trace) ;
643625 assert ! ( !keep) ; // Should not keep when user drops
644626 assert_eq ! ( priority, PRIORITY_AUTO_DROP ) ; // Fallthrough to auto-drop
645627
@@ -648,7 +630,7 @@ mod tests {
648630 let mut trace = create_test_trace ( vec ! [ span] ) ;
649631 trace. set_sampling ( Some ( TraceSampling :: new ( false , Some ( PRIORITY_AUTO_KEEP ) , None , None ) ) ) ;
650632
651- let ( keep, priority, decision_maker, _, _ ) = sampler. run_samplers ( & mut trace) ;
633+ let ( keep, priority, decision_maker, _) = sampler. run_samplers ( & mut trace) ;
652634 assert ! ( keep) ;
653635 assert_eq ! ( priority, PRIORITY_AUTO_KEEP ) ;
654636 assert_eq ! ( decision_maker, DECISION_MAKER_MANUAL_PRIORITY ) ;
@@ -692,7 +674,7 @@ mod tests {
692674 let span_with_error = create_test_span ( u64:: MAX - 1 , 1 , 1 ) ;
693675 let mut trace = create_test_trace ( vec ! [ span_with_error] ) ;
694676
695- let ( keep, priority, decision_maker, _, _ ) = sampler. run_samplers ( & mut trace) ;
677+ let ( keep, priority, decision_maker, _) = sampler. run_samplers ( & mut trace) ;
696678 assert ! ( keep) ;
697679 assert_eq ! ( priority, PRIORITY_AUTO_KEEP ) ;
698680 assert_eq ! ( decision_maker, "" ) ; // Error sampler doesn't set decision_maker
@@ -706,7 +688,7 @@ mod tests {
706688 let span = create_test_span_with_metrics ( 12345 , 1 , metrics) ;
707689 let mut trace = create_test_trace ( vec ! [ span] ) ;
708690
709- let ( keep, priority, decision_maker, _, _ ) = sampler. run_samplers ( & mut trace) ;
691+ let ( keep, priority, decision_maker, _) = sampler. run_samplers ( & mut trace) ;
710692 assert ! ( keep) ;
711693 assert_eq ! ( priority, 2 ) ; // UserKeep
712694 assert_eq ! ( decision_maker, DECISION_MAKER_MANUAL_PRIORITY ) ; // manual decision
@@ -717,7 +699,7 @@ mod tests {
717699 let mut sampler = create_test_sampler ( ) ;
718700 let mut trace = create_test_trace ( vec ! [ ] ) ;
719701
720- let ( keep, priority, _, _, _ ) = sampler. run_samplers ( & mut trace) ;
702+ let ( keep, priority, _, _) = sampler. run_samplers ( & mut trace) ;
721703 assert ! ( !keep) ;
722704 assert_eq ! ( priority, PRIORITY_AUTO_DROP ) ;
723705 }
@@ -865,32 +847,36 @@ mod tests {
865847 ) ;
866848 let mut trace = create_test_trace ( vec ! [ root_span] ) ;
867849
868- let ( keep, priority, decision_maker, add_prob_rate , root_span_idx) = sampler. run_samplers ( & mut trace) ;
850+ let ( keep, priority, decision_maker, root_span_idx) = sampler. run_samplers ( & mut trace) ;
869851
870852 if keep && decision_maker == DECISION_MAKER_PROBABILISTIC {
871- // If sampled probabilistically, check probRateKey should be added
853+ // If sampled probabilistically, check that probRateKey was already added
872854 assert_eq ! ( priority, PRIORITY_AUTO_KEEP ) ;
873855 assert_eq ! ( decision_maker, DECISION_MAKER_PROBABILISTIC ) ; // probabilistic sampling marker
874- assert ! ( add_prob_rate) ; // Should add prob_rate_key
875856
876- // Use root span index directly
857+ // Check that the root span already has the probRateKey (it should have been added in run_samplers)
877858 let root_idx = root_span_idx. unwrap_or ( 0 ) ;
859+ let root_span = & trace. spans ( ) [ root_idx] ;
860+ assert ! ( root_span. metrics( ) . contains_key( PROB_RATE_KEY ) ) ;
861+ assert_eq ! ( * root_span. metrics( ) . get( PROB_RATE_KEY ) . unwrap( ) , 0.75 ) ;
878862
879- // Test that metadata is applied correctly
863+ // Test that apply_sampling_metadata still works correctly for other metadata
880864 let mut trace_with_metadata = trace. clone ( ) ;
881865 sampler. apply_sampling_metadata (
882866 & mut trace_with_metadata,
883867 keep,
884868 priority,
885869 decision_maker,
886- add_prob_rate,
887870 root_idx,
888871 ) ;
889872
890- // Check that the root span has the probRateKey
891- let modified_root = & trace_with_metadata. spans ( ) [ 0 ] ;
892- assert ! ( modified_root. metrics( ) . contains_key( PROB_RATE_KEY ) ) ;
893- assert_eq ! ( * modified_root. metrics( ) . get( PROB_RATE_KEY ) . unwrap( ) , 0.75 ) ;
873+ // Check that decision maker tag was added
874+ let modified_root = & trace_with_metadata. spans ( ) [ root_idx] ;
875+ assert ! ( modified_root. meta( ) . contains_key( TAG_DECISION_MAKER ) ) ;
876+ assert_eq ! (
877+ modified_root. meta( ) . get( TAG_DECISION_MAKER ) . unwrap( ) ,
878+ & MetaString :: from( DECISION_MAKER_PROBABILISTIC )
879+ ) ;
894880 }
895881 }
896882}
0 commit comments