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>;