tc_tracing/logging/
directives.rs1use once_cell::sync::OnceCell;
18use parking_lot::Mutex;
19use tracing_subscriber::{
20 filter::Directive, fmt as tracing_fmt, fmt::time::ChronoLocal, layer, reload::Handle,
21 EnvFilter, Registry,
22};
23
24static FILTER_RELOAD_HANDLE: OnceCell<Handle<EnvFilter, SCSubscriber>> = OnceCell::new();
26static DEFAULT_DIRECTIVES: OnceCell<Mutex<Vec<String>>> = OnceCell::new();
28static CURRENT_DIRECTIVES: OnceCell<Mutex<Vec<String>>> = OnceCell::new();
30
31pub(crate) fn add_default_directives(directives: &str) {
37 DEFAULT_DIRECTIVES
38 .get_or_init(|| Mutex::new(Vec::new()))
39 .lock()
40 .push(directives.to_owned());
41 add_directives(directives);
42}
43
44pub fn add_directives(directives: &str) {
46 CURRENT_DIRECTIVES
47 .get_or_init(|| Mutex::new(Vec::new()))
48 .lock()
49 .push(directives.to_owned());
50}
51
52pub(crate) fn parse_default_directive(directive: &str) -> super::Result<Directive> {
56 let dir = directive.parse()?;
57 add_default_directives(directive);
58 Ok(dir)
59}
60
61pub fn reload_filter() -> Result<(), String> {
63 let mut env_filter = EnvFilter::default();
64 if let Some(current_directives) = CURRENT_DIRECTIVES.get() {
65 for directive in current_directives
67 .lock()
68 .join(",")
69 .split(',')
70 .map(|d| d.parse())
71 {
72 match directive {
73 Ok(dir) => env_filter = env_filter.add_directive(dir),
74 Err(invalid_directive) => {
75 log::warn!(
76 target: "tracing",
77 "Unable to parse directive while setting log filter: {:?}",
78 invalid_directive,
79 );
80 }
81 }
82 }
83 }
84 env_filter = env_filter.add_directive(
85 "tc_tracing=trace"
86 .parse()
87 .expect("provided directive is valid"),
88 );
89 log::debug!(target: "tracing", "Reloading log filter with: {}", env_filter);
90 FILTER_RELOAD_HANDLE
91 .get()
92 .ok_or("No reload handle present".to_string())?
93 .reload(env_filter)
94 .map_err(|e| format!("{}", e))
95}
96
97pub fn reset_log_filter() -> Result<(), String> {
101 let directive = DEFAULT_DIRECTIVES
102 .get_or_init(|| Mutex::new(Vec::new()))
103 .lock()
104 .clone();
105
106 *CURRENT_DIRECTIVES
107 .get_or_init(|| Mutex::new(Vec::new()))
108 .lock() = directive;
109 reload_filter()
110}
111
112pub(crate) fn set_reload_handle(handle: Handle<EnvFilter, SCSubscriber>) {
114 let _ = FILTER_RELOAD_HANDLE.set(handle);
115}
116
117type SCSubscriber<
120 N = tracing_fmt::format::DefaultFields,
121 E = crate::logging::EventFormat<ChronoLocal>,
122 W = fn() -> std::io::Stderr,
123> = layer::Layered<tracing_fmt::Layer<Registry, N, E, W>, Registry>;