@@ -10,7 +10,11 @@ use std::{
10
10
io:: { self , IsTerminal } ,
11
11
iter:: Fuse ,
12
12
mem,
13
- sync:: Mutex ,
13
+ sync:: {
14
+ atomic:: { AtomicBool , Ordering } ,
15
+ Mutex ,
16
+ } ,
17
+ thread:: LocalKey ,
14
18
time:: Instant ,
15
19
} ;
16
20
use tracing_core:: {
@@ -463,6 +467,28 @@ where
463
467
unit = self . styled( Style :: new( ) . dimmed( ) , unit) ,
464
468
)
465
469
}
470
+
471
+ fn is_recursive ( ) -> Option < RecursiveGuard > {
472
+ thread_local ! {
473
+ pub static IS_EMPTY : AtomicBool = const { AtomicBool :: new( true ) } ;
474
+ }
475
+
476
+ IS_EMPTY . with ( |is_empty| {
477
+ is_empty
478
+ . compare_exchange ( true , false , Ordering :: Relaxed , Ordering :: Relaxed )
479
+ . ok ( )
480
+ . map ( |_| RecursiveGuard ( & IS_EMPTY ) )
481
+ } )
482
+ }
483
+ }
484
+
485
+ struct RecursiveGuard ( & ' static LocalKey < AtomicBool > ) ;
486
+
487
+ impl Drop for RecursiveGuard {
488
+ fn drop ( & mut self ) {
489
+ self . 0
490
+ . with ( |is_empty| is_empty. store ( true , Ordering :: Relaxed ) ) ;
491
+ }
466
492
}
467
493
468
494
impl < S , W , FT > Layer < S > for HierarchicalLayer < W , FT >
@@ -472,6 +498,10 @@ where
472
498
FT : FormatTime + ' static ,
473
499
{
474
500
fn on_new_span ( & self , attrs : & Attributes , id : & Id , ctx : Context < S > ) {
501
+ let Some ( _guard) = Self :: is_recursive ( ) else {
502
+ return ;
503
+ } ;
504
+
475
505
let span = ctx. span ( id) . expect ( "in new_span but span does not exist" ) ;
476
506
477
507
if span. extensions ( ) . get :: < Data > ( ) . is_none ( ) {
@@ -507,6 +537,10 @@ where
507
537
}
508
538
509
539
fn on_event ( & self , event : & Event < ' _ > , ctx : Context < S > ) {
540
+ let Some ( _guard) = Self :: is_recursive ( ) else {
541
+ return ;
542
+ } ;
543
+
510
544
let span = ctx. current_span ( ) ;
511
545
let span_id = span. id ( ) ;
512
546
let span = span_id. and_then ( |id| ctx. span ( id) ) ;
@@ -588,6 +622,10 @@ where
588
622
}
589
623
590
624
fn on_close ( & self , id : Id , ctx : Context < S > ) {
625
+ let Some ( _guard) = Self :: is_recursive ( ) else {
626
+ return ;
627
+ } ;
628
+
591
629
let bufs = & mut * self . bufs . lock ( ) . unwrap ( ) ;
592
630
593
631
let span = ctx. span ( & id) . expect ( "invalid span in on_close" ) ;
0 commit comments