use tracing_subscriber::{
filter, fmt,
prelude::*,
reload::{self},
};
pub use tracing::Level;
pub fn init_log(
global: bool,
file: String,
time_format: String,
) -> (
Box<dyn Fn(Level) + Send + Sync + 'static>,
tracing_appender::non_blocking::WorkerGuard,
) {
let format_str: &'static str = Box::leak(time_format.into_boxed_str());
let format = time::format_description::parse(format_str)
.expect("Invalid time format")
.to_owned();
let timer = tracing_subscriber::fmt::time::UtcTime::new(format);
let stdout = file == "";
let (writer, guard) = if stdout {
let (writer, guard) = tracing_appender::non_blocking(std::io::stdout());
(writer, guard)
} else {
let (dir, file_name) = match file.rfind('/') {
Some(idx) => {
let (dir, file) = file.split_at(idx);
let file_name = &file[1..];
(dir, file_name)
}
None => ("", file.as_str()),
};
let file_appender = tracing_appender::rolling::never(dir, file_name);
let (writer, guard) = tracing_appender::non_blocking(file_appender);
(writer, guard)
};
let layer = fmt::Layer::default()
.with_timer(timer)
.with_file(false)
.with_line_number(false)
.with_writer(writer)
.with_ansi(stdout);
let (layer, _reload_layer_handle) = reload::Layer::new(layer);
let filter = filter::LevelFilter::WARN;
let (filter, reload_filter) = reload::Layer::new(filter);
let reg = tracing_subscriber::registry().with(filter).with(layer);
if global {
reg.init()
}
return (
Box::new(move |level: Level| {
let _ = reload_filter.modify(|filter| *filter = level.into());
}),
guard,
);
}