json_subscriber/fmt/
mod.rs

1//! This module only provides compatibility with `tracing-subscriber`. The methods here are just
2//! copies that only use different types for the [`Subscriber`] and [`SubscriberBuilder`].
3
4use std::error::Error;
5
6pub use builder::SubscriberBuilder;
7pub use layer::Layer;
8use tracing::Subscriber as Collect;
9use tracing_subscriber::{registry::LookupSpan, util::SubscriberInitExt};
10
11mod builder;
12mod layer;
13mod names;
14
15/// Returns a new [`SubscriberBuilder`] for configuring a json [formatting subscriber].
16///
17/// This is essentially shorthand for [`SubscriberBuilder::default()`].
18///
19/// # Examples
20///
21/// Using [`init`] to set the default subscriber:
22///
23/// ```rust
24/// json_subscriber::fmt().init();
25/// ```
26///
27/// Configuring the output format:
28///
29/// ```rust
30/// 
31/// json_subscriber::fmt()
32///     // Configure formatting settings.
33///     .with_target(false)
34///     .with_timer(tracing_subscriber::fmt::time::uptime())
35///     .with_level(true)
36///     // Set the subscriber as the default.
37///     .init();
38/// ```
39///
40/// [`try_init`] returns an error if the default subscriber could not be set:
41///
42/// ```rust
43/// use std::error::Error;
44///
45/// fn init_subscriber() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
46///     tracing_subscriber::fmt()
47///         // Configure the subscriber to emit logs in JSON format.
48///         .json()
49///         // Configure the subscriber to flatten event fields in the output JSON objects.
50///         .flatten_event(true)
51///         // Set the subscriber as the default, returning an error if this fails.
52///         .try_init()?;
53///
54///     Ok(())
55/// }
56/// ```
57///
58/// Rather than setting the subscriber as the default, [`finish`] _returns_ the
59/// constructed subscriber, which may then be passed to other functions:
60///
61/// ```rust
62/// let subscriber = tracing_subscriber::fmt()
63///     .with_max_level(tracing::Level::DEBUG)
64///     .compact()
65///     .finish();
66///
67/// tracing::subscriber::with_default(subscriber, || {
68///     // the subscriber will only be set as the default
69///     // inside this closure...
70/// })
71/// ```
72///
73/// [formatting subscriber]: tracing::Subscriber
74/// [`SubscriberBuilder::default()`]: SubscriberBuilder::default
75/// [`init`]: SubscriberBuilder::init()
76/// [`try_init`]: SubscriberBuilder::try_init()
77/// [`finish`]: SubscriberBuilder::finish()
78#[must_use]
79pub fn fmt() -> SubscriberBuilder {
80    SubscriberBuilder::default()
81}
82
83/// Returns a new [json formatting layer] that can be [composed] with other layers to construct a
84/// [`Subscriber`].
85///
86/// This layer is primarily for compatibility with `tracing_subscriber`, if you need more control
87/// over the output, [`JsonLayer`](crate::JsonLayer) can be used instead.
88///
89/// [json formatting layer]: Layer
90/// [composed]: tracing_subscriber::layer
91/// [`Layer::default()`]: Layer::default
92#[must_use]
93pub fn layer<S>() -> Layer<S>
94where
95    S: Collect + for<'lookup> LookupSpan<'lookup>,
96{
97    Layer::default()
98}
99
100/// A type that can be used to create a [`Subscriber`](tracing::Subscriber) which collects tracing
101/// spans and events and emits them in JSON.
102///
103/// This type is actually ZST and is only useful to call [`builder`](fn@Self::builder) to configure
104/// a subscriber.
105pub struct Subscriber;
106
107impl Subscriber {
108    /// Creates a [`SubscriberBuilder`] which can be used to configure a [`Subscriber`].
109    ///
110    /// # Examples
111    ///
112    /// ```rust
113    /// # use json_subscriber::fmt::Subscriber;
114    /// let subscriber = Subscriber::builder()
115    ///     .with_max_level(tracing::Level::INFO)
116    ///     .with_target(false)
117    ///     .finish();
118    /// ```
119    #[must_use]
120    pub fn builder() -> SubscriberBuilder {
121        SubscriberBuilder::default()
122    }
123}
124
125/// Install a global tracing subscriber that listens for events and
126/// filters based on the value of the [`RUST_LOG` environment variable],
127/// if one is not already set.
128///
129/// If the `tracing-log` feature is enabled, this will also install
130/// the [`LogTracer`] to convert `log` records into `tracing` `Event`s.
131///
132/// This is shorthand for
133///
134/// ```rust
135/// # fn doc() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
136/// json_subscriber::fmt().try_init()
137/// # }
138/// ```
139///
140///
141/// # Errors
142///
143/// Returns an Error if the initialization was unsuccessful,
144/// likely because a global subscriber was already installed by another
145/// call to `try_init`.
146///
147/// [`LogTracer`]:
148///     https://docs.rs/tracing-log/0.1.0/tracing_log/struct.LogTracer.html
149/// [`RUST_LOG` environment variable]: tracing_subscriber::EnvFilter::DEFAULT_ENV
150pub fn try_init() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
151    let builder = Subscriber::builder();
152
153    #[cfg(feature = "env-filter")]
154    let builder = builder.with_env_filter(tracing_subscriber::EnvFilter::from_default_env());
155
156    // If `env-filter` is disabled, remove the default max level filter from the
157    // subscriber; it will be added to the `Targets` filter instead if no filter
158    // is set in `RUST_LOG`.
159    // Replacing the default `LevelFilter` with an `EnvFilter` would imply this,
160    // but we can't replace the builder's filter with a `Targets` filter yet.
161    #[cfg(not(feature = "env-filter"))]
162    let builder = builder.with_max_level(tracing_core::LevelFilter::TRACE);
163
164    let subscriber = builder.finish();
165    #[cfg(not(feature = "env-filter"))]
166    let subscriber = {
167        use std::{env, str::FromStr};
168
169        use tracing_subscriber::{filter::Targets, layer::SubscriberExt};
170        let targets = match env::var("RUST_LOG") {
171            Ok(var) => {
172                Targets::from_str(&var)
173                    .map_err(|error| {
174                        eprintln!("Ignoring `RUST_LOG={var:?}`: {error}");
175                    })
176                    .unwrap_or_default()
177            },
178            Err(env::VarError::NotPresent) => {
179                Targets::new().with_default(tracing_core::LevelFilter::INFO)
180            },
181            Err(error) => {
182                eprintln!("Ignoring `RUST_LOG`: {error}");
183                Targets::new().with_default(tracing_core::LevelFilter::INFO)
184            },
185        };
186        subscriber.with(targets)
187    };
188
189    subscriber.try_init().map_err(Into::into)
190}
191
192/// Install a global tracing subscriber that listens for events and
193/// filters based on the value of the [`RUST_LOG` environment variable].
194///
195/// The configuration of the subscriber initialized by this function
196/// depends on what [feature flags](crate#feature-flags) are enabled.
197///
198/// If the `tracing-log` feature is enabled, this will also install
199/// the `LogTracer` to convert `Log` records into `tracing` `Event`s.
200///
201/// If the `env-filter` feature is enabled, this is shorthand for
202///
203/// ```rust
204/// # use tracing_subscriber::EnvFilter;
205/// #[cfg(feature = "env-filter")]
206/// json_subscriber::fmt()
207///     .with_env_filter(EnvFilter::from_default_env())
208///     .init();
209/// ```
210///
211/// # Panics
212/// Panics if the initialization was unsuccessful, likely because a
213/// global subscriber was already installed by another call to `try_init`.
214///
215/// [`RUST_LOG` environment variable]: tracing_subscriber::EnvFilter::DEFAULT_ENV
216pub fn init() {
217    try_init().expect("Unable to install global subscriber");
218}