use tracing_subscriber::EnvFilter;
pub struct TelemetryGuard {
_priv: (),
}
#[must_use]
pub fn init(verbose: bool) -> TelemetryGuard {
match std::env::var("VESSEL_LOG_FORMAT").as_deref() {
Ok("json") => init_json(),
_ => init_fmt(verbose),
}
}
fn init_fmt(verbose: bool) -> TelemetryGuard {
let default = if verbose {
"vessel=debug"
} else {
"vessel=warn"
};
let stderr_filter =
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(default));
if let Some(log_path) = std::env::var("VESSEL_LOG").ok().filter(|s| !s.is_empty()) {
match std::fs::OpenOptions::new()
.create(true)
.append(true)
.open(&log_path)
{
Ok(file) => {
let filter = if verbose {
EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("vessel=debug"))
} else {
EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("vessel=info"))
};
let file = std::sync::Mutex::new(file);
tracing_subscriber::fmt()
.with_env_filter(filter)
.with_ansi(false)
.with_writer(file)
.init();
}
Err(e) => {
eprintln!("warning: VESSEL_LOG={log_path}: {e}");
tracing_subscriber::fmt()
.with_env_filter(stderr_filter)
.with_writer(std::io::stderr)
.init();
}
}
} else {
tracing_subscriber::fmt()
.with_env_filter(stderr_filter)
.with_writer(std::io::stderr)
.init();
}
TelemetryGuard { _priv: () }
}
fn init_json() -> TelemetryGuard {
use tracing_subscriber::layer::SubscriberExt as _;
use tracing_subscriber::util::SubscriberInitExt as _;
let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
tracing_subscriber::registry()
.with(filter)
.with(
tracing_subscriber::fmt::layer()
.json()
.with_writer(std::io::stderr)
.with_span_events(tracing_subscriber::fmt::format::FmtSpan::CLOSE),
)
.init();
TelemetryGuard { _priv: () }
}