Files
WebScraper/src/util/logger.rs
2025-12-05 21:20:12 +01:00

78 lines
2.1 KiB
Rust

// src/util/logger.rs
use chrono::Local;
use once_cell::sync::Lazy;
use tokio::sync::Mutex;
use std::fs::{self, OpenOptions};
use std::io::Write;
use std::path::PathBuf;
static LOGGER: Lazy<Mutex<Option<DebugLogger>>> = Lazy::new(|| Mutex::new(None));
pub struct DebugLogger {
file: std::fs::File,
log_path: PathBuf,
}
impl DebugLogger {
fn new(log_dir: &std::path::Path) -> std::io::Result<Self> {
fs::create_dir_all(log_dir)?;
let filename = format!("backtest_{}.log", Local::now().format("%Y%m%d_%H%M%S"));
let log_path = log_dir.join(&filename);
let file = OpenOptions::new()
.create(true)
.append(true)
.open(&log_path)?;
Ok(Self { file, log_path })
}
async fn log(&mut self, msg: &str) {
let line = format!("[{}] {}\n", Local::now().format("%H:%M:%S"), msg);
let _ = self.file.write_all(line.as_bytes());
let _ = self.file.flush();
println!("{}", line.trim_end());
}
}
pub async fn init_debug_logger(log_dir: &std::path::Path) -> Result<(), String> {
let mut logger = LOGGER.lock().await;
match DebugLogger::new(log_dir) {
Ok(l) => {
let log_path = l.log_path.clone();
*logger = Some(l);
println!("✓ Logger initialized at: {:?}", log_path);
Ok(())
}
Err(e) => {
let err_msg = format!("Failed to initialize logger: {}", e);
eprintln!("{}", err_msg);
Err(err_msg)
}
}
}
pub async fn log_message(msg: &str) {
let mut logger = LOGGER.lock().await;
if let Some(l) = logger.as_mut() {
l.log(msg).await;
} else {
println!("[LOG] {}", msg);
}
}
pub async fn log_detailed(level: &str, msg: &str) {
let formatted = format!("[{}] {}", level, msg);
log_message(&formatted).await;
}
pub async fn log_info(msg: &str) {
log_detailed("INFO", msg).await;
}
pub async fn log_warn(msg: &str) {
log_detailed("WARN", msg).await;
}
pub async fn log_error(msg: &str) {
log_detailed("ERROR", msg).await;
}