tracing_subscriber/fmt/
fmt_layer.rs

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