use anyhow::{Context, Result};
use std::fs;
use std::path::Path;
use std::sync::Once;
use tracing::{debug, error, info, instrument, Level};
use tracing_appender::rolling::{RollingFileAppender, Rotation};
use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
static INIT: Once = Once::new();
#[derive(Clone, Debug)]
pub struct TracingConfig {
pub debug_mode: bool,
pub data_dir: String,
}
impl Default for TracingConfig {
fn default() -> Self {
Self {
debug_mode: std::env::var("DEBUG").is_ok(),
data_dir: "data_dir".to_string(),
}
}
}
pub fn initialize(config: TracingConfig) -> Result<()> {
let mut result = Ok(());
INIT.call_once(|| {
result = setup_tracing(&config);
if let Err(e) = fs::create_dir_all(&config.data_dir) {
error!("Failed to create data directory: {}", e);
result = Err(anyhow::anyhow!("Failed to create data directory: {}", e));
}
});
result
}
fn setup_tracing(config: &TracingConfig) -> Result<()> {
let logs_dir = Path::new("logs");
fs::create_dir_all(logs_dir)?;
let file_appender = RollingFileAppender::new(Rotation::DAILY, logs_dir, "application.log");
let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender);
let default_level = if config.debug_mode {
Level::DEBUG
} else {
Level::INFO
};
let env_filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new(format!("{}", default_level)));
tracing_subscriber::registry()
.with(
fmt::Layer::default()
.with_writer(std::io::stdout)
.with_ansi(true),
)
.with(
fmt::Layer::default()
.with_writer(non_blocking)
.with_ansi(false),
)
.with(env_filter)
.init();
info!("Tracing initialized with debug_mode: {}", config.debug_mode);
static mut GUARD: Option<tracing_appender::non_blocking::WorkerGuard> = None;
unsafe {
GUARD = Some(_guard);
}
Ok(())
}
#[instrument(skip(audio_data))]
pub fn save_audio_chunk(chunk_id: u64, audio_data: &[u8], data_dir: &str) -> Result<()> {
let debug_mode = std::env::var("DEBUG").is_ok();
if !debug_mode {
return Ok(());
}
let chunk_path = Path::new(data_dir).join(format!("chunk_{}.wav", chunk_id));
debug!("Saving audio chunk to {:?}", chunk_path);
fs::write(&chunk_path, audio_data)
.with_context(|| format!("Failed to save audio chunk to {:?}", chunk_path))?;
info!("Saved audio chunk: {:?}", chunk_path);
Ok(())
}
pub fn is_debug_mode() -> bool {
std::env::var("DEBUG").is_ok()
}