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
13pub struct Logger {
14    _guard: WorkerGuard,
15}
16
17impl Logger {
18    /// Create a new logger with a custom log file prefix.
19    ///
20    /// # Arguments
21    /// * `prefix` - The prefix for log files (e.g., "multi_code", "europa")
22    ///
23    /// Log files will be created as `logs/{prefix}-{date}.log`
24    pub fn new(prefix: &str) -> io::Result<Self> {
25        let log_dir = Path::new(LOG_DIR);
26        if !log_dir.exists() {
27            fs::create_dir_all(log_dir)?;
28        }
29
30        let date = Local::now().format("%Y-%m-%d");
31        let log_file_name = format!("{}/{}-{}.log", LOG_DIR, prefix, date);
32
33        let file = File::create(&log_file_name)?;
34
35        let (non_blocking, guard) = tracing_appender::non_blocking(file);
36
37        let env_filter =
38            EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("debug"));
39
40        tracing_subscriber::registry()
41            .with(env_filter)
42            .with(
43                fmt::layer()
44                    .with_writer(non_blocking)
45                    .with_ansi(false)
46                    .with_target(true)
47                    .with_thread_ids(false)
48                    .with_file(true)
49                    .with_line_number(true),
50            )
51            .init();
52
53        tracing::info!("Logger initialized, writing to {}", log_file_name);
54
55        Ok(Self { _guard: guard })
56    }
57}