@@ -2,7 +2,7 @@ pub(crate) mod format;
2
2
3
3
use ansi_term:: { Color , Style } ;
4
4
use chrono:: { DateTime , Local } ;
5
- use format:: { Buffers , ColorLevel , Config , FmtEvent } ;
5
+ use format:: { Buffers , ColorLevel , Config , FmtEvent , SpanMode } ;
6
6
use std:: {
7
7
fmt:: { self , Write as _} ,
8
8
io,
@@ -149,6 +149,26 @@ where
149
149
}
150
150
}
151
151
152
+ /// Whether to print the currently active span's message again before entering a new span.
153
+ /// This helps if the entry to the current span was quite a while back (and with scrolling
154
+ /// upwards in logs).
155
+ pub fn with_verbose_entry ( self , verbose_entry : bool ) -> Self {
156
+ Self {
157
+ config : self . config . with_verbose_entry ( verbose_entry) ,
158
+ ..self
159
+ }
160
+ }
161
+
162
+ /// Whether to print the currently active span's message again before dropping it.
163
+ /// This helps if the entry to the current span was quite a while back (and with scrolling
164
+ /// upwards in logs).
165
+ pub fn with_verbose_exit ( self , verbose_exit : bool ) -> Self {
166
+ Self {
167
+ config : self . config . with_verbose_exit ( verbose_exit) ,
168
+ ..self
169
+ }
170
+ }
171
+
152
172
fn styled ( & self , style : Style , text : impl AsRef < str > ) -> String {
153
173
if self . config . ansi {
154
174
style. paint ( text. as_ref ( ) ) . to_string ( )
@@ -177,29 +197,30 @@ where
177
197
}
178
198
Ok ( ( ) )
179
199
}
180
- }
181
200
182
- impl < S , W > Layer < S > for HierarchicalLayer < W >
183
- where
184
- S : Subscriber + for < ' span > LookupSpan < ' span > + fmt:: Debug ,
185
- W : MakeWriter + ' static ,
186
- {
187
- fn new_span ( & self , attrs : & Attributes , id : & Id , ctx : Context < S > ) {
188
- let data = Data :: new ( attrs) ;
189
- let span = ctx. span ( id) . expect ( "in new_span but span does not exist" ) ;
190
- span. extensions_mut ( ) . insert ( data) ;
191
- }
192
-
193
- fn on_enter ( & self , id : & tracing:: Id , ctx : Context < S > ) {
194
- let span = ctx. span ( & id) . expect ( "in on_enter but span does not exist" ) ;
201
+ fn write_span_info < S : Subscriber + for < ' span > LookupSpan < ' span > + fmt:: Debug > (
202
+ & self ,
203
+ id : & tracing:: Id ,
204
+ ctx : & Context < S > ,
205
+ entering : bool ,
206
+ style : SpanMode ,
207
+ ) {
208
+ let span = ctx
209
+ . span ( & id)
210
+ . expect ( "in on_enter/on_exit but span does not exist" ) ;
195
211
let ext = span. extensions ( ) ;
196
212
let data = ext. get :: < Data > ( ) . expect ( "span does not have data" ) ;
197
213
198
214
let mut guard = self . bufs . lock ( ) . unwrap ( ) ;
199
215
let bufs = & mut * guard;
200
216
let mut current_buf = & mut bufs. current_buf ;
201
217
202
- let indent = ctx. scope ( ) . count ( ) . saturating_sub ( 1 ) ;
218
+ let indent = ctx. scope ( ) . count ( ) ;
219
+ let indent = if entering {
220
+ indent. saturating_sub ( 1 )
221
+ } else {
222
+ indent
223
+ } ;
203
224
204
225
if self . config . targets {
205
226
let target = span. metadata ( ) . target ( ) ;
@@ -232,10 +253,47 @@ where
232
253
)
233
254
. unwrap ( ) ;
234
255
235
- bufs. indent_current ( indent, & self . config ) ;
256
+ bufs. indent_current ( indent, & self . config , style ) ;
236
257
let writer = self . make_writer . make_writer ( ) ;
237
258
bufs. flush_current_buf ( writer)
238
259
}
260
+ }
261
+
262
+ impl < S , W > Layer < S > for HierarchicalLayer < W >
263
+ where
264
+ S : Subscriber + for < ' span > LookupSpan < ' span > + fmt:: Debug ,
265
+ W : MakeWriter + ' static ,
266
+ {
267
+ fn new_span ( & self , attrs : & Attributes , id : & Id , ctx : Context < S > ) {
268
+ let data = Data :: new ( attrs) ;
269
+ let span = ctx. span ( id) . expect ( "in new_span but span does not exist" ) ;
270
+ span. extensions_mut ( ) . insert ( data) ;
271
+ }
272
+
273
+ fn on_enter ( & self , id : & tracing:: Id , ctx : Context < S > ) {
274
+ let mut iter = ctx. scope ( ) ;
275
+ let mut prev = iter. next ( ) ;
276
+ let mut cur = iter. next ( ) ;
277
+ loop {
278
+ match ( prev, cur) {
279
+ ( Some ( span) , Some ( cur_elem) ) => {
280
+ if let Some ( next) = iter. next ( ) {
281
+ prev = Some ( cur_elem) ;
282
+ cur = Some ( next) ;
283
+ } else {
284
+ self . write_span_info ( & span. id ( ) , & ctx, false , SpanMode :: PreOpen ) ;
285
+ break ;
286
+ }
287
+ }
288
+ // Iterator is not sealed, so we need to catch this case.
289
+ ( None , Some ( _) ) => break ,
290
+ // Just the new span on the stack
291
+ ( Some ( _) , None ) => break ,
292
+ ( None , None ) => unreachable ! ( "just entered span must exist" ) ,
293
+ }
294
+ }
295
+ self . write_span_info ( id, & ctx, false , SpanMode :: Open ) ;
296
+ }
239
297
240
298
fn on_event ( & self , event : & Event < ' _ > , ctx : Context < S > ) {
241
299
let mut guard = self . bufs . lock ( ) . unwrap ( ) ;
@@ -303,10 +361,19 @@ where
303
361
bufs : & mut bufs,
304
362
} ;
305
363
event. record ( & mut visitor) ;
306
- visitor. bufs . indent_current ( indent, & self . config ) ;
364
+ visitor
365
+ . bufs
366
+ . indent_current ( indent, & self . config , SpanMode :: Event ) ;
307
367
let writer = self . make_writer . make_writer ( ) ;
308
368
bufs. flush_current_buf ( writer)
309
369
}
310
370
311
- fn on_exit ( & self , _id : & Id , _ctx : Context < S > ) { }
371
+ fn on_exit ( & self , id : & Id , ctx : Context < S > ) {
372
+ if self . config . verbose_exit {
373
+ self . write_span_info ( id, & ctx, false , SpanMode :: Close ) ;
374
+ if let Some ( span) = ctx. scope ( ) . last ( ) {
375
+ self . write_span_info ( & span. id ( ) , & ctx, false , SpanMode :: PostClose ) ;
376
+ }
377
+ }
378
+ }
312
379
}
0 commit comments