Coverage Report

Created: 2025-10-10 07:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tracing-subscriber-0.3.20/src/util.rs
Line
Count
Source
1
//! Extension traits and other utilities to make working with subscribers more
2
//! ergonomic.
3
use core::fmt;
4
#[cfg(feature = "std")]
5
use std::error::Error;
6
use tracing_core::dispatcher::{self, Dispatch};
7
#[cfg(feature = "tracing-log")]
8
use tracing_log::AsLog;
9
10
/// Extension trait adding utility methods for subscriber initialization.
11
///
12
/// This trait provides extension methods to make configuring and setting a
13
/// [default subscriber] more ergonomic. It is automatically implemented for all
14
/// types that can be converted into a [trace dispatcher]. Since `Dispatch`
15
/// implements `From<T>` for all `T: Subscriber`, all `Subscriber`
16
/// implementations will implement this extension trait as well. Types which
17
/// can be converted into `Subscriber`s, such as builders that construct a
18
/// `Subscriber`, may implement `Into<Dispatch>`, and will also receive an
19
/// implementation of this trait.
20
///
21
/// [default subscriber]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html#setting-the-default-subscriber
22
/// [trace dispatcher]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html
23
pub trait SubscriberInitExt
24
where
25
    Self: Into<Dispatch>,
26
{
27
    /// Sets `self` as the [default subscriber] in the current scope, returning a
28
    /// guard that will unset it when dropped.
29
    ///
30
    /// If the "tracing-log" feature flag is enabled, this will also initialize
31
    /// a [`log`] compatibility layer. This allows the subscriber to consume
32
    /// `log::Record`s as though they were `tracing` `Event`s.
33
    ///
34
    /// [default subscriber]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html#setting-the-default-subscriber
35
    /// [`log`]: https://crates.io/log
36
    #[cfg(feature = "std")]
37
    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
38
0
    fn set_default(self) -> dispatcher::DefaultGuard {
39
        #[cfg(feature = "tracing-log")]
40
        let _ = tracing_log::LogTracer::init();
41
42
0
        dispatcher::set_default(&self.into())
43
0
    }
Unexecuted instantiation: <tracing_subscriber::layer::layered::Layered<tracing_tree::HierarchicalLayer<tracing_subscriber::fmt::writer::TestWriter>, tracing_subscriber::registry::sharded::Registry> as tracing_subscriber::util::SubscriberInitExt>::set_default
Unexecuted instantiation: <_ as tracing_subscriber::util::SubscriberInitExt>::set_default
44
45
    /// Attempts to set `self` as the [global default subscriber] in the current
46
    /// scope, returning an error if one is already set.
47
    ///
48
    /// If the "tracing-log" feature flag is enabled, this will also attempt to
49
    /// initialize a [`log`] compatibility layer. This allows the subscriber to
50
    /// consume `log::Record`s as though they were `tracing` `Event`s.
51
    ///
52
    /// This method returns an error if a global default subscriber has already
53
    /// been set, or if a `log` logger has already been set (when the
54
    /// "tracing-log" feature is enabled).
55
    ///
56
    /// [global default subscriber]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html#setting-the-default-subscriber
57
    /// [`log`]: https://crates.io/log
58
0
    fn try_init(self) -> Result<(), TryInitError> {
59
0
        dispatcher::set_global_default(self.into()).map_err(TryInitError::new)?;
60
61
        // Since we are setting the global default subscriber, we can
62
        // opportunistically go ahead and set its global max level hint as
63
        // the max level for the `log` crate as well. This should make
64
        // skipping `log` diagnostics much faster.
65
        #[cfg(feature = "tracing-log")]
66
        tracing_log::LogTracer::builder()
67
            // Note that we must call this *after* setting the global default
68
            // subscriber, so that we get its max level hint.
69
            .with_max_level(tracing_core::LevelFilter::current().as_log())
70
            .init()
71
            .map_err(TryInitError::new)?;
72
73
0
        Ok(())
74
0
    }
75
76
    /// Attempts to set `self` as the [global default subscriber] in the current
77
    /// scope, panicking if this fails.
78
    ///
79
    /// If the "tracing-log" feature flag is enabled, this will also attempt to
80
    /// initialize a [`log`] compatibility layer. This allows the subscriber to
81
    /// consume `log::Record`s as though they were `tracing` `Event`s.
82
    ///
83
    /// This method panics if a global default subscriber has already been set,
84
    /// or if a `log` logger has already been set (when the "tracing-log"
85
    /// feature is enabled).
86
    ///
87
    /// [global default subscriber]: https://docs.rs/tracing/0.1.21/tracing/dispatcher/index.html#setting-the-default-subscriber
88
    /// [`log`]: https://crates.io/log
89
0
    fn init(self) {
90
0
        self.try_init()
91
0
            .expect("failed to set global default subscriber")
92
0
    }
93
}
94
95
impl<T> SubscriberInitExt for T where T: Into<Dispatch> {}
96
97
/// Error returned by [`try_init`](SubscriberInitExt::try_init) if a global default subscriber could not be initialized.
98
pub struct TryInitError {
99
    #[cfg(feature = "std")]
100
    inner: Box<dyn Error + Send + Sync + 'static>,
101
102
    #[cfg(not(feature = "std"))]
103
    _p: (),
104
}
105
106
// ==== impl TryInitError ====
107
108
impl TryInitError {
109
    #[cfg(feature = "std")]
110
0
    fn new(e: impl Into<Box<dyn Error + Send + Sync + 'static>>) -> Self {
111
0
        Self { inner: e.into() }
112
0
    }
113
114
    #[cfg(not(feature = "std"))]
115
    fn new<T>(_: T) -> Self {
116
        Self { _p: () }
117
    }
118
}
119
120
impl fmt::Debug for TryInitError {
121
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122
        #[cfg(feature = "std")]
123
        {
124
0
            fmt::Debug::fmt(&self.inner, f)
125
        }
126
127
        #[cfg(not(feature = "std"))]
128
        {
129
            f.write_str("TryInitError(())")
130
        }
131
0
    }
132
}
133
134
impl fmt::Display for TryInitError {
135
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136
        #[cfg(feature = "std")]
137
        {
138
0
            fmt::Display::fmt(&self.inner, f)
139
        }
140
141
        #[cfg(not(feature = "std"))]
142
        {
143
            f.write_str("failed to set global default subscriber")
144
        }
145
0
    }
146
}
147
148
#[cfg(feature = "std")]
149
impl Error for TryInitError {
150
0
    fn source(&self) -> Option<&(dyn Error + 'static)> {
151
0
        self.inner.source()
152
0
    }
153
}