Skip to content

Commit c80a6b8

Browse files
committed
fix: print any span outside the context of current span
Retracing may print parent spans leading up to the current span. The indent was always formatted as the depth of the subscribers *current_span* which is not connect for spans in the middle of the tree. This fixes this issue
1 parent cc504ce commit c80a6b8

File tree

4 files changed

+82
-64
lines changed

4 files changed

+82
-64
lines changed

examples/basic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ fn main() {
1010
.with_thread_names(true)
1111
.with_thread_ids(true)
1212
.with_verbose_exit(true)
13-
.with_verbose_entry(false)
13+
.with_verbose_entry(true)
1414
.with_span_modes(true)
1515
.with_targets(true);
1616

examples/concurrent.rs

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ fn main() {
1919
.with_verbose_exit(true)
2020
.with_verbose_entry(true)
2121
.with_verbose_retrace(true)
22-
.with_deferred_spans(true)
22+
.with_deferred_spans(false)
23+
.with_span_modes(true)
2324
.with_targets(true);
2425

2526
let subscriber = Registry::default().with(layer);
@@ -47,32 +48,34 @@ fn main() {
4748
});
4849

4950
debug!("starting countdowns");
50-
debug_span!("countdowns").in_scope(|| {
51-
let mut countdown_a = CountdownFuture {
52-
label: "a",
53-
count: 3,
54-
}
55-
.instrument(span!(Level::DEBUG, "countdown_a"))
56-
.fuse();
57-
58-
let mut countdown_b = CountdownFuture {
59-
label: "b",
60-
count: 5,
61-
}
62-
.instrument(span!(Level::DEBUG, "countdown_b"))
63-
.fuse();
64-
65-
// We don't care if the futures are ready, as we poll manually
66-
let waker = futures::task::noop_waker();
67-
let mut cx = Context::from_waker(&waker);
68-
69-
let _ = countdown_a.poll_unpin(&mut cx);
70-
let _ = countdown_b.poll_unpin(&mut cx);
71-
72-
std::thread::sleep(std::time::Duration::from_millis(300));
73-
74-
let _ = countdown_b.poll_unpin(&mut cx);
75-
});
51+
debug_span!("countdowns").in_scope(
52+
|| {
53+
let mut countdown_a = CountdownFuture {
54+
label: "a",
55+
count: 3,
56+
}
57+
.instrument(span!(Level::DEBUG, "countdown_a"))
58+
.fuse();
59+
60+
let mut countdown_b = CountdownFuture {
61+
label: "b",
62+
count: 5,
63+
}
64+
.instrument(span!(Level::DEBUG, "countdown_b"))
65+
.fuse();
66+
67+
// We don't care if the futures are ready, as we poll manually
68+
let waker = futures::task::noop_waker();
69+
let mut cx = Context::from_waker(&waker);
70+
71+
let _ = countdown_a.poll_unpin(&mut cx);
72+
let _ = countdown_b.poll_unpin(&mut cx);
73+
74+
std::thread::sleep(std::time::Duration::from_millis(300));
75+
76+
let _ = countdown_b.poll_unpin(&mut cx);
77+
}, //
78+
);
7679

7780
tracing::info!("finished countdowns");
7881

src/format.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ fn indent_block_with_lines(
332332
style: SpanMode,
333333
) {
334334
let indent_spaces = indent * indent_amount;
335+
335336
if lines.is_empty() {
336337
return;
337338
} else if indent_spaces == 0 {
@@ -343,7 +344,12 @@ fn indent_block_with_lines(
343344
SpanMode::Open { .. } => buf.push_str(LINE_OPEN),
344345
SpanMode::Retrace { .. } => buf.push_str("*"),
345346
SpanMode::Close { .. } => buf.push_str(LINE_CLOSE),
346-
SpanMode::PreOpen | SpanMode::PostClose => {}
347+
SpanMode::PreOpen | SpanMode::PostClose => {
348+
unreachable!(
349+
"indent_amount: {} {}, style: {:?}",
350+
indent_amount, indent, style
351+
)
352+
}
347353
SpanMode::Event => {}
348354
}
349355
}
@@ -352,6 +358,7 @@ fn indent_block_with_lines(
352358
}
353359
return;
354360
}
361+
355362
let mut s = String::with_capacity(indent_spaces + prefix.len());
356363
s.push_str(prefix);
357364

@@ -383,7 +390,7 @@ fn indent_block_with_lines(
383390
}
384391
buf.push_str(LINE_OPEN);
385392
}
386-
SpanMode::Open { verbose: true } | SpanMode::Retrace { verbose: true } => {
393+
SpanMode::Open { verbose: true } => {
387394
buf.push_str(LINE_VERT);
388395
for _ in 1..(indent_amount / 2) {
389396
buf.push(' ');
@@ -402,6 +409,13 @@ fn indent_block_with_lines(
402409
buf.push_str(LINE_VERT);
403410
}
404411
}
412+
SpanMode::Retrace { verbose: true } => {
413+
buf.push_str(LINE_BRANCH);
414+
for _ in 1..indent_amount {
415+
buf.push_str(LINE_HORIZ);
416+
}
417+
buf.push_str(LINE_OPEN);
418+
}
405419
SpanMode::Close { verbose: false } => {
406420
buf.push_str(LINE_BRANCH);
407421
for _ in 1..indent_amount {
@@ -468,7 +482,7 @@ fn indent_block_with_lines(
468482
fn indent_block(
469483
block: &mut String,
470484
buf: &mut String,
471-
indent: usize,
485+
mut indent: usize,
472486
indent_amount: usize,
473487
indent_lines: bool,
474488
prefix: &str,
@@ -477,6 +491,12 @@ fn indent_block(
477491
let lines: Vec<&str> = block.lines().collect();
478492
let indent_spaces = indent * indent_amount;
479493
buf.reserve(block.len() + (lines.len() * indent_spaces));
494+
495+
// The PreOpen and PostClose events are generated for the indent of the child span
496+
if matches!(style, SpanMode::PreOpen | SpanMode::PostClose) {
497+
indent += 1;
498+
}
499+
480500
if indent_lines {
481501
indent_block_with_lines(&lines, buf, indent, indent_amount, prefix, style);
482502
} else {

src/lib.rs

Lines changed: 28 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ use tracing_subscriber::{
3636
pub(crate) struct Data {
3737
start: Instant,
3838
kvs: Vec<(&'static str, String)>,
39-
printed: bool,
39+
written: bool,
4040
}
4141

4242
impl Data {
4343
pub fn new(attrs: &Attributes<'_>, printed: bool) -> Self {
4444
let mut span = Self {
4545
start: Instant::now(),
4646
kvs: Vec::new(),
47-
printed,
47+
written: printed,
4848
};
4949
attrs.record(&mut span);
5050
span
@@ -265,13 +265,18 @@ where
265265
Ok(())
266266
}
267267

268-
fn write_span_info<S>(&self, id: &Id, bufs: &mut Buffers, ctx: &Context<S>, style: SpanMode)
269-
where
268+
fn write_span_info<S>(
269+
&self,
270+
span: &SpanRef<S>,
271+
bufs: &mut Buffers,
272+
ctx: &Context<S>,
273+
style: SpanMode,
274+
) where
270275
S: Subscriber + for<'span> LookupSpan<'span>,
271276
{
272-
let span = ctx
273-
.span(id)
274-
.expect("in on_enter/on_exit but span does not exist");
277+
// let span = ctx
278+
// .span(id)
279+
// .expect("in on_enter/on_exit but span does not exist");
275280

276281
let ext = span.extensions();
277282
let data = ext.get::<Data>().expect("span does not have data");
@@ -282,13 +287,7 @@ where
282287
write_span_mode(current_buf, style)
283288
}
284289

285-
let indent = ctx
286-
.lookup_current()
287-
.as_ref()
288-
.map(scope_path)
289-
.into_iter()
290-
.flatten()
291-
.count();
290+
let indent = scope_path(span).skip(1).count();
292291

293292
let should_write = match style {
294293
SpanMode::Open { .. } | SpanMode::Event => true,
@@ -372,12 +371,12 @@ where
372371

373372
if self.config.verbose_entry {
374373
if let Some(span) = span.parent() {
375-
self.write_span_info(&span.id(), bufs, &ctx, SpanMode::PreOpen);
374+
self.write_span_info(&span, bufs, &ctx, SpanMode::PreOpen);
376375
}
377376
}
378377

379378
self.write_span_info(
380-
id,
379+
&span,
381380
bufs,
382381
&ctx,
383382
SpanMode::Open {
@@ -399,10 +398,10 @@ where
399398
|| current_span
400399
.extensions()
401400
.get::<Data>()
402-
.is_some_and(|v| !v.printed)
401+
.is_some_and(|v| !v.written)
403402
{
404403
if let Some(data) = current_span.extensions_mut().get_mut::<Data>() {
405-
data.printed = true;
404+
data.written = true;
406405
}
407406

408407
let old_span_id = bufs.current_span.replace((*span_id).clone());
@@ -412,11 +411,11 @@ where
412411
if Some(*span_id) != old_span_id.as_ref() {
413412
let old_span = old_span_id.as_ref().and_then(|v| ctx.span(v));
414413

415-
eprintln!(
416-
"concurrent old: {:?}, new: {:?}",
417-
old_span.as_ref().map(|v| v.metadata().name()),
418-
current_span.metadata().name()
419-
);
414+
// eprintln!(
415+
// "concurrent old: {:?}, new: {:?}",
416+
// old_span.as_ref().map(|v| v.metadata().name()),
417+
// current_span.metadata().name()
418+
// );
420419

421420
let old_path = old_span.as_ref().map(scope_path).into_iter().flatten();
422421
let new_path = scope_path(current_span);
@@ -425,9 +424,8 @@ where
425424
let new_path = DifferenceIter::new(old_path, new_path, |v| v.id());
426425

427426
for span in new_path {
428-
eprintln!("Writing span {:?}", span.id());
429427
self.write_span_info(
430-
&span.id(),
428+
&span,
431429
bufs,
432430
&ctx,
433431
SpanMode::Retrace {
@@ -541,18 +539,15 @@ where
541539
bufs.current_span = None;
542540
}
543541

544-
let span = ctx.span(&id);
542+
let span = ctx.span(&id).expect("invalid span in on_close");
545543

546544
// Span was not printed, so don't print an exit
547545
if self.config.deferred_spans
548-
&& span
549-
.as_ref()
550-
.and_then(|v| v.extensions().get::<Data>().map(|v| v.printed))
551-
!= Some(true)
546+
&& span.extensions().get::<Data>().map(|v| v.written) != Some(true)
552547
{}
553548

554549
self.write_span_info(
555-
&id,
550+
&span,
556551
bufs,
557552
&ctx,
558553
SpanMode::Close {
@@ -561,11 +556,11 @@ where
561556
);
562557

563558
if self.config.verbose_exit {
564-
if let Some(parent_span) = span.and_then(|span| span.parent()) {
559+
if let Some(parent_span) = span.parent() {
565560
// Consider parent as entered
566561
bufs.current_span = Some(parent_span.id());
567562

568-
self.write_span_info(&parent_span.id(), bufs, &ctx, SpanMode::PostClose);
563+
self.write_span_info(&parent_span, bufs, &ctx, SpanMode::PostClose);
569564
}
570565
}
571566
}

0 commit comments

Comments
 (0)