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}