use anyhow::{Context, Result};
use std::fs;
use std::path::PathBuf;
use std::sync::OnceLock;
use tracing_appender::non_blocking::WorkerGuard;
use tracing_subscriber::{EnvFilter, fmt, layer::SubscriberExt, util::SubscriberInitExt};
static LOG_GUARD: OnceLock<WorkerGuard> = OnceLock::new();
pub fn init_stderr_if_enabled() {
if std::env::var("RUST_LOG").is_err() {
return;
}
let filter = EnvFilter::from_default_env();
let stderr_layer = fmt::layer()
.with_writer(std::io::stderr)
.with_target(false)
.without_time();
let _ = tracing_subscriber::registry()
.with(filter)
.with(stderr_layer)
.try_init();
}
pub fn init(dbdir: &PathBuf, log_level: &str) -> Result<()> {
fs::create_dir_all(dbdir).with_context(|| format!("Failed to create dbdir {:?}", dbdir))?;
let file_appender = tracing_appender::rolling::never(dbdir, "bob.log");
let (non_blocking, guard) = tracing_appender::non_blocking(file_appender);
LOG_GUARD
.set(guard)
.map_err(|_| anyhow::anyhow!("Logging already initialized"))?;
let file_layer = fmt::layer()
.json()
.with_writer(non_blocking)
.with_target(true)
.with_thread_ids(false)
.with_thread_names(false)
.with_file(false)
.with_line_number(false)
.with_span_list(false);
let default_filter = format!("bob={}", log_level);
let filter =
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(&default_filter));
tracing_subscriber::registry()
.with(filter)
.with(file_layer)
.init();
tracing::info!(dbdir = %dbdir.display(),
log_level = log_level,
"Logging initialized"
);
Ok(())
}