/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tracing-tree-0.2.5/src/lib.rs
Line | Count | Source |
1 | | pub(crate) mod format; |
2 | | pub mod time; |
3 | | |
4 | | use crate::time::FormatTime; |
5 | | use format::{write_span_mode, Buffers, ColorLevel, Config, FmtEvent, SpanMode}; |
6 | | |
7 | | use nu_ansi_term::{Color, Style}; |
8 | | use std::{ |
9 | | fmt::{self, Write as _}, |
10 | | io::{self, IsTerminal}, |
11 | | iter::Fuse, |
12 | | mem, |
13 | | sync::Mutex, |
14 | | time::Instant, |
15 | | }; |
16 | | use tracing_core::{ |
17 | | field::{Field, Visit}, |
18 | | span::{Attributes, Id}, |
19 | | Event, Subscriber, |
20 | | }; |
21 | | #[cfg(feature = "tracing-log")] |
22 | | use tracing_log::NormalizeEvent; |
23 | | use tracing_subscriber::{ |
24 | | fmt::MakeWriter, |
25 | | layer::{Context, Layer}, |
26 | | registry::{LookupSpan, ScopeFromRoot, SpanRef}, |
27 | | }; |
28 | | |
29 | | // Span extension data |
30 | | pub(crate) struct Data { |
31 | | start: Instant, |
32 | | kvs: Vec<(&'static str, String)>, |
33 | | written: bool, |
34 | | } |
35 | | |
36 | | impl Data { |
37 | 0 | pub fn new(attrs: &Attributes<'_>, written: bool) -> Self { |
38 | 0 | let mut span = Self { |
39 | 0 | start: Instant::now(), |
40 | 0 | kvs: Vec::new(), |
41 | 0 | written, |
42 | 0 | }; |
43 | 0 | attrs.record(&mut span); |
44 | 0 | span |
45 | 0 | } |
46 | | } |
47 | | |
48 | | impl Visit for Data { |
49 | 0 | fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { |
50 | 0 | self.kvs.push((field.name(), format!("{:?}", value))) |
51 | 0 | } |
52 | | } |
53 | | |
54 | | #[derive(Debug)] |
55 | | pub struct HierarchicalLayer<W = fn() -> io::Stderr, FT = ()> |
56 | | where |
57 | | W: for<'writer> MakeWriter<'writer> + 'static, |
58 | | FT: FormatTime, |
59 | | { |
60 | | make_writer: W, |
61 | | bufs: Mutex<Buffers>, |
62 | | config: Config, |
63 | | timer: FT, |
64 | | } |
65 | | |
66 | | impl Default for HierarchicalLayer { |
67 | 0 | fn default() -> Self { |
68 | 0 | Self::new(2) |
69 | 0 | } |
70 | | } |
71 | | |
72 | | impl HierarchicalLayer<fn() -> io::Stderr> { |
73 | 0 | pub fn new(indent_amount: usize) -> Self { |
74 | 0 | let ansi = io::stderr().is_terminal(); |
75 | 0 | let config = Config { |
76 | 0 | ansi, |
77 | 0 | indent_amount, |
78 | 0 | ..Default::default() |
79 | 0 | }; |
80 | 0 | Self { |
81 | 0 | make_writer: io::stderr, |
82 | 0 | bufs: Mutex::new(Buffers::new()), |
83 | 0 | config, |
84 | 0 | timer: (), |
85 | 0 | } |
86 | 0 | } |
87 | | } |
88 | | |
89 | | impl<W, FT> HierarchicalLayer<W, FT> |
90 | | where |
91 | | W: for<'writer> MakeWriter<'writer> + 'static, |
92 | | FT: FormatTime, |
93 | | { |
94 | | /// Enables terminal colors, boldness and italics. |
95 | 0 | pub fn with_ansi(self, ansi: bool) -> Self { |
96 | 0 | Self { |
97 | 0 | config: self.config.with_ansi(ansi), |
98 | 0 | ..self |
99 | 0 | } |
100 | 0 | } Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::with_ansi Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _>>::with_ansi |
101 | | |
102 | 0 | pub fn with_writer<W2>(self, make_writer: W2) -> HierarchicalLayer<W2, FT> |
103 | 0 | where |
104 | 0 | W2: for<'writer> MakeWriter<'writer>, |
105 | | { |
106 | 0 | HierarchicalLayer { |
107 | 0 | make_writer, |
108 | 0 | config: self.config, |
109 | 0 | bufs: self.bufs, |
110 | 0 | timer: self.timer, |
111 | 0 | } |
112 | 0 | } Unexecuted instantiation: <tracing_tree::HierarchicalLayer>::with_writer::<tracing_subscriber::fmt::writer::TestWriter> Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _>>::with_writer::<_> |
113 | | |
114 | 0 | pub fn with_indent_amount(self, indent_amount: usize) -> Self { |
115 | 0 | let config = Config { |
116 | 0 | indent_amount, |
117 | 0 | ..self.config |
118 | 0 | }; |
119 | 0 | Self { config, ..self } |
120 | 0 | } Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::with_indent_amount Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _>>::with_indent_amount |
121 | | |
122 | | /// Renders an ascii art tree instead of just using whitespace indentation. |
123 | 0 | pub fn with_indent_lines(self, indent_lines: bool) -> Self { |
124 | 0 | Self { |
125 | 0 | config: self.config.with_indent_lines(indent_lines), |
126 | 0 | ..self |
127 | 0 | } |
128 | 0 | } Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::with_indent_lines Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _>>::with_indent_lines |
129 | | |
130 | | /// Specifies how to measure and format time at which event has occurred. |
131 | 0 | pub fn with_timer<FT2: FormatTime>(self, timer: FT2) -> HierarchicalLayer<W, FT2> { |
132 | 0 | HierarchicalLayer { |
133 | 0 | make_writer: self.make_writer, |
134 | 0 | config: self.config, |
135 | 0 | bufs: self.bufs, |
136 | 0 | timer, |
137 | 0 | } |
138 | 0 | } |
139 | | |
140 | | /// Whether to render the event and span targets. Usually targets are the module path to the |
141 | | /// event/span macro invocation. |
142 | 0 | pub fn with_targets(self, targets: bool) -> Self { |
143 | 0 | Self { |
144 | 0 | config: self.config.with_targets(targets), |
145 | 0 | ..self |
146 | 0 | } |
147 | 0 | } Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::with_targets Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _>>::with_targets |
148 | | |
149 | | /// Whether to render the thread id in the beginning of every line. This is helpful to |
150 | | /// untangle the tracing statements emitted by each thread. |
151 | 0 | pub fn with_thread_ids(self, thread_ids: bool) -> Self { |
152 | 0 | Self { |
153 | 0 | config: self.config.with_thread_ids(thread_ids), |
154 | 0 | ..self |
155 | 0 | } |
156 | 0 | } |
157 | | |
158 | | /// Whether to render the thread name in the beginning of every line. Not all threads have |
159 | | /// names, but if they do, this may be more helpful than the generic thread ids. |
160 | 0 | pub fn with_thread_names(self, thread_names: bool) -> Self { |
161 | 0 | Self { |
162 | 0 | config: self.config.with_thread_names(thread_names), |
163 | 0 | ..self |
164 | 0 | } |
165 | 0 | } |
166 | | |
167 | | /// Resets the indentation to zero after `wraparound` indentation levels. |
168 | | /// This is helpful if you expect very deeply nested spans as otherwise the indentation |
169 | | /// just runs out of your screen. |
170 | 0 | pub fn with_wraparound(self, wraparound: usize) -> Self { |
171 | 0 | Self { |
172 | 0 | config: self.config.with_wraparound(wraparound), |
173 | 0 | ..self |
174 | 0 | } |
175 | 0 | } |
176 | | |
177 | | /// Whether to print the currently active span's message again before entering a new span. |
178 | | /// This helps if the entry to the current span was quite a while back (and with scrolling |
179 | | /// upwards in logs). |
180 | 0 | pub fn with_verbose_entry(self, verbose_entry: bool) -> Self { |
181 | 0 | Self { |
182 | 0 | config: self.config.with_verbose_entry(verbose_entry), |
183 | 0 | ..self |
184 | 0 | } |
185 | 0 | } |
186 | | |
187 | | /// Whether to print the currently active span's message again before dropping it. |
188 | | /// This helps if the entry to the current span was quite a while back (and with scrolling |
189 | | /// upwards in logs). |
190 | 0 | pub fn with_verbose_exit(self, verbose_exit: bool) -> Self { |
191 | 0 | Self { |
192 | 0 | config: self.config.with_verbose_exit(verbose_exit), |
193 | 0 | ..self |
194 | 0 | } |
195 | 0 | } |
196 | | |
197 | | /// Whether to print the currently active span's message again if another span was entered in |
198 | | /// the meantime |
199 | | /// This helps during concurrent or multi-threaded events where threads are entered, but not |
200 | | /// necessarily *exited* before other *divergent* spans are entered and generating events. |
201 | 0 | pub fn with_span_retrace(self, enabled: bool) -> Self { |
202 | 0 | Self { |
203 | 0 | config: self.config.with_span_retrace(enabled), |
204 | 0 | ..self |
205 | 0 | } |
206 | 0 | } |
207 | | |
208 | | /// Defers printing span opening until an event is generated within the span. |
209 | | /// |
210 | | /// Avoids printing empty spans with no generated events. |
211 | 0 | pub fn with_deferred_spans(self, enabled: bool) -> Self { |
212 | 0 | Self { |
213 | 0 | config: self.config.with_deferred_spans(enabled), |
214 | 0 | ..self |
215 | 0 | } |
216 | 0 | } |
217 | | |
218 | | /// Prefixes each branch with the event mode, such as `open`, or `close` |
219 | 0 | pub fn with_span_modes(self, enabled: bool) -> Self { |
220 | 0 | Self { |
221 | 0 | config: self.config.with_span_modes(enabled), |
222 | 0 | ..self |
223 | 0 | } |
224 | 0 | } |
225 | | |
226 | | /// Whether to print `{}` around the fields when printing a span. |
227 | | /// This can help visually distinguish fields from the rest of the message. |
228 | 0 | pub fn with_bracketed_fields(self, bracketed_fields: bool) -> Self { |
229 | 0 | Self { |
230 | 0 | config: self.config.with_bracketed_fields(bracketed_fields), |
231 | 0 | ..self |
232 | 0 | } |
233 | 0 | } |
234 | | |
235 | | /// Whether to print the time with higher precision. |
236 | 0 | pub fn with_higher_precision(self, higher_precision: bool) -> Self { |
237 | 0 | Self { |
238 | 0 | config: self.config.with_higher_precision(higher_precision), |
239 | 0 | ..self |
240 | 0 | } |
241 | 0 | } |
242 | | |
243 | 0 | fn styled(&self, style: Style, text: impl AsRef<str>) -> String { |
244 | 0 | if self.config.ansi { |
245 | 0 | style.paint(text.as_ref()).to_string() |
246 | | } else { |
247 | 0 | text.as_ref().to_string() |
248 | | } |
249 | 0 | } Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::styled::<alloc::string::String> Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::styled::<&str> Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _>>::styled::<_> |
250 | | |
251 | 0 | fn print_kvs<'a, I, V>(&self, buf: &mut impl fmt::Write, kvs: I) -> fmt::Result |
252 | 0 | where |
253 | 0 | I: IntoIterator<Item = (&'a str, V)>, |
254 | 0 | V: fmt::Display + 'a, |
255 | | { |
256 | 0 | let mut kvs = kvs.into_iter(); |
257 | 0 | if let Some((k, v)) = kvs.next() { |
258 | 0 | if k == "message" { |
259 | 0 | write!(buf, "{}", v)?; |
260 | | } else { |
261 | 0 | write!(buf, "{}={}", k, v)?; |
262 | | } |
263 | 0 | } |
264 | 0 | for (k, v) in kvs { |
265 | 0 | write!(buf, ", {}={}", k, v)?; |
266 | | } |
267 | 0 | Ok(()) |
268 | 0 | } Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::print_kvs::<core::iter::adapters::map::Map<core::slice::iter::Iter<(&str, alloc::string::String)>, <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::write_span_info<tracing_subscriber::registry::sharded::Registry>::{closure#0}>, &alloc::string::String, &mut alloc::string::String> Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _>>::print_kvs::<_, _, _> |
269 | | |
270 | | /// If `span_retrace` ensures that `new_span` is properly printed before an event |
271 | 0 | fn write_retrace_span<'a, S>( |
272 | 0 | &self, |
273 | 0 | new_span: &SpanRef<'a, S>, |
274 | 0 | bufs: &mut Buffers, |
275 | 0 | ctx: &'a Context<S>, |
276 | 0 | ) where |
277 | 0 | S: Subscriber + for<'new_span> LookupSpan<'new_span>, |
278 | | { |
279 | 0 | let should_write = if self.config.deferred_spans { |
280 | 0 | if let Some(data) = new_span.extensions_mut().get_mut::<Data>() { |
281 | 0 | !data.written |
282 | | } else { |
283 | 0 | false |
284 | | } |
285 | | } else { |
286 | 0 | false |
287 | | }; |
288 | | |
289 | | // Also handle deferred spans along with retrace since deferred spans may need to print |
290 | | // multiple spans at once as a whole tree can be deferred |
291 | 0 | if self.config.span_retrace || should_write { |
292 | 0 | let old_span_id = bufs.current_span.replace((new_span.id()).clone()); |
293 | 0 | let old_span_id = old_span_id.as_ref(); |
294 | | |
295 | 0 | if Some(&new_span.id()) != old_span_id { |
296 | 0 | let old_span = old_span_id.as_ref().and_then(|v| ctx.span(v)); Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::write_retrace_span::<tracing_subscriber::registry::sharded::Registry>::{closure#0} Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _>>::write_retrace_span::<_>::{closure#0} |
297 | 0 | let old_path = old_span.as_ref().map(scope_path).into_iter().flatten(); |
298 | | |
299 | 0 | let new_path = scope_path(new_span); |
300 | | |
301 | | // Print the path from the common base of the two spans |
302 | 0 | let new_path = DifferenceIter::new(old_path, new_path, |v| v.id()); Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::write_retrace_span::<tracing_subscriber::registry::sharded::Registry>::{closure#1} Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _>>::write_retrace_span::<_>::{closure#1} |
303 | | |
304 | 0 | for (i, span) in new_path.enumerate() { |
305 | | // Mark traversed spans as *written* |
306 | 0 | let was_written = if let Some(data) = span.extensions_mut().get_mut::<Data>() { |
307 | 0 | mem::replace(&mut data.written, true) |
308 | | } else { |
309 | | // `on_new_span` was not called, before |
310 | | // Consider if this should panic instead, which is *technically* correct but is |
311 | | // bad behavior for a logging layer in production. |
312 | 0 | false |
313 | | }; |
314 | | |
315 | | // Print the previous span before entering a new deferred or retraced span |
316 | 0 | if i == 0 && self.config.verbose_entry { |
317 | 0 | if let Some(parent) = &span.parent() { |
318 | 0 | self.write_span_info(parent, bufs, SpanMode::PreOpen); |
319 | 0 | } |
320 | 0 | } |
321 | 0 | let verbose = self.config.verbose_entry && i == 0; |
322 | | |
323 | 0 | self.write_span_info( |
324 | 0 | &span, |
325 | 0 | bufs, |
326 | 0 | if was_written { |
327 | 0 | SpanMode::Retrace { verbose } |
328 | | } else { |
329 | 0 | SpanMode::Open { verbose } |
330 | | }, |
331 | | ) |
332 | | } |
333 | 0 | } |
334 | 0 | } |
335 | 0 | } Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::write_retrace_span::<tracing_subscriber::registry::sharded::Registry> Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _>>::write_retrace_span::<_> |
336 | | |
337 | 0 | fn write_span_info<S>(&self, span: &SpanRef<S>, bufs: &mut Buffers, style: SpanMode) |
338 | 0 | where |
339 | 0 | S: Subscriber + for<'span> LookupSpan<'span>, |
340 | | { |
341 | 0 | let ext = span.extensions(); |
342 | 0 | let data = ext.get::<Data>().expect("span does not have data"); |
343 | | |
344 | 0 | let mut current_buf = &mut bufs.current_buf; |
345 | | |
346 | 0 | if self.config.span_modes { |
347 | 0 | write_span_mode(current_buf, style) |
348 | 0 | } |
349 | | |
350 | 0 | let indent = scope_path(span).skip(1).count(); |
351 | | |
352 | 0 | let should_write = match style { |
353 | 0 | SpanMode::Open { .. } | SpanMode::Event => true, |
354 | | // Print the parent of a new span again before entering the child |
355 | 0 | SpanMode::PreOpen { .. } if self.config.verbose_entry => true, |
356 | 0 | SpanMode::Close { verbose } => verbose, |
357 | | // Generated if `span_retrace` is enabled |
358 | 0 | SpanMode::Retrace { .. } => true, |
359 | | // Generated if `verbose_exit` is enabled |
360 | 0 | SpanMode::PostClose => true, |
361 | 0 | _ => false, |
362 | | }; |
363 | | |
364 | 0 | if should_write { |
365 | 0 | if self.config.targets { |
366 | 0 | let target = span.metadata().target(); |
367 | 0 | write!( |
368 | 0 | &mut current_buf, |
369 | 0 | "{}::", |
370 | 0 | self.styled(Style::new().dimmed(), target,), |
371 | 0 | ) |
372 | 0 | .expect("Unable to write to buffer"); |
373 | 0 | } |
374 | | |
375 | 0 | write!( |
376 | 0 | current_buf, |
377 | 0 | "{name}", |
378 | 0 | name = self.styled(Style::new().fg(Color::Green).bold(), span.metadata().name()) |
379 | | ) |
380 | 0 | .unwrap(); |
381 | 0 | if self.config.bracketed_fields { |
382 | 0 | write!( |
383 | 0 | current_buf, |
384 | 0 | "{}", |
385 | 0 | self.styled(Style::new().fg(Color::Green).bold(), "{") // Style::new().fg(Color::Green).dimmed().paint("{") |
386 | 0 | ) |
387 | 0 | .unwrap(); |
388 | 0 | } else { |
389 | 0 | write!(current_buf, " ").unwrap(); |
390 | 0 | } |
391 | 0 | self.print_kvs(&mut current_buf, data.kvs.iter().map(|(k, v)| (*k, v))) Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::write_span_info::<tracing_subscriber::registry::sharded::Registry>::{closure#0} Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _>>::write_span_info::<_>::{closure#0} |
392 | 0 | .unwrap(); |
393 | 0 | if self.config.bracketed_fields { |
394 | 0 | write!( |
395 | 0 | current_buf, |
396 | 0 | "{}", |
397 | 0 | self.styled(Style::new().fg(Color::Green).bold(), "}") // Style::new().dimmed().paint("}") |
398 | 0 | ) |
399 | 0 | .unwrap(); |
400 | 0 | } |
401 | 0 | } |
402 | | |
403 | 0 | bufs.indent_current(indent, &self.config, style); |
404 | 0 | let writer = self.make_writer.make_writer(); |
405 | 0 | bufs.flush_current_buf(writer) |
406 | 0 | } Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::write_span_info::<tracing_subscriber::registry::sharded::Registry> Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _>>::write_span_info::<_> |
407 | | |
408 | 0 | fn get_timestamp<S>(&self, span: SpanRef<S>) -> Option<String> |
409 | 0 | where |
410 | 0 | S: Subscriber + for<'span> LookupSpan<'span>, |
411 | | { |
412 | 0 | let ext = span.extensions(); |
413 | 0 | let data = ext |
414 | 0 | .get::<Data>() |
415 | 0 | .expect("Data cannot be found in extensions"); |
416 | | |
417 | 0 | if self.config.higher_precision { |
418 | 0 | Some(self.format_timestamp_with_decimals(data.start)) |
419 | | } else { |
420 | 0 | Some(self.format_timestamp(data.start)) |
421 | | } |
422 | 0 | } Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::get_timestamp::<tracing_subscriber::registry::sharded::Registry> Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _>>::get_timestamp::<_> |
423 | | |
424 | 0 | fn format_timestamp(&self, start: std::time::Instant) -> String { |
425 | 0 | let elapsed = start.elapsed(); |
426 | 0 | let millis = elapsed.as_millis(); |
427 | 0 | let secs = elapsed.as_secs(); |
428 | | |
429 | | // Convert elapsed time to appropriate units: ms, s, or m. |
430 | | // - Less than 1s : use ms |
431 | | // - Less than 1m : use s |
432 | | // - 1m and above : use m |
433 | 0 | let (n, unit) = if millis < 1000 { |
434 | 0 | (millis as _, "ms") |
435 | 0 | } else if secs < 60 { |
436 | 0 | (secs, "s ") |
437 | | } else { |
438 | 0 | (secs / 60, "m ") |
439 | | }; |
440 | | |
441 | 0 | let timestamp = format!("{n:>3}"); |
442 | 0 | self.style_timestamp(timestamp, unit) |
443 | 0 | } Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::format_timestamp Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _>>::format_timestamp |
444 | | |
445 | 0 | fn format_timestamp_with_decimals(&self, start: std::time::Instant) -> String { |
446 | 0 | let secs = start.elapsed().as_secs_f64(); |
447 | | |
448 | | // Convert elapsed time to appropriate units: μs, ms, or s. |
449 | | // - Less than 1ms: use μs |
450 | | // - Less than 1s : use ms |
451 | | // - 1s and above : use s |
452 | 0 | let (n, unit) = if secs < 0.001 { |
453 | 0 | (secs * 1_000_000.0, "μs") |
454 | 0 | } else if secs < 1.0 { |
455 | 0 | (secs * 1_000.0, "ms") |
456 | | } else { |
457 | 0 | (secs, "s ") |
458 | | }; |
459 | | |
460 | 0 | let timestamp = format!(" {n:.2}"); |
461 | 0 | self.style_timestamp(timestamp, unit) |
462 | 0 | } Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::format_timestamp_with_decimals Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _>>::format_timestamp_with_decimals |
463 | | |
464 | 0 | fn style_timestamp(&self, timestamp: String, unit: &str) -> String { |
465 | 0 | format!( |
466 | 0 | "{timestamp}{unit} ", |
467 | 0 | timestamp = self.styled(Style::new().dimmed(), timestamp), |
468 | 0 | unit = self.styled(Style::new().dimmed(), unit), |
469 | | ) |
470 | 0 | } Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::style_timestamp Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _>>::style_timestamp |
471 | | } |
472 | | |
473 | | impl<S, W, FT> Layer<S> for HierarchicalLayer<W, FT> |
474 | | where |
475 | | S: Subscriber + for<'span> LookupSpan<'span>, |
476 | | W: for<'writer> MakeWriter<'writer> + 'static, |
477 | | FT: FormatTime + 'static, |
478 | | { |
479 | 0 | fn on_new_span(&self, attrs: &Attributes, id: &Id, ctx: Context<S>) { |
480 | 0 | let span = ctx.span(id).expect("in new_span but span does not exist"); |
481 | | |
482 | 0 | if span.extensions().get::<Data>().is_none() { |
483 | 0 | let data = Data::new(attrs, !self.config.deferred_spans); |
484 | 0 | span.extensions_mut().insert(data); |
485 | 0 | } |
486 | | |
487 | | // Entry will be printed in on_event along with retrace |
488 | 0 | if self.config.deferred_spans { |
489 | 0 | return; |
490 | 0 | } |
491 | | |
492 | 0 | let bufs = &mut *self.bufs.lock().unwrap(); |
493 | | |
494 | | // Store the most recently entered span |
495 | 0 | bufs.current_span = Some(span.id()); |
496 | | |
497 | 0 | if self.config.verbose_entry { |
498 | 0 | if let Some(span) = span.parent() { |
499 | 0 | self.write_span_info(&span, bufs, SpanMode::PreOpen); |
500 | 0 | } |
501 | 0 | } |
502 | | |
503 | 0 | self.write_span_info( |
504 | 0 | &span, |
505 | 0 | bufs, |
506 | 0 | SpanMode::Open { |
507 | 0 | verbose: self.config.verbose_entry, |
508 | 0 | }, |
509 | | ); |
510 | 0 | } Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter> as tracing_subscriber::layer::Layer<tracing_subscriber::registry::sharded::Registry>>::on_new_span Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _> as tracing_subscriber::layer::Layer<_>>::on_new_span |
511 | | |
512 | 0 | fn on_event(&self, event: &Event<'_>, ctx: Context<S>) { |
513 | 0 | let span = ctx.current_span(); |
514 | 0 | let span_id = span.id(); |
515 | 0 | let span = span_id.and_then(|id| ctx.span(id)); Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter> as tracing_subscriber::layer::Layer<tracing_subscriber::registry::sharded::Registry>>::on_event::{closure#0} Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _> as tracing_subscriber::layer::Layer<_>>::on_event::{closure#0} |
516 | | |
517 | 0 | let mut guard = self.bufs.lock().unwrap(); |
518 | 0 | let bufs = &mut *guard; |
519 | | |
520 | 0 | if let Some(new_span) = &span { |
521 | 0 | self.write_retrace_span(new_span, bufs, &ctx); |
522 | 0 | } |
523 | | |
524 | 0 | let mut event_buf = &mut bufs.current_buf; |
525 | | |
526 | | // Time. |
527 | | |
528 | | { |
529 | 0 | let prev_buffer_len = event_buf.len(); |
530 | | |
531 | 0 | self.timer |
532 | 0 | .format_time(&mut event_buf) |
533 | 0 | .expect("Unable to write time to buffer"); |
534 | | |
535 | | // Something was written to the buffer, pad it with a space. |
536 | 0 | if prev_buffer_len < event_buf.len() { |
537 | 0 | write!(event_buf, " ").expect("Unable to write to buffer"); |
538 | 0 | } |
539 | | } |
540 | | |
541 | | // printing the indentation |
542 | 0 | let indent = ctx |
543 | 0 | .event_scope(event) |
544 | 0 | .map(|scope| scope.count()) Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter> as tracing_subscriber::layer::Layer<tracing_subscriber::registry::sharded::Registry>>::on_event::{closure#1} Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _> as tracing_subscriber::layer::Layer<_>>::on_event::{closure#1} |
545 | 0 | .unwrap_or(0); |
546 | | |
547 | | // check if this event occurred in the context of a span. |
548 | | // if it has, get the start time of this span. |
549 | 0 | if let Some(span) = span { |
550 | 0 | if let Some(timestamp) = self.get_timestamp(span) { |
551 | 0 | write!(&mut event_buf, "{}", timestamp).expect("Unable to write to buffer"); |
552 | 0 | } |
553 | 0 | } |
554 | | |
555 | | #[cfg(feature = "tracing-log")] |
556 | 0 | let normalized_meta = event.normalized_metadata(); |
557 | | #[cfg(feature = "tracing-log")] |
558 | 0 | let metadata = normalized_meta.as_ref().unwrap_or_else(|| event.metadata()); Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter> as tracing_subscriber::layer::Layer<tracing_subscriber::registry::sharded::Registry>>::on_event::{closure#2} Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _> as tracing_subscriber::layer::Layer<_>>::on_event::{closure#2} |
559 | | #[cfg(not(feature = "tracing-log"))] |
560 | | let metadata = event.metadata(); |
561 | | |
562 | 0 | let level = metadata.level(); |
563 | 0 | let level = if self.config.ansi { |
564 | 0 | ColorLevel(level).to_string() |
565 | | } else { |
566 | 0 | level.to_string() |
567 | | }; |
568 | | |
569 | 0 | write!(&mut event_buf, "{level}", level = level).expect("Unable to write to buffer"); |
570 | | |
571 | 0 | if self.config.targets { |
572 | 0 | let target = metadata.target(); |
573 | 0 | write!( |
574 | 0 | &mut event_buf, |
575 | 0 | " {}", |
576 | 0 | self.styled(Style::new().dimmed(), target,), |
577 | 0 | ) |
578 | 0 | .expect("Unable to write to buffer"); |
579 | 0 | } |
580 | | |
581 | 0 | let mut visitor = FmtEvent { comma: false, bufs }; |
582 | 0 | event.record(&mut visitor); |
583 | 0 | visitor |
584 | 0 | .bufs |
585 | 0 | .indent_current(indent, &self.config, SpanMode::Event); |
586 | 0 | let writer = self.make_writer.make_writer(); |
587 | 0 | bufs.flush_current_buf(writer) |
588 | 0 | } Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter> as tracing_subscriber::layer::Layer<tracing_subscriber::registry::sharded::Registry>>::on_event Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _> as tracing_subscriber::layer::Layer<_>>::on_event |
589 | | |
590 | 0 | fn on_close(&self, id: Id, ctx: Context<S>) { |
591 | 0 | let bufs = &mut *self.bufs.lock().unwrap(); |
592 | | |
593 | 0 | let span = ctx.span(&id).expect("invalid span in on_close"); |
594 | | |
595 | | // Span was not printed, so don't print an exit |
596 | 0 | if self.config.deferred_spans |
597 | 0 | && span.extensions().get::<Data>().map(|v| v.written) != Some(true) |
598 | | { |
599 | 0 | return; |
600 | 0 | } |
601 | | |
602 | | // self.write_retrace_span(&span, bufs, &ctx); |
603 | | |
604 | 0 | self.write_span_info( |
605 | 0 | &span, |
606 | 0 | bufs, |
607 | 0 | SpanMode::Close { |
608 | 0 | verbose: self.config.verbose_exit, |
609 | 0 | }, |
610 | | ); |
611 | | |
612 | 0 | if let Some(parent_span) = span.parent() { |
613 | 0 | bufs.current_span = Some(parent_span.id()); |
614 | 0 | if self.config.verbose_exit { |
615 | 0 | // Consider parent as entered |
616 | 0 |
|
617 | 0 | self.write_span_info(&parent_span, bufs, SpanMode::PostClose); |
618 | 0 | } |
619 | 0 | } |
620 | 0 | } Unexecuted instantiation: <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter> as tracing_subscriber::layer::Layer<tracing_subscriber::registry::sharded::Registry>>::on_close Unexecuted instantiation: <tracing_tree::HierarchicalLayer<_, _> as tracing_subscriber::layer::Layer<_>>::on_close |
621 | | } |
622 | | |
623 | 0 | fn scope_path<'a, R: LookupSpan<'a>>(span: &SpanRef<'a, R>) -> ScopeFromRoot<'a, R> { |
624 | 0 | span.scope().from_root() |
625 | 0 | } Unexecuted instantiation: tracing_tree::scope_path::<tracing_subscriber::registry::sharded::Registry> Unexecuted instantiation: tracing_tree::scope_path::<_> |
626 | | |
627 | | /// Runs `A` and `B` side by side and only yields items present in `B` |
628 | | struct DifferenceIter<L, R, F> { |
629 | | left: Fuse<L>, |
630 | | right: R, |
631 | | compare: F, |
632 | | } |
633 | | |
634 | | impl<L: Iterator<Item = T>, R: Iterator<Item = T>, T, U: PartialEq, F: Fn(&T) -> U> |
635 | | DifferenceIter<L, R, F> |
636 | | { |
637 | 0 | fn new(left: L, right: R, compare: F) -> Self { |
638 | 0 | Self { |
639 | 0 | left: left.fuse(), |
640 | 0 | right, |
641 | 0 | compare, |
642 | 0 | } |
643 | 0 | } Unexecuted instantiation: <tracing_tree::DifferenceIter<core::iter::adapters::flatten::Flatten<core::option::IntoIter<tracing_subscriber::registry::ScopeFromRoot<tracing_subscriber::registry::sharded::Registry>>>, tracing_subscriber::registry::ScopeFromRoot<tracing_subscriber::registry::sharded::Registry>, <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::write_retrace_span<tracing_subscriber::registry::sharded::Registry>::{closure#1}>>::new Unexecuted instantiation: <tracing_tree::DifferenceIter<_, _, _>>::new |
644 | | } |
645 | | |
646 | | impl<L: Iterator<Item = T>, R: Iterator<Item = T>, T, U: PartialEq, F: Fn(&T) -> U> Iterator |
647 | | for DifferenceIter<L, R, F> |
648 | | { |
649 | | type Item = T; |
650 | | |
651 | 0 | fn next(&mut self) -> Option<Self::Item> { |
652 | | loop { |
653 | 0 | let left = self.left.next(); |
654 | 0 | let right = self.right.next()?; |
655 | | |
656 | 0 | if left.as_ref().map(&self.compare) != Some((self.compare)(&right)) { |
657 | 0 | return Some(right); |
658 | 0 | } |
659 | | } |
660 | 0 | } Unexecuted instantiation: <tracing_tree::DifferenceIter<core::iter::adapters::flatten::Flatten<core::option::IntoIter<tracing_subscriber::registry::ScopeFromRoot<tracing_subscriber::registry::sharded::Registry>>>, tracing_subscriber::registry::ScopeFromRoot<tracing_subscriber::registry::sharded::Registry>, <tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>>::write_retrace_span<tracing_subscriber::registry::sharded::Registry>::{closure#1}> as core::iter::traits::iterator::Iterator>::next Unexecuted instantiation: <tracing_tree::DifferenceIter<_, _, _> as core::iter::traits::iterator::Iterator>::next |
661 | | } |