sc_tracing/logging/
directives.rs1use parking_lot::Mutex;
19use std::sync::OnceLock;
20use tracing_subscriber::{
21 filter::Directive, fmt as tracing_fmt, layer, reload::Handle, EnvFilter, Registry,
22};
23
24static FILTER_RELOAD_HANDLE: OnceLock<Handle<EnvFilter, SCSubscriber>> = OnceLock::new();
26static DEFAULT_DIRECTIVES: OnceLock<Mutex<Vec<String>>> = OnceLock::new();
28static CURRENT_DIRECTIVES: OnceLock<Mutex<Vec<String>>> = OnceLock::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 fn get_directives() -> Vec<String> {
54 CURRENT_DIRECTIVES.get_or_init(|| Mutex::new(Vec::new())).lock().clone()
55}
56
57pub(crate) fn parse_default_directive(directive: &str) -> super::Result<Directive> {
61 let dir = directive.parse()?;
62 add_default_directives(directive);
63 Ok(dir)
64}
65
66pub fn reload_filter() -> Result<(), String> {
68 let mut env_filter = EnvFilter::default();
69 if let Some(current_directives) = CURRENT_DIRECTIVES.get() {
70 for directive in current_directives.lock().join(",").split(',').map(|d| d.parse()) {
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
85 let max_level_hint =
87 tracing_subscriber::Layer::<tracing_subscriber::FmtSubscriber>::max_level_hint(&env_filter);
88 log::set_max_level(super::to_log_level_filter(max_level_hint));
89
90 log::debug!(target: "tracing", "Reloading log filter with: {}", env_filter);
91 FILTER_RELOAD_HANDLE
92 .get()
93 .ok_or("No reload handle present")?
94 .reload(env_filter)
95 .map_err(|e| format!("{}", e))
96}
97
98pub fn reset_log_filter() -> Result<(), String> {
102 let directive = DEFAULT_DIRECTIVES.get_or_init(|| Mutex::new(Vec::new())).lock().clone();
103
104 *CURRENT_DIRECTIVES.get_or_init(|| Mutex::new(Vec::new())).lock() = directive;
105 reload_filter()
106}
107
108pub(crate) fn set_reload_handle(handle: Handle<EnvFilter, SCSubscriber>) {
110 let _ = FILTER_RELOAD_HANDLE.set(handle);
111}
112
113type SCSubscriber<
116 N = tracing_fmt::format::DefaultFields,
117 E = crate::logging::EventFormat,
118 W = crate::logging::DefaultLogger,
119> = layer::Layered<tracing_fmt::Layer<Registry, N, E, W>, Registry>;