use std::sync::Once;
use tracing_subscriber::EnvFilter;
static INIT: Once = Once::new();
pub fn init(verbose: u8) {
INIT.call_once(|| {
#[cfg(feature = "tokio-console")]
if std::env::var("FERRIDRIVER_PROFILE").as_deref() == Ok("console") {
console_subscriber::init();
return;
}
let filter = build_filter(verbose);
let use_ansi = std::io::IsTerminal::is_terminal(&std::io::stderr());
#[cfg(feature = "profiling")]
if std::env::var("FERRIDRIVER_PROFILE").as_deref() == Ok("chrome") {
use tracing_subscriber::prelude::*;
let trace_file =
std::env::var("FERRIDRIVER_TRACE_FILE").unwrap_or_else(|_| format!("trace-{}.json", std::process::id()));
let (chrome_layer, guard) = tracing_chrome::ChromeLayerBuilder::new()
.file(trace_file)
.include_args(true)
.build();
std::mem::forget(guard);
let fmt_layer = tracing_subscriber::fmt::layer()
.with_writer(std::io::stderr)
.with_ansi(use_ansi);
let _ = tracing_subscriber::registry()
.with(filter)
.with(fmt_layer)
.with(chrome_layer)
.try_init();
return;
}
let _ = tracing_subscriber::fmt()
.with_env_filter(filter)
.with_writer(std::io::stderr)
.with_ansi(use_ansi)
.try_init();
});
}
pub fn init_from_env() {
if std::env::var("FERRIDRIVER_DEBUG").is_ok()
|| std::env::var("RUST_LOG").is_ok()
|| std::env::var("FERRIDRIVER_PROFILE").is_ok()
{
init(0);
}
}
fn build_filter(verbose: u8) -> EnvFilter {
if std::env::var("RUST_LOG").is_ok() {
return EnvFilter::from_default_env();
}
if let Ok(debug_val) = std::env::var("FERRIDRIVER_DEBUG") {
return parse_debug_categories(&debug_val);
}
match verbose {
0 => EnvFilter::new("warn"),
1 => EnvFilter::new("warn,ferridriver=debug"),
_ => EnvFilter::new("warn,ferridriver=trace"),
}
}
fn parse_debug_categories(debug_val: &str) -> EnvFilter {
let mut filter = EnvFilter::new("warn");
for category in debug_val.split(',').map(str::trim) {
let directive = match category {
"*" | "all" => "ferridriver=trace",
"cdp" => "ferridriver::cdp=trace",
"step" | "steps" => "ferridriver::bdd::step=trace",
"hook" | "hooks" => "ferridriver::bdd::hook=trace",
"worker" => "ferridriver::worker=trace",
"fixture" => "ferridriver::fixture=trace",
"reporter" => "ferridriver::reporter=trace",
"action" => "ferridriver::action=trace",
"runner" => "ferridriver::runner=trace",
"napi" => "napi=trace",
other => {
let owned = format!("{other}=trace");
filter = filter.add_directive(
owned
.parse()
.unwrap_or_else(|_| "warn".parse().expect("'warn' is a valid directive")),
);
continue;
},
};
filter = filter.add_directive(
directive
.parse()
.unwrap_or_else(|_| "warn".parse().expect("'warn' is a valid directive")),
);
}
filter
}