tracing_subscriber_init/format/
json.rs1use tracing::{Subscriber, metadata::LevelFilter};
10use tracing_subscriber::{
11 Layer,
12 filter::Filtered,
13 fmt::{
14 self,
15 format::{Format, Json, JsonFields},
16 },
17};
18
19use crate::{TracingConfig, utils::get_effective_level};
20
21#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
22pub fn json<C, S>(config: &C) -> (fmt::Layer<S, JsonFields, Format<Json>>, LevelFilter)
41where
42 C: TracingConfig,
43 S: Subscriber,
44 for<'a> S: tracing_subscriber::registry::LookupSpan<'a>,
45{
46 let layer = fmt::layer()
47 .json()
48 .with_ansi(config.with_ansi())
49 .with_file(config.with_file())
50 .with_level(config.with_level())
51 .with_target(config.with_target())
52 .with_thread_ids(config.with_thread_ids())
53 .with_thread_names(config.with_thread_names())
54 .with_line_number(config.with_line_number())
55 .with_current_span(config.with_current_span())
56 .with_span_list(config.with_span_list());
57
58 let layer = if let Some(fmt_span) = config.with_span_events() {
59 layer.with_span_events(fmt_span)
60 } else {
61 layer
62 };
63 let level = get_effective_level(config.quiet(), config.verbose());
64 let level_filter = LevelFilter::from(level);
65 (layer, level_filter)
66}
67
68#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
69pub fn filtered<C, S>(
87 config: &C,
88) -> Filtered<fmt::Layer<S, JsonFields, Format<Json>>, LevelFilter, S>
89where
90 C: TracingConfig,
91 S: Subscriber,
92 for<'a> S: tracing_subscriber::registry::LookupSpan<'a>,
93{
94 let (layer, level_filter) = json(config);
95 layer.with_filter(level_filter)
96}
97
98#[cfg(test)]
99mod test {
100 use tracing::{Level, debug, error, info, span, trace, warn};
101 use tracing_subscriber::Layer;
102
103 use super::filtered as json_filtered;
104
105 use crate::{TestAll, set_default, utils::test::TestConfig};
106
107 #[test]
108 fn json_filtered_works() {
109 let config = TestConfig;
110 let layer = json_filtered(&config);
111 let _unused = set_default(vec![layer.boxed()]);
112 let span = span!(Level::INFO, "json_filtered_works");
113 let _enter = span.enter();
114 error!("error level");
115 warn!("warn level");
116 info!("info level");
117 debug!("debug level");
118 trace!("trace level");
119 }
120
121 #[test]
122 fn json_filtered_all_works() {
123 let config = TestAll;
124 let layer = json_filtered(&config);
125 let _unused = set_default(vec![layer.boxed()]);
126 let span = span!(Level::TRACE, "json_filtered_all_works");
127 let _enter = span.enter();
128 error!("error level");
129 warn!("warn level");
130 info!("info level");
131 debug!("debug level");
132 trace!("trace level");
133 }
134
135 #[cfg(feature = "tstime")]
136 #[test]
137 fn json_utc_works() {
138 use super::json;
139 use time::format_description::well_known::Iso8601;
140 use tracing_subscriber::fmt::time::UtcTime;
141
142 let config = TestConfig;
143 let (layer, level_filter) = json(&config);
144 let filtered_layer = layer
145 .with_timer(UtcTime::new(Iso8601::DEFAULT))
146 .with_filter(level_filter);
147 let _unused = set_default(vec![filtered_layer.boxed()]);
148 let span = span!(Level::INFO, "json_utc_works");
149 let _enter = span.enter();
150 error!("error level");
151 warn!("warn level");
152 info!("info level");
153 debug!("debug level");
154 trace!("trace level");
155 }
156}