diff --git a/graph/solutions/file-based-logging-for-rust-tui-apps-using-tracing-appender-1768d9.md b/graph/solutions/file-based-logging-for-rust-tui-apps-using-tracing-appender-1768d9.md new file mode 100644 index 00000000000..7eb88f8504e --- /dev/null +++ b/graph/solutions/file-based-logging-for-rust-tui-apps-using-tracing-appender-1768d9.md @@ -0,0 +1,57 @@ +--- +id: 1768d9ab-0c21-4ec3-bb04-bd70366f6240 +type: solution +title: "File-based logging for Rust TUI apps using tracing-appender" +tags: [sba-scout, rust, tracing, logging, tui, ratatui, solution] +importance: 0.6 +confidence: 0.8 +created: "2026-02-28T16:53:12.444250+00:00" +updated: "2026-02-28T16:53:12.444250+00:00" +--- + +# File Logging for Rust TUI Apps + +**Project:** sba-scout (Rust) | **Commit:** `bf7c3f8` + +## Problem + +Writing to stdout/stderr corrupts ratatui TUI display. Any tracing output needs to go to a file instead. + +## Solution + +Use `tracing-appender` with `rolling::never()` for a fixed log file path. + +### Dependencies + +```toml +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } +tracing-appender = "0.2" +``` + +### Setup + +```rust +use tracing_appender::rolling; +use tracing_subscriber::EnvFilter; + +let file_appender = rolling::never("data", "sba-scout.log"); +let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender); + +tracing_subscriber::fmt() + .with_env_filter(EnvFilter::from_default_env()) + .with_writer(non_blocking) + .init(); + +// _guard must stay alive for the duration of the app! +``` + +### Usage + +- Set `RUST_LOG=debug` (or `info`, `error`, etc.) for verbose output +- Log is written to `data/sba-scout.log` +- Add `tracing::error!()` alongside UI notification sends to capture full error context in log + +## Critical + +The `WorkerGuard` returned by `non_blocking()` must be kept alive (stored in a variable that lives for the entire app scope). Dropping it early silently stops log output.