tracing_subscriber_init/format/
compact.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::{Compact, DefaultFields, Format},
16    },
17};
18
19use crate::{TracingConfig, utils::get_effective_level};
20
21/// Create a [`Compact`](tracing_subscriber::fmt::format::Compact) 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::{compact, set_default, TestAll, TracingConfig};
29/// #
30/// # pub fn main() -> Result<()> {
31/// let config = TestAll;
32/// let (layer, level_filter) = compact(&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 compact<C, S>(config: &C) -> (fmt::Layer<S, DefaultFields, Format<Compact>>, LevelFilter)
40where
41    C: TracingConfig,
42    S: Subscriber,
43    for<'a> S: tracing_subscriber::registry::LookupSpan<'a>,
44{
45    let layer = fmt::layer()
46        .compact()
47        .with_ansi(config.with_ansi())
48        .with_file(config.with_file())
49        .with_level(config.with_level())
50        .with_target(config.with_target())
51        .with_thread_ids(config.with_thread_ids())
52        .with_thread_names(config.with_thread_names())
53        .with_line_number(config.with_line_number());
54    let layer = if let Some(fmt_span) = config.with_span_events() {
55        layer.with_span_events(fmt_span)
56    } else {
57        layer
58    };
59    let level = get_effective_level(config.quiet(), config.verbose());
60    let level_filter = LevelFilter::from(level);
61    (layer, level_filter)
62}
63
64/// Create a [`Compact`](tracing_subscriber::fmt::format::Compact) format filtered layer configured from the given [`TracingConfig`].
65///
66/// # Example
67/// ```rust
68/// # use anyhow::Result;
69/// # use tracing::info;
70/// # use tracing_subscriber::Layer;
71/// # use tracing_subscriber_init::{compact_filtered, set_default, TestAll, TracingConfig};
72/// #
73/// # pub fn main() -> Result<()> {
74/// let config = TestAll;
75/// let layer = compact_filtered(&config);
76/// let _unused = set_default(vec![layer.boxed()]);
77/// info!("info level");
78/// #   Ok(())
79/// # }
80/// ```
81pub fn filtered<C, S>(
82    config: &C,
83) -> Filtered<fmt::Layer<S, DefaultFields, Format<Compact>>, LevelFilter, S>
84where
85    C: TracingConfig,
86    S: Subscriber,
87    for<'a> S: tracing_subscriber::registry::LookupSpan<'a>,
88{
89    let (layer, level_filter) = compact(config);
90    layer.with_filter(level_filter)
91}
92
93#[cfg(test)]
94mod test {
95    use tracing::{Level, debug, error, info, span, trace, warn};
96    use tracing_subscriber::Layer;
97
98    use super::filtered as compact_filtered;
99
100    use crate::{TestAll, set_default, utils::test::TestConfig};
101
102    #[test]
103    fn compact_filtered_works() {
104        let config = TestConfig;
105        let layer = compact_filtered(&config);
106        let _unused = set_default(vec![layer.boxed()]);
107        let span = span!(Level::INFO, "compact_filtered_works");
108        let _enter = span.enter();
109        error!("error level");
110        warn!("warn level");
111        info!("info level");
112        debug!("debug level");
113        trace!("trace level");
114    }
115
116    #[test]
117    fn compact_filtered_all_works() {
118        let config = TestAll;
119        let layer = compact_filtered(&config);
120        let _unused = set_default(vec![layer.boxed()]);
121        let span = span!(Level::TRACE, "compact_filtered_all_works");
122        let _enter = span.enter();
123        error!("error level");
124        warn!("warn level");
125        info!("info level");
126        debug!("debug level");
127        trace!("trace level");
128    }
129
130    #[cfg(feature = "tstime")]
131    #[test]
132    fn compact_utc_works() {
133        use super::compact;
134        use time::format_description::well_known::Iso8601;
135        use tracing_subscriber::fmt::time::UtcTime;
136
137        let config = TestConfig;
138        let (layer, level_filter) = compact(&config);
139        let filtered_layer = layer
140            .with_timer(UtcTime::new(Iso8601::DEFAULT))
141            .with_filter(level_filter);
142        let _unused = set_default(vec![filtered_layer.boxed()]);
143        let span = span!(Level::INFO, "compact_utc_works");
144        let _enter = span.enter();
145        error!("error level");
146        warn!("warn level");
147        info!("info level");
148        debug!("debug level");
149        trace!("trace level");
150    }
151}