1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use once_cell::sync::OnceCell;
use parking_lot::Mutex;
use tracing_subscriber::{
filter::Directive, fmt as tracing_fmt, fmt::time::ChronoLocal, layer, reload::Handle,
EnvFilter, Registry,
};
static FILTER_RELOAD_HANDLE: OnceCell<Handle<EnvFilter, SCSubscriber>> = OnceCell::new();
static DEFAULT_DIRECTIVES: OnceCell<Mutex<Vec<String>>> = OnceCell::new();
static CURRENT_DIRECTIVES: OnceCell<Mutex<Vec<String>>> = OnceCell::new();
pub(crate) fn add_default_directives(directives: &str) {
DEFAULT_DIRECTIVES
.get_or_init(|| Mutex::new(Vec::new()))
.lock()
.push(directives.to_owned());
add_directives(directives);
}
pub fn add_directives(directives: &str) {
CURRENT_DIRECTIVES
.get_or_init(|| Mutex::new(Vec::new()))
.lock()
.push(directives.to_owned());
}
pub(crate) fn parse_default_directive(directive: &str) -> super::Result<Directive> {
let dir = directive.parse()?;
add_default_directives(directive);
Ok(dir)
}
pub fn reload_filter() -> Result<(), String> {
let mut env_filter = EnvFilter::default();
if let Some(current_directives) = CURRENT_DIRECTIVES.get() {
for directive in current_directives.lock().join(",").split(',').map(|d| d.parse()) {
match directive {
Ok(dir) => env_filter = env_filter.add_directive(dir),
Err(invalid_directive) => {
log::warn!(
target: "tracing",
"Unable to parse directive while setting log filter: {:?}",
invalid_directive,
);
},
}
}
}
let max_level_hint =
tracing_subscriber::Layer::<tracing_subscriber::FmtSubscriber>::max_level_hint(&env_filter);
log::set_max_level(super::to_log_level_filter(max_level_hint));
log::debug!(target: "tracing", "Reloading log filter with: {}", env_filter);
FILTER_RELOAD_HANDLE
.get()
.ok_or("No reload handle present".to_string())?
.reload(env_filter)
.map_err(|e| format!("{}", e))
}
pub fn reset_log_filter() -> Result<(), String> {
let directive = DEFAULT_DIRECTIVES.get_or_init(|| Mutex::new(Vec::new())).lock().clone();
*CURRENT_DIRECTIVES.get_or_init(|| Mutex::new(Vec::new())).lock() = directive;
reload_filter()
}
pub(crate) fn set_reload_handle(handle: Handle<EnvFilter, SCSubscriber>) {
let _ = FILTER_RELOAD_HANDLE.set(handle);
}
type SCSubscriber<
N = tracing_fmt::format::DefaultFields,
E = crate::logging::EventFormat<ChronoLocal>,
W = fn() -> std::io::Stderr,
> = layer::Layered<tracing_fmt::Layer<Registry, N, E, W>, Registry>;