From abaa204300198dca509c17e2e38ceccdb32a9064 Mon Sep 17 00:00:00 2001 From: Patrick Auernig Date: Mon, 14 Aug 2023 16:01:59 +0200 Subject: [PATCH] Implement basic logging --- Cargo.lock | 167 ++++++++++++++++++++++++++++++++++- crates/wayfarer/Cargo.toml | 3 + crates/wayfarer/src/main.rs | 36 ++++++++ crates/wayfarer/src/state.rs | 33 +++++-- crates/wayfarer/src/tui.rs | 29 +++++- 5 files changed, 257 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0ab5c1a..b99b778 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -160,7 +160,7 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", - "time", + "time 0.1.45", "wasm-bindgen", "winapi", ] @@ -278,6 +278,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "deranged" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" + [[package]] name = "directories" version = "5.0.1" @@ -430,6 +436,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + [[package]] name = "jrny-save" version = "0.3.0" @@ -534,6 +546,16 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-traits" version = "0.2.16" @@ -555,6 +577,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "owo-colors" version = "3.5.0" @@ -590,6 +618,12 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +[[package]] +name = "pin-project-lite" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" + [[package]] name = "proc-macro2" version = "1.0.66" @@ -680,6 +714,21 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "serde" +version = "1.0.183" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + [[package]] name = "signal-hook" version = "0.3.17" @@ -773,6 +822,16 @@ dependencies = [ "syn 2.0.27", ] +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "time" version = "0.1.45" @@ -784,6 +843,103 @@ dependencies = [ "winapi", ] +[[package]] +name = "time" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" +dependencies = [ + "deranged", + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "time-macros" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" +dependencies = [ + "time-core", +] + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-appender" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e" +dependencies = [ + "crossbeam-channel", + "time 0.3.25", + "tracing-subscriber", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.27", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", +] + [[package]] name = "tui-input" version = "0.8.0" @@ -824,6 +980,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "walkdir" version = "2.3.3" @@ -912,6 +1074,9 @@ dependencies = [ "lazy_static", "notify", "ratatui", + "tracing", + "tracing-appender", + "tracing-subscriber", "tui-input", ] diff --git a/crates/wayfarer/Cargo.toml b/crates/wayfarer/Cargo.toml index da2ed33..ed14951 100644 --- a/crates/wayfarer/Cargo.toml +++ b/crates/wayfarer/Cargo.toml @@ -9,6 +9,9 @@ license-file.workspace = true anyhow = "1.0" directories = "5.0" lazy_static = "1.4" +tracing = "0.1" +tracing-subscriber = "0.3" +tracing-appender = "0.2" [dependencies.clap] version = "4.3" diff --git a/crates/wayfarer/src/main.rs b/crates/wayfarer/src/main.rs index 714a77f..6ca253d 100644 --- a/crates/wayfarer/src/main.rs +++ b/crates/wayfarer/src/main.rs @@ -7,6 +7,13 @@ mod watcher; use anyhow::Result; use clap::Parser as ArgParser; +use tracing::Level as TracingLevel; +use tracing_appender::rolling; +use tracing_subscriber::filter::Targets; +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::util::SubscriberInitExt; + +use crate::state::logs_dir; #[derive(Debug, ArgParser)] @@ -31,6 +38,8 @@ pub(crate) enum CommandArgs { fn main() -> Result<()> { + tracing_setup()?; + let args = Args::parse(); match &args.command { @@ -44,3 +53,30 @@ fn main() -> Result<()> { Ok(()) } + + +fn tracing_setup() -> Result<()> { + // lower log leven when targeting release + let level = if cfg!(debug_assertions) { + TracingLevel::TRACE + } else { + TracingLevel::INFO + }; + + let filter_layer = Targets::new() + .with_target("wayfarer", level) + .with_default(TracingLevel::ERROR); + + let file_writer = rolling::daily(logs_dir()?, "app"); + + let fmt_layer = tracing_subscriber::fmt::layer() + .with_writer(file_writer) + .with_ansi(false); + + tracing_subscriber::registry() + .with(fmt_layer) + .with(filter_layer) + .try_init()?; + + Ok(()) +} diff --git a/crates/wayfarer/src/state.rs b/crates/wayfarer/src/state.rs index 8ecd135..2b3792f 100644 --- a/crates/wayfarer/src/state.rs +++ b/crates/wayfarer/src/state.rs @@ -1,12 +1,16 @@ -#![cfg(feature = "tui")] - -use std::fs::{self, create_dir_all, read_to_string}; -use std::io::Write; -use std::os::unix::prelude::OsStrExt; -use std::path::Path; +use std::fs::create_dir_all; +use std::path::PathBuf; +#[cfg(feature = "tui")] +use std::{ + fs::{self, read_to_string}, + io::Write, + os::unix::prelude::OsStrExt, + path::Path, +}; use anyhow::Result; use directories::ProjectDirs; +#[cfg(feature = "tui")] use jrny_save::Savefile; @@ -17,11 +21,27 @@ lazy_static::lazy_static! { } +pub fn logs_dir() -> Result { + let log_root_path = DIRS + .state_dir() + .unwrap_or_else(|| DIRS.cache_dir()) + .join("logs"); + + if !log_root_path.exists() { + create_dir_all(&log_root_path)?; + } + + Ok(log_root_path) +} + + +#[cfg(feature = "tui")] #[derive(Debug, Default)] pub struct PersistentState { pub savefile: Option, } +#[cfg(feature = "tui")] impl PersistentState { pub fn load() -> Result { let data_dir = DIRS.data_local_dir(); @@ -68,6 +88,7 @@ impl PersistentState { } +#[cfg(feature = "tui")] fn load_last_active_savefile() -> Result> { let state_path = DIRS.data_local_dir().join("active_savefile"); diff --git a/crates/wayfarer/src/tui.rs b/crates/wayfarer/src/tui.rs index dd05792..6a57f28 100644 --- a/crates/wayfarer/src/tui.rs +++ b/crates/wayfarer/src/tui.rs @@ -18,6 +18,7 @@ use ratatui::backend::CrosstermBackend; use ratatui::layout::{Alignment, Constraint, Direction, Layout, Rect}; use ratatui::style::Style; use ratatui::widgets::{Block, Borders, Cell, Padding, Paragraph, Row, Table}; +use tracing::{debug, error, info}; use tui_input::backend::crossterm::EventHandler; use tui_input::Input; @@ -93,6 +94,7 @@ pub(crate) fn execute(_app_args: &AppArgs, _args: &Args) -> Result<()> { } +#[tracing::instrument(skip_all)] #[cfg_attr(not(feature = "watch"), allow(unused_mut))] fn run(terminal: &mut Terminal, mut state: State) -> Result<()> { let (mut msg_tx, msg_rx) = mpsc::channel::(); @@ -105,9 +107,13 @@ fn run(terminal: &mut Terminal, mut state: State) -> Result<()> { handle_events(&mut msg_tx, &mut state)?; match msg_rx.try_recv() { - Ok(Message::Exit) => break, + Ok(Message::Exit) => { + debug!("Exiting..."); + break; + } Ok(message) => { if let Err(err) = handle_message(&mut state, &mut msg_tx, message) { + error!(message = ?err); state.mode = Mode::ShowError(format!("{}", err)); } } @@ -120,6 +126,7 @@ fn run(terminal: &mut Terminal, mut state: State) -> Result<()> { } +#[tracing::instrument(skip(state, msg_tx))] #[cfg_attr(not(feature = "watch"), allow(unused_variables))] fn handle_message( state: &mut State, @@ -128,13 +135,17 @@ fn handle_message( ) -> Result<()> { match message { Message::SetMode(mode) => { + debug!("Setting mode to {:?}", mode); + state.mode = mode; } Message::LoadFile => { - state - .persistent - .set_active_savefile_path(state.file_select.value())?; + let file_path = state.file_select.value(); + + info!("Loading file {}", file_path); + + state.persistent.set_active_savefile_path(file_path)?; #[cfg(feature = "watch")] if state.file_watcher.is_some() { @@ -153,15 +164,22 @@ fn handle_message( let callback = move || { evq_tx.send(Message::ReloadFile).unwrap(); }; + + info!("Starting file watcher on {}", savefile.path.display()); + let file_watcher = FileWatcher::new(&savefile.path, callback); state.file_watcher = Some(file_watcher); } else { + info!("Stopped file watcher on {}", savefile.path.display()); + state.file_watcher = None; } } #[cfg(feature = "watch")] Message::ReloadFile if state.persistent.savefile.is_some() => { + debug!("Reloading file"); + state.persistent.reload_active_savefile()?; } @@ -186,6 +204,7 @@ fn handle_events(event_queue: &mut mpsc::Sender, state: &mut State) -> } +#[tracing::instrument(skip(msg_tx, state))] fn handle_keyboard_input( key: KeyEvent, msg_tx: &mut mpsc::Sender, @@ -235,6 +254,7 @@ fn handle_keyboard_input( fn setup() -> Result { let mut stdout = io::stdout(); + debug!("Enabling terminal raw mode"); enable_raw_mode()?; execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?; @@ -244,6 +264,7 @@ fn setup() -> Result { fn reset(mut terminal: Terminal) -> Result<()> { + debug!("Disabling terminal raw mode"); disable_raw_mode()?; execute!(