diff options
| author | Kevin Hoerr <kjhoerr@submelon.dev> | 2026-04-22 14:52:59 -0400 |
|---|---|---|
| committer | Kevin Hoerr <kjhoerr@submelon.dev> | 2026-04-22 14:52:59 -0400 |
| commit | 0952686526e118339b945ccfb84db1dcc69ee2ab (patch) | |
| tree | 983cc5018ba31f88d89c241c951a38a4cae752c8 | |
| parent | 25246c26c11f485272689b8c7bd7910f90cc38ed (diff) | |
| download | equity-tracker-0952686526e118339b945ccfb84db1dcc69ee2ab.tar.gz equity-tracker-0952686526e118339b945ccfb84db1dcc69ee2ab.tar.bz2 equity-tracker-0952686526e118339b945ccfb84db1dcc69ee2ab.zip | |
Add logging
| -rw-r--r-- | Cargo.lock | 122 | ||||
| -rw-r--r-- | Cargo.toml | 3 | ||||
| -rw-r--r-- | TODO.md | 2 | ||||
| -rw-r--r-- | src/app/mod.rs | 9 | ||||
| -rw-r--r-- | src/app/store/sqlite.rs | 2 | ||||
| -rw-r--r-- | src/logging.rs | 54 | ||||
| -rw-r--r-- | src/main.rs | 12 |
7 files changed, 203 insertions, 1 deletions
@@ -389,6 +389,9 @@ dependencies = [ "ratatui", "sqlite", "thiserror 2.0.18", + "tracing", + "tracing-error", + "tracing-subscriber", ] [[package]] @@ -744,6 +747,15 @@ dependencies = [ ] [[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] name = "memchr" version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -845,6 +857,15 @@ dependencies = [ ] [[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.60.2", +] + +[[package]] name = "num-bigint" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1047,6 +1068,12 @@ dependencies = [ ] [[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] name = "pkg-config" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1343,6 +1370,15 @@ dependencies = [ ] [[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1619,6 +1655,15 @@ dependencies = [ ] [[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] name = "time" version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1640,6 +1685,77 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] name = "typenum" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1717,6 +1833,12 @@ dependencies = [ ] [[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -18,6 +18,9 @@ miette = { version = "7.6.0", features = ["fancy"] } ratatui = "0.30.0" sqlite = "0.37.0" thiserror = "2.0.18" +tracing = "0.1.44" +tracing-error = "0.2.1" +tracing-subscriber = { version = "0.3.23", features = ["env-filter"] } [lints.rust] @@ -3,7 +3,7 @@ - [x] SQLite integration - [x] Design process flow - [x] Prepare in-mem schema -- [ ] Write debug logging to file? +- [x] Write debug logging to file - [ ] Add app state handling - [ ] Init screen: app loading - [ ] Add detect change control for schema diff --git a/src/app/mod.rs b/src/app/mod.rs index 15290ef..d51640f 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -34,6 +34,7 @@ impl App { } pub fn exit(&mut self) -> Result<()> { + tracing::event!(tracing::Level::TRACE, exit = true, "Changing exit status."); self.exit = true; Ok(()) } @@ -42,6 +43,7 @@ impl App { let store = self.context.unwrap_store(); let count = store.get_counter()?; + tracing::event!(tracing::Level::TRACE, count, "Decrementing counter."); if count == 0 { Err(OverflowError { _msg: "Cannot count below 0".into(), @@ -57,6 +59,7 @@ impl App { let store = self.context.unwrap_store(); let count = store.get_counter()?; + tracing::event!(tracing::Level::TRACE, count, "Incrementing counter."); if count == u8::MAX { Err(OverflowError { _msg: "Cannot count above u8::MAX".into(), @@ -77,6 +80,12 @@ impl App { } pub fn set_error(&mut self, error: ErrReport) -> Result<()> { + tracing::event!( + tracing::Level::ERROR, + error = error.to_string(), + help = error.help().map_or(String::default(), |h| h.to_string()) + ); + self.error = Some(error); Ok(()) } diff --git a/src/app/store/sqlite.rs b/src/app/store/sqlite.rs index 4f5f8f2..e971ef3 100644 --- a/src/app/store/sqlite.rs +++ b/src/app/store/sqlite.rs @@ -87,6 +87,8 @@ impl Store for SQLiteStore { fn set_counter(&mut self, new_count: u8) -> Result<u8, ContextError> { self.update_counter(i64::from(new_count))?; + tracing::event!(tracing::Level::DEBUG, new_count, "Updated counter."); + Ok(new_count) } } diff --git a/src/logging.rs b/src/logging.rs new file mode 100644 index 0000000..fd81dba --- /dev/null +++ b/src/logging.rs @@ -0,0 +1,54 @@ +use std::{io::Error, path::PathBuf, str::FromStr}; + +use tracing_error::ErrorLayer; +use tracing_subscriber::{self, Layer, layer::SubscriberExt, util::SubscriberInitExt}; + +const LOG_FILE: &'static str = "equity-tracker.log"; + +const LOG_LEVEL: &'static str = "LOG_LEVEL"; +const DEFAULT_LOG_LEVEL: &'static str = "DEBUG"; + +const LOG_DIRECTORY: &'static str = "LOG_DIRECTORY"; +const DEFAULT_LOG_DIRECTORY: &'static str = "./target"; + +/// Either retrieves the environment variable or uses a default value +fn get_env_var(var_name: &'static str, default: &'static str) -> String { + if let Ok(env_var) = std::env::var(var_name) { + env_var + } else { + default.into() + } +} + +/// Provides a PathBuf of the configured log directory, or the target directory +fn get_log_directory() -> std::io::Result<PathBuf> { + let env_dir = get_env_var(LOG_DIRECTORY, DEFAULT_LOG_DIRECTORY); + let path = PathBuf::from_str(&env_dir).map_err(|e| Error::other(e))?; + + Ok(path) +} + +/// Configure the logging through tracing +pub fn initialize_logging() -> std::io::Result<()> { + let directory = get_log_directory()?; + std::fs::create_dir_all(directory.clone())?; + + let log_path = directory.join(LOG_FILE); + let log_file = std::fs::File::create(log_path)?; + + let log_filter = get_env_var(LOG_LEVEL, DEFAULT_LOG_LEVEL); + let file_subscriber = tracing_subscriber::fmt::layer() + .with_file(true) + .with_line_number(true) + .with_target(false) + .with_ansi(false) + .with_writer(log_file) + .with_filter(tracing_subscriber::filter::EnvFilter::builder().parse_lossy(log_filter)); + + tracing_subscriber::registry() + .with(file_subscriber) + .with(ErrorLayer::default()) + .init(); + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index bb63c86..d1d4ee4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ mod app; +mod logging; mod ui; use app::App; @@ -24,9 +25,15 @@ fn main() -> Result<()> { let backend = CrosstermBackend::new(stdout); let mut term = Terminal::new(backend).into_diagnostic()?; + logging::initialize_logging().into_diagnostic()?; + + tracing::event!(tracing::Level::DEBUG, "App initialization started."); + let mut app = App::default(); app.init_context()?; + tracing::event!(tracing::Level::INFO, "App started."); + // could be error, so don't unwrap; let term restore first let run = run_app(&mut term, &mut app); @@ -67,6 +74,11 @@ fn run_app<B: Backend>(term: &mut Terminal<B>, app: &mut App) -> Result<()> { /// Process user input and run associated app functions fn handle_key_event(app: &mut App, key_event: KeyEvent) -> Result<()> { + tracing::event!( + tracing::Level::TRACE, + event = key_event.code.to_string(), + "Received key event." + ); match key_event.code { KeyCode::Char('q') => app.exit()?, KeyCode::Left => app.decrement_counter()?, |
