use crate::CorpFinanceResult;
use std::sync::Once;
use tracing_subscriber::{fmt, prelude::*, EnvFilter};
static SUBSCRIBER_INIT: Once = Once::new();
pub fn init_tracing(json: bool, level: &str) -> CorpFinanceResult<()> {
let level = level.to_string();
SUBSCRIBER_INIT.call_once(|| {
let filter =
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(level.as_str()));
if json {
let layer = fmt::layer()
.json()
.with_current_span(true)
.with_span_list(false)
.with_writer(std::io::stderr);
let _ = tracing_subscriber::registry()
.with(filter)
.with(layer)
.try_init();
} else {
let layer = fmt::layer().with_target(true).with_writer(std::io::stderr);
let _ = tracing_subscriber::registry()
.with(filter)
.with(layer)
.try_init();
}
});
Ok(())
}
pub fn init_for_cli() -> CorpFinanceResult<()> {
let level = std::env::var("CFA_LOG_LEVEL").unwrap_or_else(|_| "info".to_string());
let format = std::env::var("CFA_LOG_FORMAT").unwrap_or_else(|_| "text".to_string());
let json = format.eq_ignore_ascii_case("json");
init_tracing(json, &level)
}
pub fn init_for_mcp() -> CorpFinanceResult<()> {
let level = std::env::var("CFA_LOG_LEVEL").unwrap_or_else(|_| "info".to_string());
init_tracing(true, &level)
}
pub fn init_for_test() -> CorpFinanceResult<()> {
init_tracing(false, "trace")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn init_for_test_is_idempotent() {
init_for_test().expect("first init");
init_for_test().expect("second init");
init_for_test().expect("third init");
}
#[test]
fn init_tracing_with_explicit_level() {
init_tracing(false, "debug").expect("init_tracing");
init_tracing(true, "info").expect("second init_tracing");
}
}