11use crate :: TracingExtension ;
22use protocol:: { Event , Instant , Labels , Span } ;
33use std:: borrow:: Cow ;
4+ use std:: cell:: Cell ;
45use std:: sync:: Arc ;
56use thread_local:: ThreadLocal ;
67use tracing:: { Id , Subscriber } ;
78use tracing_subscriber:: layer:: { Context , Layer } ;
89use tracing_subscriber:: registry:: LookupSpan ;
910
11+ thread_local ! {
12+ static IN_TRACING : Cell <bool > = const { Cell :: new( false ) } ;
13+ }
14+
15+ struct ReentrancyGuard ;
16+
17+ impl ReentrancyGuard {
18+ fn new ( ) -> Option < Self > {
19+ IN_TRACING . with ( |in_tracing| {
20+ if in_tracing. get ( ) {
21+ None
22+ } else {
23+ in_tracing. set ( true ) ;
24+ Some ( ReentrancyGuard )
25+ }
26+ } )
27+ }
28+ }
29+
30+ impl Drop for ReentrancyGuard {
31+ fn drop ( & mut self ) {
32+ IN_TRACING . with ( |in_tracing| {
33+ in_tracing. set ( false ) ;
34+ } ) ;
35+ }
36+ }
37+
1038pub ( crate ) struct SpanData {
1139 pub labels : Labels < ' static > ,
1240 pub start_timestamp : u64 ,
6290 S : Subscriber + for < ' a > LookupSpan < ' a > ,
6391{
6492 fn on_new_span ( & self , attrs : & tracing:: span:: Attributes < ' _ > , id : & Id , ctx : Context < ' _ , S > ) {
93+ let _guard = match ReentrancyGuard :: new ( ) {
94+ Some ( guard) => guard,
95+ None => {
96+ eprintln ! (
97+ "tracing-manytrace: reentrancy detected in on_new_span name={} location={}:{}" ,
98+ attrs. metadata( ) . name( ) ,
99+ attrs. metadata( ) . file( ) . unwrap_or( "<unknown>" ) ,
100+ attrs. metadata( ) . line( ) . unwrap_or( 0 )
101+ ) ;
102+ return ;
103+ }
104+ } ;
105+
65106 if !self . extension . is_active ( ) {
66107 return ;
67108 }
@@ -86,6 +127,26 @@ where
86127 }
87128
88129 fn on_enter ( & self , id : & Id , ctx : Context < ' _ , S > ) {
130+ let _guard = match ReentrancyGuard :: new ( ) {
131+ Some ( guard) => guard,
132+ None => {
133+ if let Some ( span) = ctx. span ( id) {
134+ eprintln ! (
135+ "tracing-manytrace: reentrancy detected in on_enter name={} location={}:{}" ,
136+ span. metadata( ) . name( ) ,
137+ span. metadata( ) . file( ) . unwrap_or( "<unknown>" ) ,
138+ span. metadata( ) . line( ) . unwrap_or( 0 )
139+ ) ;
140+ } else {
141+ eprintln ! (
142+ "tracing-manytrace: reentrancy detected in on_enter span_id={:?}" ,
143+ id
144+ ) ;
145+ }
146+ return ;
147+ }
148+ } ;
149+
89150 if !self . extension . is_active ( ) {
90151 return ;
91152 }
@@ -98,6 +159,26 @@ where
98159 }
99160
100161 fn on_exit ( & self , id : & Id , ctx : Context < ' _ , S > ) {
162+ let _guard = match ReentrancyGuard :: new ( ) {
163+ Some ( guard) => guard,
164+ None => {
165+ if let Some ( span) = ctx. span ( id) {
166+ eprintln ! (
167+ "tracing-manytrace: reentrancy detected in on_exit name={} location={}:{}" ,
168+ span. metadata( ) . name( ) ,
169+ span. metadata( ) . file( ) . unwrap_or( "<unknown>" ) ,
170+ span. metadata( ) . line( ) . unwrap_or( 0 )
171+ ) ;
172+ } else {
173+ eprintln ! (
174+ "tracing-manytrace: reentrancy detected in on_exit span_id={:?}" ,
175+ id
176+ ) ;
177+ }
178+ return ;
179+ }
180+ } ;
181+
101182 if !self . extension . is_active ( ) {
102183 return ;
103184 }
@@ -121,6 +202,19 @@ where
121202 }
122203
123204 fn on_event ( & self , event : & tracing:: Event < ' _ > , ctx : Context < ' _ , S > ) {
205+ let _guard = match ReentrancyGuard :: new ( ) {
206+ Some ( guard) => guard,
207+ None => {
208+ eprintln ! (
209+ "tracing-manytrace: reentrancy detected in on_event name={} location={}:{}" ,
210+ event. metadata( ) . name( ) ,
211+ event. metadata( ) . file( ) . unwrap_or( "<unknown>" ) ,
212+ event. metadata( ) . line( ) . unwrap_or( 0 )
213+ ) ;
214+ return ;
215+ }
216+ } ;
217+
124218 if !self . extension . is_active ( ) {
125219 return ;
126220 }
0 commit comments