use std::sync::Arc;
use arc_swap::ArcSwap;
use tracing_subscriber::prelude::*;
use tracing_subscriber::{EnvFilter, fmt};
use crate::config::Config;
use crate::error::ItraceError;
use crate::formatter::ItraceFormatter;
pub struct Builder {
tracer_name: String,
use_env: bool,
}
impl Default for Builder {
fn default() -> Self {
Self::new()
}
}
impl Builder {
pub fn new() -> Self {
Self {
tracer_name: "default".to_string(),
use_env: false,
}
}
pub fn tracer(mut self, name: &str) -> Self {
self.tracer_name = name.to_string();
self
}
pub fn from_env(mut self) -> Self {
self.use_env = true;
self
}
pub fn init(self) -> Result<(), ItraceError> {
let tracer_name = self.resolve_tracer_name();
let config = Config::load(&tracer_name)?;
let filter_string = config.to_env_filter_string();
let filter = EnvFilter::try_new(&filter_string).unwrap_or_else(|_| EnvFilter::new("info"));
let shared = Arc::new(ArcSwap::new(Arc::new(config)));
let formatter = ItraceFormatter::new(Arc::clone(&shared));
let subscriber = tracing_subscriber::registry().with(filter).with(
fmt::Layer::new()
.event_format(formatter)
.with_writer(std::io::stderr),
);
subscriber.try_init()?;
Ok(())
}
fn resolve_tracer_name(&self) -> String {
if self.use_env {
std::env::var("ITRACE_TRACER").unwrap_or_else(|_| self.tracer_name.clone())
} else {
self.tracer_name.clone()
}
}
}