sc_tracing/logging/
directives.rs1use parking_lot::Mutex;
18use std::sync::OnceLock;
19use tracing_subscriber::{
20 filter::Directive, fmt as tracing_fmt, layer, reload::Handle, EnvFilter, Registry,
21};
22
23static FILTER_RELOAD_HANDLE: OnceLock<Handle<EnvFilter, SCSubscriber>> = OnceLock::new();
25static DEFAULT_DIRECTIVES: OnceLock<Mutex<Vec<String>>> = OnceLock::new();
27static CURRENT_DIRECTIVES: OnceLock<Mutex<Vec<String>>> = OnceLock::new();
29
30pub(crate) fn add_default_directives(directives: &str) {
36 DEFAULT_DIRECTIVES
37 .get_or_init(|| Mutex::new(Vec::new()))
38 .lock()
39 .push(directives.to_owned());
40 add_directives(directives);
41}
42
43pub fn add_directives(directives: &str) {
45 CURRENT_DIRECTIVES
46 .get_or_init(|| Mutex::new(Vec::new()))
47 .lock()
48 .push(directives.to_owned());
49}
50
51pub(crate) fn parse_default_directive(directive: &str) -> super::Result<Directive> {
55 let dir = directive.parse()?;
56 add_default_directives(directive);
57 Ok(dir)
58}
59
60pub fn reload_filter() -> Result<(), String> {
62 let mut env_filter = EnvFilter::default();
63 if let Some(current_directives) = CURRENT_DIRECTIVES.get() {
64 for directive in current_directives.lock().join(",").split(',').map(|d| d.parse()) {
66 match directive {
67 Ok(dir) => env_filter = env_filter.add_directive(dir),
68 Err(invalid_directive) => {
69 log::warn!(
70 target: "tracing",
71 "Unable to parse directive while setting log filter: {:?}",
72 invalid_directive,
73 );
74 },
75 }
76 }
77 }
78
79 let max_level_hint =
81 tracing_subscriber::Layer::<tracing_subscriber::FmtSubscriber>::max_level_hint(&env_filter);
82 log::set_max_level(super::to_log_level_filter(max_level_hint));
83
84 log::debug!(target: "tracing", "Reloading log filter with: {}", env_filter);
85 FILTER_RELOAD_HANDLE
86 .get()
87 .ok_or("No reload handle present")?
88 .reload(env_filter)
89 .map_err(|e| format!("{}", e))
90}
91
92pub fn reset_log_filter() -> Result<(), String> {
96 let directive = DEFAULT_DIRECTIVES.get_or_init(|| Mutex::new(Vec::new())).lock().clone();
97
98 *CURRENT_DIRECTIVES.get_or_init(|| Mutex::new(Vec::new())).lock() = directive;
99 reload_filter()
100}
101
102pub(crate) fn set_reload_handle(handle: Handle<EnvFilter, SCSubscriber>) {
104 let _ = FILTER_RELOAD_HANDLE.set(handle);
105}
106
107type SCSubscriber<
110 N = tracing_fmt::format::DefaultFields,
111 E = crate::logging::EventFormat,
112 W = crate::logging::DefaultLogger,
113> = layer::Layered<tracing_fmt::Layer<Registry, N, E, W>, Registry>;