use std::env;
use clap::Parser;
use tracing::Level;
use tracing::metadata::LevelFilter;
use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitExt};
fn get_levels(bin: &str, cli_level: Option<Level>) -> String {
let env_level = env::var("RUST_LOG").ok();
let Some(cli_level) = cli_level else {
return env_level.unwrap_or_default();
};
let level_str = format!(
"{bin}={level},hickory={level}",
level = cli_level.to_string().to_lowercase(),
);
match env_level {
Some(env_level) => format!("{level_str},{env_level}"),
None => level_str,
}
}
pub fn logger(bin: &str, cli_level: Option<Level>) {
let subscriber = EnvFilter::builder()
.with_default_directive(LevelFilter::OFF.into())
.parse(get_levels(bin, cli_level))
.expect("failed to configure tracing/logging");
tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer().compact())
.with(subscriber)
.init();
}
#[derive(Debug, Parser)]
pub struct LogConfig {
#[clap(long)]
trace: bool,
#[clap(long)]
debug: bool,
#[clap(long)]
info: bool,
#[clap(long)]
warn: bool,
#[clap(long)]
error: bool,
}
impl LogConfig {
pub fn level(&self) -> Option<Level> {
Some(if self.trace {
Level::TRACE
} else if self.debug {
Level::DEBUG
} else if self.info {
Level::INFO
} else if self.warn {
Level::WARN
} else if self.error {
Level::ERROR
} else {
return None;
})
}
}