From 69f89b4c6980c6b2f8e0302f0711b59f05e3cd44 Mon Sep 17 00:00:00 2001 From: Georgy Moshkin <gmoshkin@picodata.io> Date: Mon, 15 Aug 2022 15:25:59 +0300 Subject: [PATCH] feat: now can highlight relevant parts of logs To highlight all the logging messages containing the given key do this: * rust: `tlog::highlight_key(log_key, Some(color))`. * lua: `picolib.log.highlight_key(log_key, color)`. To disable highlight for the given key do this: * rust: `tlog::highlight_key(log_key, None)`. * lua: `picolib.log.highlight_key(log_key)`. To disable highlighting of all keys do this: * rust: `tlog::clear_highlight()`. * lua: `picolib.log.clear_highlight()`. --- src/main.rs | 29 +++++++++++++++++++++++++++++ src/tlog.rs | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 9ab9bafa12..4b7e95a83d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -114,6 +114,35 @@ fn picolib_setup(args: &args::Run) { .propose_and_wait(traft::OpReturnOne, Duration::from_secs_f64(timeout)) }), ); + luamod.set("log", &[()]); + #[rustfmt::skip] + l.exec_with( + "picolib.log.highlight_key = ...", + tlua::function2(|key: String, color: Option<String>| -> Result<(), String> { + let color = match color.as_deref() { + None => None, + Some("red") => Some(tlog::Color::Red), + Some("green") => Some(tlog::Color::Green), + Some("blue") => Some(tlog::Color::Blue), + Some("cyan") => Some(tlog::Color::Cyan), + Some("yellow") => Some(tlog::Color::Yellow), + Some("magenta") => Some(tlog::Color::Magenta), + Some("white") => Some(tlog::Color::White), + Some("black") => Some(tlog::Color::Black), + Some(other) => { + return Err(format!("unknown color: {other:?}")) + } + }; + tlog::highlight_key(key, color); + Ok(()) + }), + ) + .unwrap(); + l.exec_with( + "picolib.log.clear_highlight = ...", + tlua::function0(tlog::clear_highlight), + ) + .unwrap(); { l.exec( r#" diff --git a/src/tlog.rs b/src/tlog.rs index c7b3911896..4f78cb7204 100644 --- a/src/tlog.rs +++ b/src/tlog.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + pub struct Drain; pub fn root() -> slog::Logger { @@ -54,10 +56,49 @@ struct StrSerializer { pub str: String, } +#[rustfmt::skip] +#[repr(u8)] +#[derive(Clone, Copy)] +pub enum Color { + Red = 1, + Green = 2, + Blue = 4, + Cyan = 6, + Yellow = 3, + Magenta = 5, + White = 7, + Black = 0, +} + +pub static mut HIGHLIGHT: Option<HashMap<String, Color>> = None; + +#[inline] +pub fn clear_highlight() { + unsafe { + HIGHLIGHT = None; + } +} + +#[inline] +pub fn highlight_key(key: impl Into<String> + AsRef<str>, color: Option<Color>) { + let hi = unsafe { HIGHLIGHT.get_or_insert_with(HashMap::new) }; + if let Some(color) = color { + hi.insert(key.into(), color); + } else { + hi.remove(key.as_ref()); + } +} + impl slog::Serializer for StrSerializer { fn emit_arguments(&mut self, key: slog::Key, val: &std::fmt::Arguments) -> slog::Result { use std::fmt::Write; - write!(&mut self.str, ", {key}: {val}").unwrap(); + match unsafe { HIGHLIGHT.as_ref() }.and_then(|h| h.get(key)) { + Some(&color) => { + let color = color as u8; + write!(&mut self.str, ", \x1b[3{color}m{key}: {val}\x1b[0m").unwrap(); + } + _ => write!(&mut self.str, ", {key}: {val}").unwrap(), + } Ok(()) } } -- GitLab