From a1b0d93118a68055c3ee48eefc4ee2dc8c99a858 Mon Sep 17 00:00:00 2001 From: Tony Giorgio Date: Wed, 5 Jun 2024 18:58:33 -0500 Subject: [PATCH] Better logging --- Cargo.lock | 12 --- mutiny-core/src/logging.rs | 8 +- mutiny-wasm/Cargo.toml | 1 - mutiny-wasm/src/utils.rs | 174 ++++++++++++++++++++++++++++++++++++- 4 files changed, 176 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e5ae49991..7d2988b51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2655,7 +2655,6 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test", - "wasm-logger", "web-sys", ] @@ -4632,17 +4631,6 @@ dependencies = [ "syn 2.0.48", ] -[[package]] -name = "wasm-logger" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "074649a66bb306c8f2068c9016395fa65d8e08d2affcbf95acf3c24c3ab19718" -dependencies = [ - "log", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "wasm-ws" version = "0.1.1" diff --git a/mutiny-core/src/logging.rs b/mutiny-core/src/logging.rs index cf0b67c92..bb74af9ca 100644 --- a/mutiny-core/src/logging.rs +++ b/mutiny-core/src/logging.rs @@ -107,13 +107,13 @@ impl Logger for MutinyLogger { let raw_log = record.args.to_string(); let log = format!( "{} {} {:<5} [{}:{}] {}\n", - // log the session id so we can tie logs to a particular session, useful for detecting - // if we have multiple sessions running at once - self.session_id, // Note that a "real" lightning node almost certainly does *not* want subsecond // precision for message-receipt information as it makes log entries a target for // deanonymization attacks. For testing, however, its quite useful. Utc::now().format("%Y-%m-%d %H:%M:%S%.3f"), + // log the session id so we can tie logs to a particular session, useful for detecting + // if we have multiple sessions running at once + self.session_id, record.level, record.module_path, record.line, @@ -129,7 +129,7 @@ impl Logger for MutinyLogger { } match record.level { - Level::Gossip => trace!("{}", log), + Level::Gossip => (), // way too noisy Level::Trace => trace!("{}", log), Level::Debug => debug!("{}", log), Level::Info => info!("{}", log), diff --git a/mutiny-wasm/Cargo.toml b/mutiny-wasm/Cargo.toml index 2541c492c..16ca4e280 100644 --- a/mutiny-wasm/Cargo.toml +++ b/mutiny-wasm/Cargo.toml @@ -32,7 +32,6 @@ thiserror = "1.0" instant = { version = "0.1", features = ["wasm-bindgen"] } lnurl-rs = { version = "0.4.1", default-features = false } nostr = { version = "0.29.0", default-features = false, features = ["nip04", "nip05", "nip07", "nip47", "nip57"] } -wasm-logger = "0.2.0" log = "0.4.17" rexie = "0.5.0" gloo-utils = { version = "0.2.0", features = ["serde"] } diff --git a/mutiny-wasm/src/utils.rs b/mutiny-wasm/src/utils.rs index 7128ddc7a..2b4cfd7ab 100644 --- a/mutiny-wasm/src/utils.rs +++ b/mutiny-wasm/src/utils.rs @@ -1,5 +1,7 @@ -use log::{debug, Level}; +#![allow(dead_code)] +use log::{debug, Level, Log, Metadata, Record}; use wasm_bindgen::prelude::*; +use web_sys::console; pub fn set_panic_hook() { // When the `console_error_panic_hook` feature is enabled, we can call the @@ -14,11 +16,179 @@ pub fn set_panic_hook() { #[wasm_bindgen(start)] pub async fn main_js() -> Result<(), JsValue> { - wasm_logger::init(wasm_logger::Config::new(Level::Info).message_on_new_line()); + init( + Config::new(Level::Trace).message_on_new_line(), + Style::none(), + ); debug!("Main function begins and ends"); Ok(()) } +/// Specify what to be logged +pub struct Config { + level: Level, + module_prefix: Option, + message_location: MessageLocation, +} + +/// Specify where the message will be logged. +pub enum MessageLocation { + /// The message will be on the same line as other info (level, path...) + SameLine, + /// The message will be on its own line, a new after other info. + NewLine, +} + +impl Default for Config { + fn default() -> Self { + Self { + level: Level::Debug, + module_prefix: None, + message_location: MessageLocation::SameLine, + } + } +} + +impl Config { + /// Specify the maximum level you want to log + pub fn new(level: Level) -> Self { + Self { + level, + module_prefix: None, + message_location: MessageLocation::SameLine, + } + } + + /// Configure the `target` of the logger. If specified, the logger + /// only output for `log`s in module that its path starts with + /// `module_prefix`. wasm-logger only supports single prefix. Only + /// the last call to `module_prefix` has effect if you call it multiple times. + pub fn module_prefix(mut self, module_prefix: &str) -> Self { + self.module_prefix = Some(module_prefix.to_string()); + self + } + + /// Put the message on a new line, separated from other information + /// such as level, file path, line number. + pub fn message_on_new_line(mut self) -> Self { + self.message_location = MessageLocation::NewLine; + self + } +} + +/// The log styles +pub struct Style { + pub lvl_trace: String, + pub lvl_debug: String, + pub lvl_info: String, + pub lvl_warn: String, + pub lvl_error: String, + pub tgt: String, + pub args: String, +} + +impl Style { + pub fn new() -> Style { + let base = String::from("color: white; padding: 0 3px; background:"); + Style { + lvl_trace: format!("{} gray;", base), + lvl_debug: format!("{} blue;", base), + lvl_info: format!("{} green;", base), + lvl_warn: format!("{} orange;", base), + lvl_error: format!("{} darkred;", base), + tgt: String::from("font-weight: bold; color: inherit"), + args: String::from("background: inherit; color: inherit"), + } + } + + pub fn none() -> Style { + Style { + lvl_trace: String::new(), + lvl_debug: String::new(), + lvl_info: String::new(), + lvl_warn: String::new(), + lvl_error: String::new(), + tgt: String::new(), + args: String::new(), + } + } +} + +/// The logger +pub struct WasmLogger { + pub config: Config, + pub style: Style, +} + +impl Log for WasmLogger { + fn enabled(&self, metadata: &Metadata<'_>) -> bool { + if let Some(ref prefix) = self.config.module_prefix { + metadata.target().starts_with(prefix) + } else { + true + } + } + + fn log(&self, record: &Record<'_>) { + if self.enabled(record.metadata()) { + let style = &self.style; + let s = format!("{}", record.args()); + let s = JsValue::from_str(&s); + let tgt_style = JsValue::from_str(&style.tgt); + let args_style = JsValue::from_str(&style.args); + + match record.level() { + Level::Trace => console::debug_4( + &s, + &JsValue::from(&style.lvl_trace), + &tgt_style, + &args_style, + ), + Level::Debug => console::log_4( + &s, + &JsValue::from(&style.lvl_debug), + &tgt_style, + &args_style, + ), + Level::Info => { + console::info_4(&s, &JsValue::from(&style.lvl_info), &tgt_style, &args_style) + } + Level::Warn => { + console::warn_4(&s, &JsValue::from(&style.lvl_warn), &tgt_style, &args_style) + } + Level::Error => console::error_4( + &s, + &JsValue::from(&style.lvl_error), + &tgt_style, + &args_style, + ), + } + } + } + + fn flush(&self) {} +} + +/// Initialize the logger which the given config. If failed, it will log a message to the the browser console. +/// +/// ## Examples +/// ```rust +/// wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); +/// ``` +/// or +/// ```rust +/// wasm_logger::init(wasm_logger::Config::with_prefix(log::Level::Debug, "some::module")); +/// ``` +pub fn init(config: Config, style: Style) { + let max_level = config.level; + let wl = WasmLogger { config, style }; + + match log::set_boxed_logger(Box::new(wl)) { + Ok(_) => log::set_max_level(max_level.to_level_filter()), + Err(e) => console::error_1(&JsValue::from(e.to_string())), + } +} + #[cfg(test)] pub(crate) mod test { macro_rules! log {