]> git.proxmox.com Git - rustc.git/blob - vendor/tracing-subscriber/src/fmt/fmt_layer.rs
New upstream version 1.60.0+dfsg1
[rustc.git] / vendor / tracing-subscriber / src / fmt / fmt_layer.rs
1 use crate::{
2 field::RecordFields,
3 fmt::{format, FormatEvent, FormatFields, MakeWriter, TestWriter},
4 layer::{self, Context},
5 registry::{self, LookupSpan, SpanRef},
6 };
7 use format::{FmtSpan, TimingDisplay};
8 use std::{any::TypeId, cell::RefCell, fmt, io, marker::PhantomData, ops::Deref, time::Instant};
9 use tracing_core::{
10 field,
11 span::{Attributes, Current, Id, Record},
12 Event, Metadata, Subscriber,
13 };
14
15 /// A [`Layer`] that logs formatted representations of `tracing` events.
16 ///
17 /// ## Examples
18 ///
19 /// Constructing a layer with the default configuration:
20 ///
21 /// ```rust
22 /// use tracing_subscriber::{fmt, Registry};
23 /// use tracing_subscriber::prelude::*;
24 ///
25 /// let subscriber = Registry::default()
26 /// .with(fmt::Layer::default());
27 ///
28 /// tracing::subscriber::set_global_default(subscriber).unwrap();
29 /// ```
30 ///
31 /// Overriding the layer's behavior:
32 ///
33 /// ```rust
34 /// use tracing_subscriber::{fmt, Registry};
35 /// use tracing_subscriber::prelude::*;
36 ///
37 /// let fmt_layer = fmt::layer()
38 /// .with_target(false) // don't include event targets when logging
39 /// .with_level(false); // don't include event levels when logging
40 ///
41 /// let subscriber = Registry::default().with(fmt_layer);
42 /// # tracing::subscriber::set_global_default(subscriber).unwrap();
43 /// ```
44 ///
45 /// Setting a custom event formatter:
46 ///
47 /// ```rust
48 /// use tracing_subscriber::fmt::{self, format, time};
49 /// use tracing_subscriber::prelude::*;
50 ///
51 /// let fmt = format().with_timer(time::Uptime::default());
52 /// let fmt_layer = fmt::layer()
53 /// .event_format(fmt)
54 /// .with_target(false);
55 /// # let subscriber = fmt_layer.with_subscriber(tracing_subscriber::registry::Registry::default());
56 /// # tracing::subscriber::set_global_default(subscriber).unwrap();
57 /// ```
58 ///
59 /// [`Layer`]: ../layer/trait.Layer.html
60 #[cfg_attr(docsrs, doc(cfg(all(feature = "fmt", feature = "std"))))]
61 #[derive(Debug)]
62 pub struct Layer<
63 S,
64 N = format::DefaultFields,
65 E = format::Format<format::Full>,
66 W = fn() -> io::Stdout,
67 > {
68 make_writer: W,
69 fmt_fields: N,
70 fmt_event: E,
71 fmt_span: format::FmtSpanConfig,
72 is_ansi: bool,
73 _inner: PhantomData<S>,
74 }
75
76 impl<S> Layer<S> {
77 /// Returns a new [`Layer`](struct.Layer.html) with the default configuration.
78 pub fn new() -> Self {
79 Self::default()
80 }
81 }
82
83 // This needs to be a seperate impl block because they place different bounds on the type parameters.
84 impl<S, N, E, W> Layer<S, N, E, W>
85 where
86 S: Subscriber + for<'a> LookupSpan<'a>,
87 N: for<'writer> FormatFields<'writer> + 'static,
88 W: for<'writer> MakeWriter<'writer> + 'static,
89 {
90 /// Sets the [event formatter][`FormatEvent`] that the layer being built will
91 /// use to format events.
92 ///
93 /// The event formatter may be any type implementing the [`FormatEvent`]
94 /// trait, which is implemented for all functions taking a [`FmtContext`], a
95 /// [`Writer`], and an [`Event`].
96 ///
97 /// # Examples
98 ///
99 /// Setting a type implementing [`FormatEvent`] as the formatter:
100 /// ```rust
101 /// use tracing_subscriber::fmt::{self, format};
102 ///
103 /// let layer = fmt::layer()
104 /// .event_format(format().compact());
105 /// # // this is necessary for type inference.
106 /// # use tracing_subscriber::Layer as _;
107 /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default());
108 /// ```
109 /// [`FormatEvent`]: format::FormatEvent
110 /// [`Event`]: tracing::Event
111 /// [`Writer`]: format::Writer
112 pub fn event_format<E2>(self, e: E2) -> Layer<S, N, E2, W>
113 where
114 E2: FormatEvent<S, N> + 'static,
115 {
116 Layer {
117 fmt_fields: self.fmt_fields,
118 fmt_event: e,
119 fmt_span: self.fmt_span,
120 make_writer: self.make_writer,
121 is_ansi: self.is_ansi,
122 _inner: self._inner,
123 }
124 }
125
126 /// Updates the event formatter by applying a function to the existing event formatter.
127 ///
128 /// This sets the event formatter that the layer being built will use to record fields.
129 ///
130 /// # Examples
131 ///
132 /// Updating an event formatter:
133 ///
134 /// ```rust
135 /// let layer = tracing_subscriber::fmt::layer()
136 /// .map_event_format(|e| e.compact());
137 /// # // this is necessary for type inference.
138 /// # use tracing_subscriber::Layer as _;
139 /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default());
140 /// ```
141 pub fn map_event_format<E2>(self, f: impl FnOnce(E) -> E2) -> Layer<S, N, E2, W>
142 where
143 E2: FormatEvent<S, N> + 'static,
144 {
145 Layer {
146 fmt_fields: self.fmt_fields,
147 fmt_event: f(self.fmt_event),
148 fmt_span: self.fmt_span,
149 make_writer: self.make_writer,
150 is_ansi: self.is_ansi,
151 _inner: self._inner,
152 }
153 }
154 }
155
156 // This needs to be a seperate impl block because they place different bounds on the type parameters.
157 impl<S, N, E, W> Layer<S, N, E, W> {
158 /// Sets the [`MakeWriter`] that the layer being built will use to write events.
159 ///
160 /// # Examples
161 ///
162 /// Using `stderr` rather than `stdout`:
163 ///
164 /// ```rust
165 /// use std::io;
166 /// use tracing_subscriber::fmt;
167 ///
168 /// let layer = fmt::layer()
169 /// .with_writer(io::stderr);
170 /// # // this is necessary for type inference.
171 /// # use tracing_subscriber::Layer as _;
172 /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default());
173 /// ```
174 pub fn with_writer<W2>(self, make_writer: W2) -> Layer<S, N, E, W2>
175 where
176 W2: for<'writer> MakeWriter<'writer> + 'static,
177 {
178 Layer {
179 fmt_fields: self.fmt_fields,
180 fmt_event: self.fmt_event,
181 fmt_span: self.fmt_span,
182 is_ansi: self.is_ansi,
183 make_writer,
184 _inner: self._inner,
185 }
186 }
187
188 /// Configures the subscriber to support [`libtest`'s output capturing][capturing] when used in
189 /// unit tests.
190 ///
191 /// See [`TestWriter`] for additional details.
192 ///
193 /// # Examples
194 ///
195 /// Using [`TestWriter`] to let `cargo test` capture test output:
196 ///
197 /// ```rust
198 /// use std::io;
199 /// use tracing_subscriber::fmt;
200 ///
201 /// let layer = fmt::layer()
202 /// .with_test_writer();
203 /// # // this is necessary for type inference.
204 /// # use tracing_subscriber::Layer as _;
205 /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default());
206 /// ```
207 /// [capturing]:
208 /// https://doc.rust-lang.org/book/ch11-02-running-tests.html#showing-function-output
209 /// [`TestWriter`]: writer/struct.TestWriter.html
210 pub fn with_test_writer(self) -> Layer<S, N, E, TestWriter> {
211 Layer {
212 fmt_fields: self.fmt_fields,
213 fmt_event: self.fmt_event,
214 fmt_span: self.fmt_span,
215 is_ansi: self.is_ansi,
216 make_writer: TestWriter::default(),
217 _inner: self._inner,
218 }
219 }
220
221 /// Enable ANSI terminal colors for formatted output.
222 #[cfg(feature = "ansi")]
223 #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))]
224 pub fn with_ansi(self, ansi: bool) -> Self {
225 Self {
226 is_ansi: ansi,
227 ..self
228 }
229 }
230
231 /// Updates the [`MakeWriter`] by applying a function to the existing [`MakeWriter`].
232 ///
233 /// This sets the [`MakeWriter`] that the layer being built will use to write events.
234 ///
235 /// # Examples
236 ///
237 /// Redirect output to stderr if level is <= WARN:
238 ///
239 /// ```rust
240 /// use tracing::Level;
241 /// use tracing_subscriber::fmt::{self, writer::MakeWriterExt};
242 ///
243 /// let stderr = std::io::stderr.with_max_level(Level::WARN);
244 /// let layer = fmt::layer()
245 /// .map_writer(move |w| stderr.or_else(w));
246 /// # // this is necessary for type inference.
247 /// # use tracing_subscriber::Layer as _;
248 /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default());
249 /// ```
250 pub fn map_writer<W2>(self, f: impl FnOnce(W) -> W2) -> Layer<S, N, E, W2>
251 where
252 W2: for<'writer> MakeWriter<'writer> + 'static,
253 {
254 Layer {
255 fmt_fields: self.fmt_fields,
256 fmt_event: self.fmt_event,
257 fmt_span: self.fmt_span,
258 is_ansi: self.is_ansi,
259 make_writer: f(self.make_writer),
260 _inner: self._inner,
261 }
262 }
263 }
264
265 impl<S, N, L, T, W> Layer<S, N, format::Format<L, T>, W>
266 where
267 N: for<'writer> FormatFields<'writer> + 'static,
268 {
269 /// Use the given [`timer`] for span and event timestamps.
270 ///
271 /// See the [`time` module] for the provided timer implementations.
272 ///
273 /// Note that using the `"time`"" feature flag enables the
274 /// additional time formatters [`UtcTime`] and [`LocalTime`], which use the
275 /// [`time` crate] to provide more sophisticated timestamp formatting
276 /// options.
277 ///
278 /// [`timer`]: super::time::FormatTime
279 /// [`time` module]: mod@super::time
280 /// [`UtcTime`]: super::time::UtcTime
281 /// [`LocalTime`]: super::time::LocalTime
282 /// [`time` crate]: https://docs.rs/time/0.3
283 pub fn with_timer<T2>(self, timer: T2) -> Layer<S, N, format::Format<L, T2>, W> {
284 Layer {
285 fmt_event: self.fmt_event.with_timer(timer),
286 fmt_fields: self.fmt_fields,
287 fmt_span: self.fmt_span,
288 make_writer: self.make_writer,
289 is_ansi: self.is_ansi,
290 _inner: self._inner,
291 }
292 }
293
294 /// Do not emit timestamps with spans and event.
295 pub fn without_time(self) -> Layer<S, N, format::Format<L, ()>, W> {
296 Layer {
297 fmt_event: self.fmt_event.without_time(),
298 fmt_fields: self.fmt_fields,
299 fmt_span: self.fmt_span.without_time(),
300 make_writer: self.make_writer,
301 is_ansi: self.is_ansi,
302 _inner: self._inner,
303 }
304 }
305
306 /// Configures how synthesized events are emitted at points in the [span
307 /// lifecycle][lifecycle].
308 ///
309 /// The following options are available:
310 ///
311 /// - `FmtSpan::NONE`: No events will be synthesized when spans are
312 /// created, entered, exited, or closed. Data from spans will still be
313 /// included as the context for formatted events. This is the default.
314 /// - `FmtSpan::NEW`: An event will be synthesized when spans are created.
315 /// - `FmtSpan::ENTER`: An event will be synthesized when spans are entered.
316 /// - `FmtSpan::EXIT`: An event will be synthesized when spans are exited.
317 /// - `FmtSpan::CLOSE`: An event will be synthesized when a span closes. If
318 /// [timestamps are enabled][time] for this formatter, the generated
319 /// event will contain fields with the span's _busy time_ (the total
320 /// time for which it was entered) and _idle time_ (the total time that
321 /// the span existed but was not entered).
322 /// - `FmtSpan::ACTIVE`: Events will be synthesized when spans are entered
323 /// or exited.
324 /// - `FmtSpan::FULL`: Events will be synthesized whenever a span is
325 /// created, entered, exited, or closed. If timestamps are enabled, the
326 /// close event will contain the span's busy and idle time, as
327 /// described above.
328 ///
329 /// The options can be enabled in any combination. For instance, the following
330 /// will synthesize events whenever spans are created and closed:
331 ///
332 /// ```rust
333 /// use tracing_subscriber::fmt;
334 /// use tracing_subscriber::fmt::format::FmtSpan;
335 ///
336 /// let subscriber = fmt()
337 /// .with_span_events(FmtSpan::NEW | FmtSpan::CLOSE)
338 /// .finish();
339 /// ```
340 ///
341 /// Note that the generated events will only be part of the log output by
342 /// this formatter; they will not be recorded by other `Subscriber`s or by
343 /// `Layer`s added to this subscriber.
344 ///
345 /// [lifecycle]: https://docs.rs/tracing/latest/tracing/span/index.html#the-span-lifecycle
346 /// [time]: #method.without_time
347 pub fn with_span_events(self, kind: FmtSpan) -> Self {
348 Layer {
349 fmt_span: self.fmt_span.with_kind(kind),
350 ..self
351 }
352 }
353
354 /// Sets whether or not an event's target is displayed.
355 pub fn with_target(self, display_target: bool) -> Layer<S, N, format::Format<L, T>, W> {
356 Layer {
357 fmt_event: self.fmt_event.with_target(display_target),
358 ..self
359 }
360 }
361 /// Sets whether or not an event's [source code file path][file] is
362 /// displayed.
363 ///
364 /// [file]: tracing_core::Metadata::file
365 pub fn with_file(self, display_filename: bool) -> Layer<S, N, format::Format<L, T>, W> {
366 Layer {
367 fmt_event: self.fmt_event.with_file(display_filename),
368 ..self
369 }
370 }
371
372 /// Sets whether or not an event's [source code line number][line] is
373 /// displayed.
374 ///
375 /// [line]: tracing_core::Metadata::line
376 pub fn with_line_number(
377 self,
378 display_line_number: bool,
379 ) -> Layer<S, N, format::Format<L, T>, W> {
380 Layer {
381 fmt_event: self.fmt_event.with_line_number(display_line_number),
382 ..self
383 }
384 }
385
386 /// Sets whether or not an event's level is displayed.
387 pub fn with_level(self, display_level: bool) -> Layer<S, N, format::Format<L, T>, W> {
388 Layer {
389 fmt_event: self.fmt_event.with_level(display_level),
390 ..self
391 }
392 }
393
394 /// Sets whether or not the [thread ID] of the current thread is displayed
395 /// when formatting events
396 ///
397 /// [thread ID]: https://doc.rust-lang.org/stable/std/thread/struct.ThreadId.html
398 pub fn with_thread_ids(self, display_thread_ids: bool) -> Layer<S, N, format::Format<L, T>, W> {
399 Layer {
400 fmt_event: self.fmt_event.with_thread_ids(display_thread_ids),
401 ..self
402 }
403 }
404
405 /// Sets whether or not the [name] of the current thread is displayed
406 /// when formatting events
407 ///
408 /// [name]: https://doc.rust-lang.org/stable/std/thread/index.html#naming-threads
409 pub fn with_thread_names(
410 self,
411 display_thread_names: bool,
412 ) -> Layer<S, N, format::Format<L, T>, W> {
413 Layer {
414 fmt_event: self.fmt_event.with_thread_names(display_thread_names),
415 ..self
416 }
417 }
418
419 /// Sets the layer being built to use a [less verbose formatter](../fmt/format/struct.Compact.html).
420 pub fn compact(self) -> Layer<S, N, format::Format<format::Compact, T>, W>
421 where
422 N: for<'writer> FormatFields<'writer> + 'static,
423 {
424 Layer {
425 fmt_event: self.fmt_event.compact(),
426 fmt_fields: self.fmt_fields,
427 fmt_span: self.fmt_span,
428 make_writer: self.make_writer,
429 is_ansi: self.is_ansi,
430 _inner: self._inner,
431 }
432 }
433
434 /// Sets the layer being built to use an [excessively pretty, human-readable formatter](crate::fmt::format::Pretty).
435 #[cfg(feature = "ansi")]
436 #[cfg_attr(docsrs, doc(cfg(feature = "ansi")))]
437 pub fn pretty(self) -> Layer<S, format::Pretty, format::Format<format::Pretty, T>, W> {
438 Layer {
439 fmt_event: self.fmt_event.pretty(),
440 fmt_fields: format::Pretty::default(),
441 fmt_span: self.fmt_span,
442 make_writer: self.make_writer,
443 is_ansi: self.is_ansi,
444 _inner: self._inner,
445 }
446 }
447
448 /// Sets the layer being built to use a [JSON formatter](../fmt/format/struct.Json.html).
449 ///
450 /// The full format includes fields from all entered spans.
451 ///
452 /// # Example Output
453 ///
454 /// ```ignore,json
455 /// {"timestamp":"Feb 20 11:28:15.096","level":"INFO","target":"mycrate","fields":{"message":"some message", "key": "value"}}
456 /// ```
457 ///
458 /// # Options
459 ///
460 /// - [`Layer::flatten_event`] can be used to enable flattening event fields into the root
461 /// object.
462 ///
463 /// [`Layer::flatten_event`]: #method.flatten_event
464 #[cfg(feature = "json")]
465 #[cfg_attr(docsrs, doc(cfg(feature = "json")))]
466 pub fn json(self) -> Layer<S, format::JsonFields, format::Format<format::Json, T>, W> {
467 Layer {
468 fmt_event: self.fmt_event.json(),
469 fmt_fields: format::JsonFields::new(),
470 fmt_span: self.fmt_span,
471 make_writer: self.make_writer,
472 // always disable ANSI escapes in JSON mode!
473 is_ansi: false,
474 _inner: self._inner,
475 }
476 }
477 }
478
479 #[cfg(feature = "json")]
480 #[cfg_attr(docsrs, doc(cfg(feature = "json")))]
481 impl<S, T, W> Layer<S, format::JsonFields, format::Format<format::Json, T>, W> {
482 /// Sets the JSON layer being built to flatten event metadata.
483 ///
484 /// See [`format::Json`](../fmt/format/struct.Json.html)
485 pub fn flatten_event(
486 self,
487 flatten_event: bool,
488 ) -> Layer<S, format::JsonFields, format::Format<format::Json, T>, W> {
489 Layer {
490 fmt_event: self.fmt_event.flatten_event(flatten_event),
491 fmt_fields: format::JsonFields::new(),
492 ..self
493 }
494 }
495
496 /// Sets whether or not the formatter will include the current span in
497 /// formatted events.
498 ///
499 /// See [`format::Json`](../fmt/format/struct.Json.html)
500 pub fn with_current_span(
501 self,
502 display_current_span: bool,
503 ) -> Layer<S, format::JsonFields, format::Format<format::Json, T>, W> {
504 Layer {
505 fmt_event: self.fmt_event.with_current_span(display_current_span),
506 fmt_fields: format::JsonFields::new(),
507 ..self
508 }
509 }
510
511 /// Sets whether or not the formatter will include a list (from root to leaf)
512 /// of all currently entered spans in formatted events.
513 ///
514 /// See [`format::Json`](../fmt/format/struct.Json.html)
515 pub fn with_span_list(
516 self,
517 display_span_list: bool,
518 ) -> Layer<S, format::JsonFields, format::Format<format::Json, T>, W> {
519 Layer {
520 fmt_event: self.fmt_event.with_span_list(display_span_list),
521 fmt_fields: format::JsonFields::new(),
522 ..self
523 }
524 }
525 }
526
527 impl<S, N, E, W> Layer<S, N, E, W> {
528 /// Sets the field formatter that the layer being built will use to record
529 /// fields.
530 pub fn fmt_fields<N2>(self, fmt_fields: N2) -> Layer<S, N2, E, W>
531 where
532 N2: for<'writer> FormatFields<'writer> + 'static,
533 {
534 Layer {
535 fmt_event: self.fmt_event,
536 fmt_fields,
537 fmt_span: self.fmt_span,
538 make_writer: self.make_writer,
539 is_ansi: self.is_ansi,
540 _inner: self._inner,
541 }
542 }
543
544 /// Updates the field formatter by applying a function to the existing field formatter.
545 ///
546 /// This sets the field formatter that the layer being built will use to record fields.
547 ///
548 /// # Examples
549 ///
550 /// Updating a field formatter:
551 ///
552 /// ```rust
553 /// use tracing_subscriber::field::MakeExt;
554 /// let layer = tracing_subscriber::fmt::layer()
555 /// .map_fmt_fields(|f| f.debug_alt());
556 /// # // this is necessary for type inference.
557 /// # use tracing_subscriber::Layer as _;
558 /// # let _ = layer.with_subscriber(tracing_subscriber::registry::Registry::default());
559 /// ```
560 pub fn map_fmt_fields<N2>(self, f: impl FnOnce(N) -> N2) -> Layer<S, N2, E, W>
561 where
562 N2: for<'writer> FormatFields<'writer> + 'static,
563 {
564 Layer {
565 fmt_event: self.fmt_event,
566 fmt_fields: f(self.fmt_fields),
567 fmt_span: self.fmt_span,
568 make_writer: self.make_writer,
569 is_ansi: self.is_ansi,
570 _inner: self._inner,
571 }
572 }
573 }
574
575 impl<S> Default for Layer<S> {
576 fn default() -> Self {
577 Layer {
578 fmt_fields: format::DefaultFields::default(),
579 fmt_event: format::Format::default(),
580 fmt_span: format::FmtSpanConfig::default(),
581 make_writer: io::stdout,
582 is_ansi: cfg!(feature = "ansi"),
583 _inner: PhantomData,
584 }
585 }
586 }
587
588 impl<S, N, E, W> Layer<S, N, E, W>
589 where
590 S: Subscriber + for<'a> LookupSpan<'a>,
591 N: for<'writer> FormatFields<'writer> + 'static,
592 E: FormatEvent<S, N> + 'static,
593 W: for<'writer> MakeWriter<'writer> + 'static,
594 {
595 #[inline]
596 fn make_ctx<'a>(&'a self, ctx: Context<'a, S>, event: &'a Event<'a>) -> FmtContext<'a, S, N> {
597 FmtContext {
598 ctx,
599 fmt_fields: &self.fmt_fields,
600 event,
601 }
602 }
603 }
604
605 /// A formatted representation of a span's fields stored in its [extensions].
606 ///
607 /// Because `FormattedFields` is generic over the type of the formatter that
608 /// produced it, multiple versions of a span's formatted fields can be stored in
609 /// the [`Extensions`][extensions] type-map. This means that when multiple
610 /// formatters are in use, each can store its own formatted representation
611 /// without conflicting.
612 ///
613 /// [extensions]: ../registry/struct.Extensions.html
614 #[derive(Default)]
615 pub struct FormattedFields<E: ?Sized> {
616 _format_fields: PhantomData<fn(E)>,
617 was_ansi: bool,
618 /// The formatted fields of a span.
619 pub fields: String,
620 }
621
622 impl<E: ?Sized> FormattedFields<E> {
623 /// Returns a new `FormattedFields`.
624 pub fn new(fields: String) -> Self {
625 Self {
626 fields,
627 was_ansi: false,
628 _format_fields: PhantomData,
629 }
630 }
631
632 /// Returns a new [`format::Writer`] for writing to this `FormattedFields`.
633 ///
634 /// The returned [`format::Writer`] can be used with the
635 /// [`FormatFields::format_fields`] method.
636 pub fn as_writer(&mut self) -> format::Writer<'_> {
637 format::Writer::new(&mut self.fields).with_ansi(self.was_ansi)
638 }
639 }
640
641 impl<E: ?Sized> fmt::Debug for FormattedFields<E> {
642 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
643 f.debug_struct("FormattedFields")
644 .field("fields", &self.fields)
645 .field("formatter", &format_args!("{}", std::any::type_name::<E>()))
646 .field("was_ansi", &self.was_ansi)
647 .finish()
648 }
649 }
650
651 impl<E: ?Sized> fmt::Display for FormattedFields<E> {
652 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
653 fmt::Display::fmt(&self.fields, f)
654 }
655 }
656
657 impl<E: ?Sized> Deref for FormattedFields<E> {
658 type Target = String;
659 fn deref(&self) -> &Self::Target {
660 &self.fields
661 }
662 }
663
664 // === impl FmtLayer ===
665
666 macro_rules! with_event_from_span {
667 ($id:ident, $span:ident, $($field:literal = $value:expr),*, |$event:ident| $code:block) => {
668 let meta = $span.metadata();
669 let cs = meta.callsite();
670 let fs = field::FieldSet::new(&[$($field),*], cs);
671 #[allow(unused)]
672 let mut iter = fs.iter();
673 let v = [$(
674 (&iter.next().unwrap(), Some(&$value as &dyn field::Value)),
675 )*];
676 let vs = fs.value_set(&v);
677 let $event = Event::new_child_of($id, meta, &vs);
678 $code
679 };
680 }
681
682 impl<S, N, E, W> layer::Layer<S> for Layer<S, N, E, W>
683 where
684 S: Subscriber + for<'a> LookupSpan<'a>,
685 N: for<'writer> FormatFields<'writer> + 'static,
686 E: FormatEvent<S, N> + 'static,
687 W: for<'writer> MakeWriter<'writer> + 'static,
688 {
689 fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) {
690 let span = ctx.span(id).expect("Span not found, this is a bug");
691 let mut extensions = span.extensions_mut();
692
693 if extensions.get_mut::<FormattedFields<N>>().is_none() {
694 let mut fields = FormattedFields::<N>::new(String::new());
695 if self
696 .fmt_fields
697 .format_fields(fields.as_writer().with_ansi(self.is_ansi), attrs)
698 .is_ok()
699 {
700 fields.was_ansi = self.is_ansi;
701 extensions.insert(fields);
702 }
703 }
704
705 if self.fmt_span.fmt_timing
706 && self.fmt_span.trace_close()
707 && extensions.get_mut::<Timings>().is_none()
708 {
709 extensions.insert(Timings::new());
710 }
711
712 if self.fmt_span.trace_new() {
713 with_event_from_span!(id, span, "message" = "new", |event| {
714 drop(extensions);
715 drop(span);
716 self.on_event(&event, ctx);
717 });
718 }
719 }
720
721 fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>) {
722 let span = ctx.span(id).expect("Span not found, this is a bug");
723 let mut extensions = span.extensions_mut();
724 if let Some(fields) = extensions.get_mut::<FormattedFields<N>>() {
725 let _ = self.fmt_fields.add_fields(fields, values);
726 return;
727 }
728
729 let mut fields = FormattedFields::<N>::new(String::new());
730 if self
731 .fmt_fields
732 .format_fields(fields.as_writer().with_ansi(self.is_ansi), values)
733 .is_ok()
734 {
735 fields.was_ansi = self.is_ansi;
736 extensions.insert(fields);
737 }
738 }
739
740 fn on_enter(&self, id: &Id, ctx: Context<'_, S>) {
741 if self.fmt_span.trace_enter() || self.fmt_span.trace_close() && self.fmt_span.fmt_timing {
742 let span = ctx.span(id).expect("Span not found, this is a bug");
743 let mut extensions = span.extensions_mut();
744 if let Some(timings) = extensions.get_mut::<Timings>() {
745 let now = Instant::now();
746 timings.idle += (now - timings.last).as_nanos() as u64;
747 timings.last = now;
748 }
749
750 if self.fmt_span.trace_enter() {
751 with_event_from_span!(id, span, "message" = "enter", |event| {
752 drop(extensions);
753 drop(span);
754 self.on_event(&event, ctx);
755 });
756 }
757 }
758 }
759
760 fn on_exit(&self, id: &Id, ctx: Context<'_, S>) {
761 if self.fmt_span.trace_exit() || self.fmt_span.trace_close() && self.fmt_span.fmt_timing {
762 let span = ctx.span(id).expect("Span not found, this is a bug");
763 let mut extensions = span.extensions_mut();
764 if let Some(timings) = extensions.get_mut::<Timings>() {
765 let now = Instant::now();
766 timings.busy += (now - timings.last).as_nanos() as u64;
767 timings.last = now;
768 }
769
770 if self.fmt_span.trace_exit() {
771 with_event_from_span!(id, span, "message" = "exit", |event| {
772 drop(extensions);
773 drop(span);
774 self.on_event(&event, ctx);
775 });
776 }
777 }
778 }
779
780 fn on_close(&self, id: Id, ctx: Context<'_, S>) {
781 if self.fmt_span.trace_close() {
782 let span = ctx.span(&id).expect("Span not found, this is a bug");
783 let extensions = span.extensions();
784 if let Some(timing) = extensions.get::<Timings>() {
785 let Timings {
786 busy,
787 mut idle,
788 last,
789 } = *timing;
790 idle += (Instant::now() - last).as_nanos() as u64;
791
792 let t_idle = field::display(TimingDisplay(idle));
793 let t_busy = field::display(TimingDisplay(busy));
794
795 with_event_from_span!(
796 id,
797 span,
798 "message" = "close",
799 "time.busy" = t_busy,
800 "time.idle" = t_idle,
801 |event| {
802 drop(extensions);
803 drop(span);
804 self.on_event(&event, ctx);
805 }
806 );
807 } else {
808 with_event_from_span!(id, span, "message" = "close", |event| {
809 drop(extensions);
810 drop(span);
811 self.on_event(&event, ctx);
812 });
813 }
814 }
815 }
816
817 fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) {
818 thread_local! {
819 static BUF: RefCell<String> = RefCell::new(String::new());
820 }
821
822 BUF.with(|buf| {
823 let borrow = buf.try_borrow_mut();
824 let mut a;
825 let mut b;
826 let mut buf = match borrow {
827 Ok(buf) => {
828 a = buf;
829 &mut *a
830 }
831 _ => {
832 b = String::new();
833 &mut b
834 }
835 };
836
837 let ctx = self.make_ctx(ctx, event);
838 if self
839 .fmt_event
840 .format_event(
841 &ctx,
842 format::Writer::new(&mut buf).with_ansi(self.is_ansi),
843 event,
844 )
845 .is_ok()
846 {
847 let mut writer = self.make_writer.make_writer_for(event.metadata());
848 let _ = io::Write::write_all(&mut writer, buf.as_bytes());
849 }
850
851 buf.clear();
852 });
853 }
854
855 unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
856 // This `downcast_raw` impl allows downcasting a `fmt` layer to any of
857 // its components (event formatter, field formatter, and `MakeWriter`)
858 // as well as to the layer's type itself. The potential use-cases for
859 // this *may* be somewhat niche, though...
860 match () {
861 _ if id == TypeId::of::<Self>() => Some(self as *const Self as *const ()),
862 _ if id == TypeId::of::<E>() => Some(&self.fmt_event as *const E as *const ()),
863 _ if id == TypeId::of::<N>() => Some(&self.fmt_fields as *const N as *const ()),
864 _ if id == TypeId::of::<W>() => Some(&self.make_writer as *const W as *const ()),
865 _ => None,
866 }
867 }
868 }
869
870 /// Provides the current span context to a formatter.
871 pub struct FmtContext<'a, S, N> {
872 pub(crate) ctx: Context<'a, S>,
873 pub(crate) fmt_fields: &'a N,
874 pub(crate) event: &'a Event<'a>,
875 }
876
877 impl<'a, S, N> fmt::Debug for FmtContext<'a, S, N> {
878 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
879 f.debug_struct("FmtContext").finish()
880 }
881 }
882
883 impl<'cx, 'writer, S, N> FormatFields<'writer> for FmtContext<'cx, S, N>
884 where
885 S: Subscriber + for<'lookup> LookupSpan<'lookup>,
886 N: FormatFields<'writer> + 'static,
887 {
888 fn format_fields<R: RecordFields>(
889 &self,
890 writer: format::Writer<'writer>,
891 fields: R,
892 ) -> fmt::Result {
893 self.fmt_fields.format_fields(writer, fields)
894 }
895 }
896
897 impl<'a, S, N> FmtContext<'a, S, N>
898 where
899 S: Subscriber + for<'lookup> LookupSpan<'lookup>,
900 N: for<'writer> FormatFields<'writer> + 'static,
901 {
902 /// Visits every span in the current context with a closure.
903 ///
904 /// The provided closure will be called first with the current span,
905 /// and then with that span's parent, and then that span's parent,
906 /// and so on until a root span is reached.
907 pub fn visit_spans<E, F>(&self, mut f: F) -> Result<(), E>
908 where
909 F: FnMut(&SpanRef<'_, S>) -> Result<(), E>,
910 {
911 // visit all the current spans
912 if let Some(scope) = self.event_scope() {
913 for span in scope.from_root() {
914 f(&span)?;
915 }
916 }
917 Ok(())
918 }
919
920 /// Returns metadata for the span with the given `id`, if it exists.
921 ///
922 /// If this returns `None`, then no span exists for that ID (either it has
923 /// closed or the ID is invalid).
924 #[inline]
925 pub fn metadata(&self, id: &Id) -> Option<&'static Metadata<'static>>
926 where
927 S: for<'lookup> LookupSpan<'lookup>,
928 {
929 self.ctx.metadata(id)
930 }
931
932 /// Returns [stored data] for the span with the given `id`, if it exists.
933 ///
934 /// If this returns `None`, then no span exists for that ID (either it has
935 /// closed or the ID is invalid).
936 ///
937 /// [stored data]: ../registry/struct.SpanRef.html
938 #[inline]
939 pub fn span(&self, id: &Id) -> Option<SpanRef<'_, S>>
940 where
941 S: for<'lookup> LookupSpan<'lookup>,
942 {
943 self.ctx.span(id)
944 }
945
946 /// Returns `true` if an active span exists for the given `Id`.
947 #[inline]
948 pub fn exists(&self, id: &Id) -> bool
949 where
950 S: for<'lookup> LookupSpan<'lookup>,
951 {
952 self.ctx.exists(id)
953 }
954
955 /// Returns [stored data] for the span that the wrapped subscriber considers
956 /// to be the current.
957 ///
958 /// If this returns `None`, then we are not currently within a span.
959 ///
960 /// [stored data]: ../registry/struct.SpanRef.html
961 #[inline]
962 pub fn lookup_current(&self) -> Option<SpanRef<'_, S>>
963 where
964 S: for<'lookup> LookupSpan<'lookup>,
965 {
966 self.ctx.lookup_current()
967 }
968
969 /// Returns the current span for this formatter.
970 pub fn current_span(&self) -> Current {
971 self.ctx.current_span()
972 }
973
974 /// Returns [stored data] for the parent span of the event currently being
975 /// formatted.
976 ///
977 /// If the event has a contextual parent, this will return the current span. If
978 /// the event has an explicit parent span, this will return that span. If
979 /// the event does not have a parent span, this will return `None`.
980 ///
981 /// [stored data]: SpanRef
982 pub fn parent_span(&self) -> Option<SpanRef<'_, S>> {
983 self.ctx.event_span(self.event)
984 }
985
986 /// Returns an iterator over the [stored data] for all the spans in the
987 /// current context, starting with the specified span and ending with the
988 /// root of the trace tree and ending with the current span.
989 ///
990 /// This is equivalent to the [`Context::span_scope`] method.
991 ///
992 /// <div class="information">
993 /// <div class="tooltip ignore" style="">ⓘ<span class="tooltiptext">Note</span></div>
994 /// </div>
995 /// <div class="example-wrap" style="display:inline-block">
996 /// <pre class="ignore" style="white-space:normal;font:inherit;">
997 /// <strong>Note</strong>: Compared to <a href="#method.scope"><code>scope</code></a> this
998 /// returns the spans in reverse order (from leaf to root). Use
999 /// <a href="../registry/struct.Scope.html#method.from_root"><code>Scope::from_root</code></a>
1000 /// in case root-to-leaf ordering is desired.
1001 /// </pre></div>
1002 ///
1003 /// <div class="example-wrap" style="display:inline-block">
1004 /// <pre class="ignore" style="white-space:normal;font:inherit;">
1005 /// <strong>Note</strong>: This requires the wrapped subscriber to implement the
1006 /// <a href="../registry/trait.LookupSpan.html"><code>LookupSpan</code></a> trait.
1007 /// See the documentation on <a href="./struct.Context.html"><code>Context</code>'s
1008 /// declaration</a> for details.
1009 /// </pre></div>
1010 ///
1011 /// [stored data]: crate::registry::SpanRef
1012 pub fn span_scope(&self, id: &Id) -> Option<registry::Scope<'_, S>>
1013 where
1014 S: for<'lookup> LookupSpan<'lookup>,
1015 {
1016 self.ctx.span_scope(id)
1017 }
1018
1019 /// Returns an iterator over the [stored data] for all the spans in the
1020 /// event's span context, starting with its parent span and ending with the
1021 /// root of the trace tree.
1022 ///
1023 /// This is equivalent to calling the [`Context::event_scope`] method and
1024 /// passing the event currently being formatted.
1025 ///
1026 /// <div class="example-wrap" style="display:inline-block">
1027 /// <pre class="ignore" style="white-space:normal;font:inherit;">
1028 /// <strong>Note</strong>: Compared to <a href="#method.scope"><code>scope</code></a> this
1029 /// returns the spans in reverse order (from leaf to root). Use
1030 /// <a href="../registry/struct.Scope.html#method.from_root"><code>Scope::from_root</code></a>
1031 /// in case root-to-leaf ordering is desired.
1032 /// </pre></div>
1033 ///
1034 /// <div class="example-wrap" style="display:inline-block">
1035 /// <pre class="ignore" style="white-space:normal;font:inherit;">
1036 /// <strong>Note</strong>: This requires the wrapped subscriber to implement the
1037 /// <a href="../registry/trait.LookupSpan.html"><code>LookupSpan</code></a> trait.
1038 /// See the documentation on <a href="./struct.Context.html"><code>Context</code>'s
1039 /// declaration</a> for details.
1040 /// </pre></div>
1041 ///
1042 /// [stored data]: crate::registry::SpanRef
1043 pub fn event_scope(&self) -> Option<registry::Scope<'_, S>>
1044 where
1045 S: for<'lookup> registry::LookupSpan<'lookup>,
1046 {
1047 self.ctx.event_scope(self.event)
1048 }
1049
1050 /// Returns the [field formatter] configured by the subscriber invoking
1051 /// `format_event`.
1052 ///
1053 /// The event formatter may use the returned field formatter to format the
1054 /// fields of any events it records.
1055 ///
1056 /// [field formatter]: FormatFields
1057 pub fn field_format(&self) -> &N {
1058 self.fmt_fields
1059 }
1060 }
1061
1062 struct Timings {
1063 idle: u64,
1064 busy: u64,
1065 last: Instant,
1066 }
1067
1068 impl Timings {
1069 fn new() -> Self {
1070 Self {
1071 idle: 0,
1072 busy: 0,
1073 last: Instant::now(),
1074 }
1075 }
1076 }
1077
1078 #[cfg(test)]
1079 mod test {
1080 use super::*;
1081 use crate::fmt::{
1082 self,
1083 format::{self, test::MockTime, Format},
1084 layer::Layer as _,
1085 test::{MockMakeWriter, MockWriter},
1086 time,
1087 };
1088 use crate::Registry;
1089 use format::FmtSpan;
1090 use regex::Regex;
1091 use tracing::subscriber::with_default;
1092 use tracing_core::dispatcher::Dispatch;
1093
1094 #[test]
1095 fn impls() {
1096 let f = Format::default().with_timer(time::Uptime::default());
1097 let fmt = fmt::Layer::default().event_format(f);
1098 let subscriber = fmt.with_subscriber(Registry::default());
1099 let _dispatch = Dispatch::new(subscriber);
1100
1101 let f = format::Format::default();
1102 let fmt = fmt::Layer::default().event_format(f);
1103 let subscriber = fmt.with_subscriber(Registry::default());
1104 let _dispatch = Dispatch::new(subscriber);
1105
1106 let f = format::Format::default().compact();
1107 let fmt = fmt::Layer::default().event_format(f);
1108 let subscriber = fmt.with_subscriber(Registry::default());
1109 let _dispatch = Dispatch::new(subscriber);
1110 }
1111
1112 #[test]
1113 fn fmt_layer_downcasts() {
1114 let f = format::Format::default();
1115 let fmt = fmt::Layer::default().event_format(f);
1116 let subscriber = fmt.with_subscriber(Registry::default());
1117
1118 let dispatch = Dispatch::new(subscriber);
1119 assert!(dispatch.downcast_ref::<fmt::Layer<Registry>>().is_some());
1120 }
1121
1122 #[test]
1123 fn fmt_layer_downcasts_to_parts() {
1124 let f = format::Format::default();
1125 let fmt = fmt::Layer::default().event_format(f);
1126 let subscriber = fmt.with_subscriber(Registry::default());
1127 let dispatch = Dispatch::new(subscriber);
1128 assert!(dispatch.downcast_ref::<format::DefaultFields>().is_some());
1129 assert!(dispatch.downcast_ref::<format::Format>().is_some())
1130 }
1131
1132 #[test]
1133 fn is_lookup_span() {
1134 fn assert_lookup_span<T: for<'a> crate::registry::LookupSpan<'a>>(_: T) {}
1135 let fmt = fmt::Layer::default();
1136 let subscriber = fmt.with_subscriber(Registry::default());
1137 assert_lookup_span(subscriber)
1138 }
1139
1140 fn sanitize_timings(s: String) -> String {
1141 let re = Regex::new("time\\.(idle|busy)=([0-9.]+)[mµn]s").unwrap();
1142 re.replace_all(s.as_str(), "timing").to_string()
1143 }
1144
1145 #[test]
1146 fn synthesize_span_none() {
1147 let make_writer = MockMakeWriter::default();
1148 let subscriber = crate::fmt::Subscriber::builder()
1149 .with_writer(make_writer.clone())
1150 .with_level(false)
1151 .with_ansi(false)
1152 .with_timer(MockTime)
1153 // check that FmtSpan::NONE is the default
1154 .finish();
1155
1156 with_default(subscriber, || {
1157 let span1 = tracing::info_span!("span1", x = 42);
1158 let _e = span1.enter();
1159 });
1160 let actual = sanitize_timings(make_writer.get_string());
1161 assert_eq!("", actual.as_str());
1162 }
1163
1164 #[test]
1165 fn synthesize_span_active() {
1166 let make_writer = MockMakeWriter::default();
1167 let subscriber = crate::fmt::Subscriber::builder()
1168 .with_writer(make_writer.clone())
1169 .with_level(false)
1170 .with_ansi(false)
1171 .with_timer(MockTime)
1172 .with_span_events(FmtSpan::ACTIVE)
1173 .finish();
1174
1175 with_default(subscriber, || {
1176 let span1 = tracing::info_span!("span1", x = 42);
1177 let _e = span1.enter();
1178 });
1179 let actual = sanitize_timings(make_writer.get_string());
1180 assert_eq!(
1181 "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: enter\n\
1182 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: exit\n",
1183 actual.as_str()
1184 );
1185 }
1186
1187 #[test]
1188 fn synthesize_span_close() {
1189 let make_writer = MockMakeWriter::default();
1190 let subscriber = crate::fmt::Subscriber::builder()
1191 .with_writer(make_writer.clone())
1192 .with_level(false)
1193 .with_ansi(false)
1194 .with_timer(MockTime)
1195 .with_span_events(FmtSpan::CLOSE)
1196 .finish();
1197
1198 with_default(subscriber, || {
1199 let span1 = tracing::info_span!("span1", x = 42);
1200 let _e = span1.enter();
1201 });
1202 let actual = sanitize_timings(make_writer.get_string());
1203 assert_eq!(
1204 "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close timing timing\n",
1205 actual.as_str()
1206 );
1207 }
1208
1209 #[test]
1210 fn synthesize_span_close_no_timing() {
1211 let make_writer = MockMakeWriter::default();
1212 let subscriber = crate::fmt::Subscriber::builder()
1213 .with_writer(make_writer.clone())
1214 .with_level(false)
1215 .with_ansi(false)
1216 .with_timer(MockTime)
1217 .without_time()
1218 .with_span_events(FmtSpan::CLOSE)
1219 .finish();
1220
1221 with_default(subscriber, || {
1222 let span1 = tracing::info_span!("span1", x = 42);
1223 let _e = span1.enter();
1224 });
1225 let actual = sanitize_timings(make_writer.get_string());
1226 assert_eq!(
1227 "span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close\n",
1228 actual.as_str()
1229 );
1230 }
1231
1232 #[test]
1233 fn synthesize_span_full() {
1234 let make_writer = MockMakeWriter::default();
1235 let subscriber = crate::fmt::Subscriber::builder()
1236 .with_writer(make_writer.clone())
1237 .with_level(false)
1238 .with_ansi(false)
1239 .with_timer(MockTime)
1240 .with_span_events(FmtSpan::FULL)
1241 .finish();
1242
1243 with_default(subscriber, || {
1244 let span1 = tracing::info_span!("span1", x = 42);
1245 let _e = span1.enter();
1246 });
1247 let actual = sanitize_timings(make_writer.get_string());
1248 assert_eq!(
1249 "fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: new\n\
1250 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: enter\n\
1251 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: exit\n\
1252 fake time span1{x=42}: tracing_subscriber::fmt::fmt_layer::test: close timing timing\n",
1253 actual.as_str()
1254 );
1255 }
1256
1257 #[test]
1258 fn make_writer_based_on_meta() {
1259 struct MakeByTarget {
1260 make_writer1: MockMakeWriter,
1261 make_writer2: MockMakeWriter,
1262 }
1263
1264 impl<'a> MakeWriter<'a> for MakeByTarget {
1265 type Writer = MockWriter;
1266
1267 fn make_writer(&'a self) -> Self::Writer {
1268 self.make_writer1.make_writer()
1269 }
1270
1271 fn make_writer_for(&'a self, meta: &Metadata<'_>) -> Self::Writer {
1272 if meta.target() == "writer2" {
1273 return self.make_writer2.make_writer();
1274 }
1275 self.make_writer()
1276 }
1277 }
1278
1279 let make_writer1 = MockMakeWriter::default();
1280 let make_writer2 = MockMakeWriter::default();
1281
1282 let make_writer = MakeByTarget {
1283 make_writer1: make_writer1.clone(),
1284 make_writer2: make_writer2.clone(),
1285 };
1286
1287 let subscriber = crate::fmt::Subscriber::builder()
1288 .with_writer(make_writer)
1289 .with_level(false)
1290 .with_target(false)
1291 .with_ansi(false)
1292 .with_timer(MockTime)
1293 .with_span_events(FmtSpan::CLOSE)
1294 .finish();
1295
1296 with_default(subscriber, || {
1297 let span1 = tracing::info_span!("writer1_span", x = 42);
1298 let _e = span1.enter();
1299 tracing::info!(target: "writer2", "hello writer2!");
1300 let span2 = tracing::info_span!(target: "writer2", "writer2_span");
1301 let _e = span2.enter();
1302 tracing::warn!(target: "writer1", "hello writer1!");
1303 });
1304
1305 let actual = sanitize_timings(make_writer1.get_string());
1306 assert_eq!(
1307 "fake time writer1_span{x=42}:writer2_span: hello writer1!\n\
1308 fake time writer1_span{x=42}: close timing timing\n",
1309 actual.as_str()
1310 );
1311 let actual = sanitize_timings(make_writer2.get_string());
1312 assert_eq!(
1313 "fake time writer1_span{x=42}: hello writer2!\n\
1314 fake time writer1_span{x=42}:writer2_span: close timing timing\n",
1315 actual.as_str()
1316 );
1317 }
1318 }