From 39c72b31512c15a4171cee23403692c2c5d3292b Mon Sep 17 00:00:00 2001 From: jif-oai Date: Thu, 16 Oct 2025 15:05:55 +0100 Subject: [PATCH] Logs --- codex-rs/Cargo.lock | 2 + codex-rs/cli/Cargo.toml | 2 + codex-rs/cli/src/infty/commands.rs | 78 ++++++++++++++++++++++++ codex-rs/cli/src/infty/progress.rs | 1 - codex-rs/codex-infty/src/orchestrator.rs | 3 +- 5 files changed, 84 insertions(+), 2 deletions(-) diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index 0aae88ad6d..bb3747374e 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -973,6 +973,8 @@ dependencies = [ "textwrap 0.16.2", "tokio", "tracing", + "tracing-appender", + "tracing-subscriber", ] [[package]] diff --git a/codex-rs/cli/Cargo.toml b/codex-rs/cli/Cargo.toml index ab0d9d3d0f..ad1fa8aeb8 100644 --- a/codex-rs/cli/Cargo.toml +++ b/codex-rs/cli/Cargo.toml @@ -50,6 +50,8 @@ codex-infty = { path = "../codex-infty" } chrono = { workspace = true } serde = { workspace = true, features = ["derive"] } tracing = "0.1.41" +tracing-appender = "0.2.3" +tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } textwrap = { workspace = true } [dev-dependencies] diff --git a/codex-rs/cli/src/infty/commands.rs b/codex-rs/cli/src/infty/commands.rs index 531b5a22e6..84ef870c42 100644 --- a/codex-rs/cli/src/infty/commands.rs +++ b/codex-rs/cli/src/infty/commands.rs @@ -1,4 +1,5 @@ use std::fs; +use std::fs::OpenOptions; use std::io; use std::path::Path; use std::path::PathBuf; @@ -25,7 +26,11 @@ use codex_infty::RunParams; use codex_infty::RunStore; use owo_colors::OwoColorize; use serde::Serialize; +use std::sync::OnceLock; use supports_color::Stream; +use tracing_appender::non_blocking; +use tracing_subscriber::EnvFilter; +use tracing_subscriber::prelude::*; use super::args::CreateArgs; use super::args::ListArgs; @@ -52,6 +57,7 @@ pub(crate) async fn run_create( args: CreateArgs, ) -> Result<()> { let config = load_config(config_overrides).await?; + init_infty_logging(&config)?; let auth = load_auth(&config)?; let runs_root = resolve_runs_root(runs_root_override)?; let color_enabled = supports_color::on(Stream::Stdout).is_some(); @@ -155,6 +161,8 @@ pub(crate) async fn run_create( } pub(crate) fn run_list(runs_root_override: Option, args: ListArgs) -> Result<()> { + // Initialize logging using default Codex home discovery. + let _ = init_infty_logging_from_home(); let runs_root = resolve_runs_root(runs_root_override)?; let listings = collect_run_summaries(&runs_root)?; @@ -181,6 +189,7 @@ pub(crate) fn run_list(runs_root_override: Option, args: ListArgs) -> R pub(crate) fn run_show(runs_root_override: Option, args: ShowArgs) -> Result<()> { validate_run_id(&args.run_id)?; + let _ = init_infty_logging_from_home(); let runs_root = resolve_runs_root(runs_root_override)?; let run_path = runs_root.join(&args.run_id); let store = @@ -321,6 +330,75 @@ fn collect_run_summaries(root: &Path) -> Result> { Ok(summaries) } +fn init_infty_logging(config: &codex_core::config::Config) -> std::io::Result<()> { + let log_dir = codex_core::config::log_dir(config)?; + std::fs::create_dir_all(&log_dir)?; + + let mut log_file_opts = OpenOptions::new(); + log_file_opts.create(true).append(true); + + #[cfg(unix)] + { + use std::os::unix::fs::OpenOptionsExt; + log_file_opts.mode(0o600); + } + + let log_file = log_file_opts.open(log_dir.join("codex-infty.log"))?; + let (non_blocking, guard) = non_blocking(log_file); + static INFTY_LOG_GUARD: OnceLock = OnceLock::new(); + let _ = INFTY_LOG_GUARD.set(guard); + + // Use RUST_LOG if set, otherwise default to info for common codex crates + let env_filter = || { + EnvFilter::try_from_default_env() + .unwrap_or_else(|_| EnvFilter::new("codex_core=info,codex_infty=info,codex_cli=info")) + }; + + let file_layer = tracing_subscriber::fmt::layer() + .with_writer(non_blocking) + .with_target(false) + .with_span_events(tracing_subscriber::fmt::format::FmtSpan::CLOSE) + .with_filter(env_filter()); + + // Initialize once; subsequent calls are no‑ops. + let _ = tracing_subscriber::registry().with(file_layer).try_init(); + Ok(()) +} + +fn init_infty_logging_from_home() -> std::io::Result<()> { + let mut log_dir = codex_core::config::find_codex_home()?; + log_dir.push("log"); + std::fs::create_dir_all(&log_dir)?; + + let mut log_file_opts = OpenOptions::new(); + log_file_opts.create(true).append(true); + + #[cfg(unix)] + { + use std::os::unix::fs::OpenOptionsExt; + log_file_opts.mode(0o600); + } + + let log_file = log_file_opts.open(log_dir.join("codex-infty.log"))?; + let (non_blocking, guard) = non_blocking(log_file); + static INFTY_LOG_GUARD: OnceLock = OnceLock::new(); + let _ = INFTY_LOG_GUARD.set(guard); + + let env_filter = || { + EnvFilter::try_from_default_env() + .unwrap_or_else(|_| EnvFilter::new("codex_core=info,codex_infty=info,codex_cli=info")) + }; + + let file_layer = tracing_subscriber::fmt::layer() + .with_writer(non_blocking) + .with_target(false) + .with_span_events(tracing_subscriber::fmt::format::FmtSpan::CLOSE) + .with_filter(env_filter()); + + let _ = tracing_subscriber::registry().with(file_layer).try_init(); + Ok(()) +} + #[cfg(test)] mod tests { use super::*; diff --git a/codex-rs/cli/src/infty/progress.rs b/codex-rs/cli/src/infty/progress.rs index ed79a7329f..1724c5d38d 100644 --- a/codex-rs/cli/src/infty/progress.rs +++ b/codex-rs/cli/src/infty/progress.rs @@ -7,7 +7,6 @@ use codex_infty::ProgressReporter; use codex_infty::VerifierDecision; use codex_infty::VerifierVerdict; use crossterm::style::Stylize; -use owo_colors::OwoColorize; use std::path::Path; use supports_color::Stream; diff --git a/codex-rs/codex-infty/src/orchestrator.rs b/codex-rs/codex-infty/src/orchestrator.rs index ece0d9e54c..8ab80aae82 100644 --- a/codex-rs/codex-infty/src/orchestrator.rs +++ b/codex-rs/codex-infty/src/orchestrator.rs @@ -306,7 +306,8 @@ impl InftyOrchestrator { EventMsg::StreamError(error) => { println!("Stream error: {:?}", error); } - _ => { + e => { + tracing::info!("Unhandled event: {:?}", e); print!("."); let _ = std::io::stdout().flush(); }