diff options
| author | Brendan Allan <[email protected]> | 2026-02-11 19:36:27 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-02-11 11:36:27 +0000 |
| commit | a25b2af05aa4fe0cc2bc3474a0b5e23eca3efe4f (patch) | |
| tree | 0097ed5f15eb009b3ab1f5d235884d4733283166 /packages/desktop/src-tauri/src/logging.rs | |
| parent | 8bfd6fdba2490aa41ef9533e3301f0272711d489 (diff) | |
| download | opencode-a25b2af05aa4fe0cc2bc3474a0b5e23eca3efe4f.tar.gz opencode-a25b2af05aa4fe0cc2bc3474a0b5e23eca3efe4f.zip | |
desktop: use tracing for logging (#13135)
Diffstat (limited to 'packages/desktop/src-tauri/src/logging.rs')
| -rw-r--r-- | packages/desktop/src-tauri/src/logging.rs | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/packages/desktop/src-tauri/src/logging.rs b/packages/desktop/src-tauri/src/logging.rs new file mode 100644 index 000000000..f794f9c1b --- /dev/null +++ b/packages/desktop/src-tauri/src/logging.rs @@ -0,0 +1,83 @@ +use std::fs::File; +use std::io::{BufRead, BufReader}; +use std::path::{Path, PathBuf}; +use tracing_appender::non_blocking::WorkerGuard; +use tracing_subscriber::{EnvFilter, fmt, layer::SubscriberExt, util::SubscriberInitExt}; + +const MAX_LOG_AGE_DAYS: u64 = 7; +const TAIL_LINES: usize = 1000; + +static LOG_PATH: std::sync::OnceLock<PathBuf> = std::sync::OnceLock::new(); + +pub fn init(log_dir: &Path) -> WorkerGuard { + std::fs::create_dir_all(log_dir).expect("failed to create log directory"); + + cleanup(log_dir); + + let timestamp = chrono::Local::now().format("%Y-%m-%d_%H-%M-%S"); + let filename = format!("opencode-desktop_{timestamp}.log"); + let log_path = log_dir.join(&filename); + + LOG_PATH + .set(log_path.clone()) + .expect("logging already initialized"); + + let file = File::create(&log_path).expect("failed to create log file"); + let (non_blocking, guard) = tracing_appender::non_blocking(file); + + let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| { + if cfg!(debug_assertions) { + EnvFilter::new("opencode_lib=debug,opencode_desktop=debug,sidecar=debug") + } else { + EnvFilter::new("opencode_lib=info,opencode_desktop=info,sidecar=info") + } + }); + + tracing_subscriber::registry() + .with(filter) + .with(fmt::layer().with_writer(std::io::stderr)) + .with( + fmt::layer() + .with_writer(non_blocking) + .with_ansi(false), + ) + .init(); + + guard +} + +pub fn tail() -> String { + let Some(path) = LOG_PATH.get() else { + return String::new(); + }; + + let Ok(file) = File::open(path) else { + return String::new(); + }; + + let lines: Vec<String> = BufReader::new(file) + .lines() + .map_while(Result::ok) + .collect(); + + let start = lines.len().saturating_sub(TAIL_LINES); + lines[start..].join("\n") +} + +fn cleanup(log_dir: &Path) { + let cutoff = std::time::SystemTime::now() + - std::time::Duration::from_secs(MAX_LOG_AGE_DAYS * 24 * 60 * 60); + + let Ok(entries) = std::fs::read_dir(log_dir) else { + return; + }; + + for entry in entries.flatten() { + if let Ok(meta) = entry.metadata() + && let Ok(modified) = meta.modified() + && modified < cutoff + { + let _ = std::fs::remove_file(entry.path()); + } + } +} |
