agent_core/agent/
logger.rs

1// Logger for LLM agents using tracing
2
3use std::fs::{self, File};
4use std::io;
5use std::path::Path;
6
7use chrono::Local;
8use tracing_appender::non_blocking::WorkerGuard;
9use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
10
11const LOG_DIR: &str = "logs";
12
13/// Tracing-based logger that writes to daily log files.
14///
15/// Holds a worker guard to ensure logs are flushed before shutdown.
16pub struct Logger {
17    _guard: WorkerGuard,
18}
19
20impl Logger {
21    /// Create a new logger with a custom log file prefix.
22    ///
23    /// # Arguments
24    /// * `prefix` - The prefix for log files (e.g., "multi_code", "europa")
25    ///
26    /// Log files will be created as `logs/{prefix}-{date}.log`
27    pub fn new(prefix: &str) -> io::Result<Self> {
28        let log_dir = Path::new(LOG_DIR);
29        if !log_dir.exists() {
30            fs::create_dir_all(log_dir)?;
31        }
32
33        let date = Local::now().format("%Y-%m-%d");
34        let log_file_name = format!("{}/{}-{}.log", LOG_DIR, prefix, date);
35
36        let file = File::create(&log_file_name)?;
37
38        let (non_blocking, guard) = tracing_appender::non_blocking(file);
39
40        let env_filter =
41            EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("debug"));
42
43        tracing_subscriber::registry()
44            .with(env_filter)
45            .with(
46                fmt::layer()
47                    .with_writer(non_blocking)
48                    .with_ansi(false)
49                    .with_target(true)
50                    .with_thread_ids(false)
51                    .with_file(true)
52                    .with_line_number(true),
53            )
54            .init();
55
56        tracing::info!("Logger initialized, writing to {}", log_file_name);
57
58        Ok(Self { _guard: guard })
59    }
60}