added logging

This commit is contained in:
2025-12-05 21:20:12 +01:00
parent f7083bf9f0
commit 58a498e694
17 changed files with 526 additions and 358 deletions

134
src/util/directories.rs Normal file
View File

@@ -0,0 +1,134 @@
use std::path::{Path, PathBuf};
use std::fs;
/// Central configuration for all data paths
pub struct DataPaths {
base_dir: PathBuf,
data_dir: PathBuf,
cache_dir: PathBuf,
logs_dir: PathBuf,
// Economic data subdirectories
economic_events_dir: PathBuf,
economic_changes_dir: PathBuf,
// Corporate data subdirectories
corporate_events_dir: PathBuf,
corporate_changes_dir: PathBuf,
corporate_prices_dir: PathBuf,
}
impl DataPaths {
/// Initialize paths from a base directory
pub fn new(base_dir: impl AsRef<Path>) -> std::io::Result<Self> {
let base_dir = base_dir.as_ref().to_path_buf();
let data_dir = base_dir.join("data");
let cache_dir = base_dir.join("cache");
let logs_dir = base_dir.join("logs");
// Economic subdirectories
let economic_events_dir = data_dir.join("economic").join("events");
let economic_changes_dir = economic_events_dir.join("changes");
// Corporate subdirectories
let corporate_dir = data_dir.join("corporate");
let corporate_events_dir = corporate_dir.join("events");
let corporate_changes_dir = corporate_events_dir.join("changes");
let corporate_prices_dir = corporate_dir.join("prices");
// Create all directories if they don't exist
fs::create_dir_all(&data_dir)?;
fs::create_dir_all(&cache_dir)?;
fs::create_dir_all(&logs_dir)?;
fs::create_dir_all(&economic_events_dir)?;
fs::create_dir_all(&economic_changes_dir)?;
fs::create_dir_all(&corporate_events_dir)?;
fs::create_dir_all(&corporate_changes_dir)?;
fs::create_dir_all(&corporate_prices_dir)?;
Ok(Self {
base_dir,
data_dir,
cache_dir,
logs_dir,
economic_events_dir,
economic_changes_dir,
corporate_events_dir,
corporate_changes_dir,
corporate_prices_dir,
})
}
pub fn base_dir(&self) -> &Path {
&self.base_dir
}
pub fn data_dir(&self) -> &Path {
&self.data_dir
}
pub fn cache_dir(&self) -> &Path {
&self.cache_dir
}
pub fn logs_dir(&self) -> &Path {
&self.logs_dir
}
/// Get the economic events directory
pub fn economic_events_dir(&self) -> &Path {
&self.economic_events_dir
}
/// Get the economic changes directory
pub fn economic_changes_dir(&self) -> &Path {
&self.economic_changes_dir
}
/// Get the corporate events directory
pub fn corporate_events_dir(&self) -> &Path {
&self.corporate_events_dir
}
/// Get the corporate changes directory
pub fn corporate_changes_dir(&self) -> &Path {
&self.corporate_changes_dir
}
/// Get the corporate prices directory
pub fn corporate_prices_dir(&self) -> &Path {
&self.corporate_prices_dir
}
/// Get a specific file path within data directory
pub fn data_file(&self, filename: &str) -> PathBuf {
self.data_dir.join(filename)
}
/// Get a specific file path within cache directory
pub fn cache_file(&self, filename: &str) -> PathBuf {
self.cache_dir.join(filename)
}
/// Get a specific file path within logs directory
pub fn log_file(&self, filename: &str) -> PathBuf {
self.logs_dir.join(filename)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_paths_creation() {
let paths = DataPaths::new("./test_base").unwrap();
assert!(paths.data_dir().exists());
assert!(paths.cache_dir().exists());
assert!(paths.logs_dir().exists());
assert!(paths.economic_events_dir().exists());
assert!(paths.economic_changes_dir().exists());
assert!(paths.corporate_events_dir().exists());
assert!(paths.corporate_changes_dir().exists());
assert!(paths.corporate_prices_dir().exists());
}
}

78
src/util/logger.rs Normal file
View File

@@ -0,0 +1,78 @@
// 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;
}

3
src/util/mod.rs Normal file
View File

@@ -0,0 +1,3 @@
// src/util/mod.rs
pub mod logger;
pub mod directories;