use std::io;
use log::LevelFilter as LogLevelFilter;
use tracing::metadata::LevelFilter;
use tracing_subscriber::{
EnvFilter, Registry, fmt,
layer::Layered,
prelude::*,
reload::{self, Handle},
util::TryInitError,
};
type ReloadHandle = Handle<LevelFilter, Layered<EnvFilter, Registry, Registry>>;
pub fn setup(crate_name: &str) -> Result<ReloadHandle, TryInitError> {
let level_filter = LevelFilter::TRACE;
let (filter, reload_handle_filter) = reload::Layer::new(level_filter);
let l_stderr = fmt::layer().map_writer(move |_| io::stderr);
let crate_name_snake = crate_name.replace('-', "_");
let registry = tracing_subscriber::registry()
.with(
EnvFilter::try_from_default_env()
.unwrap_or_else(|_| format!("{crate_name_snake}=trace,tower_http=debug").into()),
)
.with(filter)
.with(l_stderr);
registry.try_init()?;
Ok(reload_handle_filter)
}
pub fn set_log_level_tracing(
reload_handle: &ReloadHandle,
level: LevelFilter,
) -> Result<(), tracing_subscriber::reload::Error> {
reload_handle.modify(|filter| *filter = level)
}
const fn convert_to_tracing(level: LogLevelFilter) -> LevelFilter {
match level {
LogLevelFilter::Off => LevelFilter::OFF,
LogLevelFilter::Error => LevelFilter::ERROR,
LogLevelFilter::Warn => LevelFilter::WARN,
LogLevelFilter::Info => LevelFilter::INFO,
LogLevelFilter::Debug => LevelFilter::DEBUG,
LogLevelFilter::Trace => LevelFilter::TRACE,
}
}
pub fn set_log_level(
reload_handle: &ReloadHandle,
level: LogLevelFilter,
) -> Result<(), tracing_subscriber::reload::Error> {
set_log_level_tracing(reload_handle, convert_to_tracing(level))
}