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