tracing_subscriber_init/format/
full.rs

1// Copyright (c) 2023 tracing-subscriber-init developers
2//
3// Licensed under the Apache License, Version 2.0
4// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0> or the MIT
5// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. All files in the project carrying such notice may not be copied,
7// modified, or distributed except according to those terms.
8
9use tracing::{Subscriber, metadata::LevelFilter};
10use tracing_subscriber::{
11    Layer,
12    filter::Filtered,
13    fmt::{
14        self,
15        format::{DefaultFields, Format, Full},
16    },
17};
18
19use crate::{TracingConfig, utils::get_effective_level};
20
21/// Create a [`Full`](tracing_subscriber::fmt::format::Full) format layer configured from the given [`TracingConfig`].
22///
23/// # Example
24/// ```rust
25/// # use anyhow::Result;
26/// # use tracing::info;
27/// # use tracing_subscriber::Layer;
28/// # use tracing_subscriber_init::{full, set_default, TestAll, TracingConfig};
29/// #
30/// # pub fn main() -> Result<()> {
31/// let config = TestAll;
32/// let (layer, level_filter) = full(&config);
33/// let layer = layer.with_filter(level_filter);
34/// let _unused = set_default(vec![layer.boxed()]);
35/// info!("info level");
36/// #   Ok(())
37/// # }
38/// ```
39pub fn full<C, S>(config: &C) -> (fmt::Layer<S, DefaultFields, Format<Full>>, LevelFilter)
40where
41    C: TracingConfig,
42    S: Subscriber,
43    for<'a> S: tracing_subscriber::registry::LookupSpan<'a>,
44{
45    let layer = fmt::layer()
46        .with_ansi(config.with_ansi())
47        .with_file(config.with_file())
48        .with_level(config.with_level())
49        .with_target(config.with_target())
50        .with_thread_ids(config.with_thread_ids())
51        .with_thread_names(config.with_thread_names())
52        .with_line_number(config.with_line_number());
53    let layer = if let Some(fmt_span) = config.with_span_events() {
54        layer.with_span_events(fmt_span)
55    } else {
56        layer
57    };
58    let level = get_effective_level(config.quiet(), config.verbose());
59    let level_filter = LevelFilter::from(level);
60    (layer, level_filter)
61}
62
63/// Create a [`Full`](tracing_subscriber::fmt::format::Full) format filtered layer configured from the given [`TracingConfig`].
64///
65/// # Example
66/// ```rust
67/// # use anyhow::Result;
68/// # use tracing::info;
69/// # use tracing_subscriber::Layer;
70/// # use tracing_subscriber_init::{full_filtered, set_default, TestAll, TracingConfig};
71/// #
72/// # pub fn main() -> Result<()> {
73/// let config = TestAll;
74/// let layer = full_filtered(&config);
75/// let _unused = set_default(vec![layer.boxed()]);
76/// info!("info level");
77/// #   Ok(())
78/// # }
79/// ```
80pub fn filtered<C, S>(
81    config: &C,
82) -> Filtered<fmt::Layer<S, DefaultFields, Format<Full>>, LevelFilter, S>
83where
84    C: TracingConfig,
85    S: Subscriber,
86    for<'a> S: tracing_subscriber::registry::LookupSpan<'a>,
87{
88    let (layer, level_filter) = full(config);
89    layer.with_filter(level_filter)
90}
91
92#[cfg(test)]
93mod test {
94    use tracing::{Level, debug, error, info, span, trace, warn};
95    use tracing_subscriber::Layer;
96
97    use super::filtered as full_filtered;
98
99    use crate::{TestAll, set_default, utils::test::TestConfig};
100
101    #[test]
102    fn full_filtered_works() {
103        let config = TestConfig;
104        let layer = full_filtered(&config);
105        let _unused = set_default(vec![layer.boxed()]);
106        let span = span!(Level::INFO, "full_filtered_works");
107        let _enter = span.enter();
108        error!("error level");
109        warn!("warn level");
110        info!("info level");
111        debug!("debug level");
112        trace!("trace level");
113    }
114
115    #[test]
116    fn full_filtered_all_works() {
117        let config = TestAll;
118        let layer = full_filtered(&config);
119        let _unused = set_default(vec![layer.boxed()]);
120        let span = span!(Level::TRACE, "full_filtered_all_works");
121        let _enter = span.enter();
122        error!("error level");
123        warn!("warn level");
124        info!("info level");
125        debug!("debug level");
126        trace!("trace level");
127    }
128
129    #[cfg(feature = "tstime")]
130    #[test]
131    fn full_utc_works() {
132        use super::full;
133        use time::format_description::well_known::Iso8601;
134        use tracing_subscriber::fmt::time::UtcTime;
135
136        let config = TestConfig;
137        let (layer, level_filter) = full(&config);
138        let filtered_layer = layer
139            .with_timer(UtcTime::new(Iso8601::DEFAULT))
140            .with_filter(level_filter);
141        let _unused = set_default(vec![filtered_layer.boxed()]);
142        let span = span!(Level::INFO, "full_utc_works");
143        let _enter = span.enter();
144        error!("error level");
145        warn!("warn level");
146        info!("info level");
147        debug!("debug level");
148        trace!("trace level");
149    }
150}