An AI agent built to do Ralph loops - plan mode for planning and ralph mode for implementing.
1use anyhow::Result;
2use std::path::PathBuf;
3use tracing_appender::non_blocking::WorkerGuard;
4use tracing_appender::rolling::{RollingFileAppender, Rotation};
5use tracing_subscriber::{EnvFilter, fmt, layer::SubscriberExt, util::SubscriberInitExt};
6
7pub fn init_logging() -> Result<WorkerGuard> {
8 let log_dir = get_log_directory()?;
9 std::fs::create_dir_all(&log_dir)?;
10
11 let file_appender = RollingFileAppender::new(Rotation::DAILY, &log_dir, "rustagent.log");
12
13 let (non_blocking, guard) = tracing_appender::non_blocking(file_appender);
14
15 let file_layer = fmt::layer()
16 .with_writer(non_blocking)
17 .with_ansi(false)
18 .with_target(true)
19 .with_thread_ids(true);
20
21 let filter =
22 EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("rustagent=info"));
23
24 tracing_subscriber::registry()
25 .with(filter)
26 .with(file_layer)
27 .init();
28
29 Ok(guard)
30}
31
32fn get_log_directory() -> Result<PathBuf> {
33 if let Ok(state_home) = std::env::var("XDG_STATE_HOME") {
34 return Ok(PathBuf::from(state_home).join("rustagent").join("logs"));
35 }
36
37 if let Some(data_dir) = dirs::data_local_dir() {
38 return Ok(data_dir.join("rustagent").join("logs"));
39 }
40
41 if let Some(home) = dirs::home_dir() {
42 return Ok(home
43 .join(".local")
44 .join("state")
45 .join("rustagent")
46 .join("logs"));
47 }
48
49 anyhow::bail!("Could not determine log directory")
50}
51
52pub fn get_log_directory_path() -> Option<PathBuf> {
53 get_log_directory().ok()
54}