Add file-based logging to avoid TUI corruption from stderr output
Errors were only visible in the truncated status bar notification. Add tracing-appender to write to data/sba-scout.log with env-filter support (RUST_LOG), and add tracing::error! calls alongside all notification-only error paths for full diagnostic visibility. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
6d2b11a797
commit
bf7c3f870f
47
rust/Cargo.lock
generated
47
rust/Cargo.lock
generated
@ -270,6 +270,15 @@ version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-queue"
|
||||
version = "0.3.12"
|
||||
@ -1371,6 +1380,15 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9"
|
||||
dependencies = [
|
||||
"regex-automata",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "md-5"
|
||||
version = "0.10.6"
|
||||
@ -2221,6 +2239,7 @@ dependencies = [
|
||||
"tokio",
|
||||
"toml",
|
||||
"tracing",
|
||||
"tracing-appender",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
@ -2903,12 +2922,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"libc",
|
||||
"num-conv",
|
||||
"num_threads",
|
||||
"powerfmt",
|
||||
"serde_core",
|
||||
"time-core",
|
||||
"time-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2917,6 +2938,16 @@ version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinystr"
|
||||
version = "0.8.2"
|
||||
@ -3112,6 +3143,18 @@ dependencies = [
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-appender"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"thiserror 2.0.18",
|
||||
"time",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.31"
|
||||
@ -3150,10 +3193,14 @@ version = "0.3.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e"
|
||||
dependencies = [
|
||||
"matchers",
|
||||
"nu-ansi-term",
|
||||
"once_cell",
|
||||
"regex-automata",
|
||||
"sharded-slab",
|
||||
"smallvec",
|
||||
"thread_local",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
]
|
||||
|
||||
@ -31,7 +31,8 @@ thiserror = "2"
|
||||
|
||||
# Logging
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = "0.3"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
tracing-appender = "0.2"
|
||||
|
||||
# Date/time
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
|
||||
@ -5,11 +5,27 @@ use ratatui::DefaultTerminal;
|
||||
use sqlx::sqlite::SqlitePool;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::time::{interval, Duration};
|
||||
use tracing_appender::non_blocking::WorkerGuard;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
use sba_scout::app::{App, AppMessage};
|
||||
use sba_scout::config;
|
||||
use sba_scout::db;
|
||||
|
||||
fn init_logging(log_dir: &std::path::Path) -> WorkerGuard {
|
||||
std::fs::create_dir_all(log_dir).ok();
|
||||
let file_appender = tracing_appender::rolling::never(log_dir, "sba-scout.log");
|
||||
let (non_blocking, guard) = tracing_appender::non_blocking(file_appender);
|
||||
tracing_subscriber::fmt()
|
||||
.with_writer(non_blocking)
|
||||
.with_env_filter(
|
||||
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")),
|
||||
)
|
||||
.with_ansi(false)
|
||||
.init();
|
||||
guard
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let settings = match config::load_settings() {
|
||||
@ -20,6 +36,9 @@ async fn main() -> Result<()> {
|
||||
}
|
||||
};
|
||||
|
||||
let log_dir = settings.db_path.parent().unwrap_or(std::path::Path::new("data"));
|
||||
let _log_guard = init_logging(log_dir);
|
||||
|
||||
if let Some(parent) = settings.db_path.parent() {
|
||||
std::fs::create_dir_all(parent)?;
|
||||
}
|
||||
|
||||
@ -56,6 +56,7 @@ impl DashboardState {
|
||||
let _ = tx.send(AppMessage::RosterLoaded(roster));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Failed to load roster: {e}");
|
||||
let _ = tx.send(AppMessage::Notify(
|
||||
format!("Failed to load roster: {e}"),
|
||||
NotifyLevel::Error,
|
||||
@ -119,6 +120,7 @@ impl DashboardState {
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Sync failed: {e}");
|
||||
self.sync_state = SyncState::Error;
|
||||
self.sync_message = format!("Sync failed: {e}");
|
||||
}
|
||||
|
||||
@ -157,6 +157,7 @@ impl GamedayState {
|
||||
let _ = tx_c.send(AppMessage::TeamsLoaded(teams));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Failed to load teams: {e}");
|
||||
let _ = tx_c.send(AppMessage::Notify(
|
||||
format!("Failed to load teams: {e}"),
|
||||
NotifyLevel::Error,
|
||||
@ -620,6 +621,7 @@ impl GamedayState {
|
||||
let _ = tx.send(AppMessage::PitchersLoaded(pitchers));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Failed to load pitchers: {e}");
|
||||
let _ = tx.send(AppMessage::Notify(
|
||||
format!("Failed to load pitchers: {e}"),
|
||||
NotifyLevel::Error,
|
||||
@ -661,6 +663,7 @@ impl GamedayState {
|
||||
let _ = tx.send(AppMessage::MatchupsCalculated(results));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Matchup calculation failed: {e}");
|
||||
let _ = tx.send(AppMessage::Notify(
|
||||
format!("Matchup calculation failed: {e}"),
|
||||
NotifyLevel::Error,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user