refactor(prettify-log): regex performance
This commit is contained in:
@@ -137,10 +137,10 @@
|
|||||||
virtualisation.vmVariant.virtualisation = {
|
virtualisation.vmVariant.virtualisation = {
|
||||||
qemu.options = [
|
qemu.options = [
|
||||||
"-nographic"
|
"-nographic"
|
||||||
"-display" "curses"
|
"-display curses"
|
||||||
"-append" "console=ttyS0"
|
"-append console=ttyS0"
|
||||||
"-serial" "mon:stdio"
|
"-serial mon:stdio"
|
||||||
"-vga" "qxl"
|
"-vga qxl"
|
||||||
];
|
];
|
||||||
forwardPorts = [
|
forwardPorts = [
|
||||||
{ from = "host"; host.port = 40500; guest.port = 22; }
|
{ from = "host"; host.port = 40500; guest.port = 22; }
|
||||||
|
|||||||
1
package/prettify-log/Cargo.lock
generated
1
package/prettify-log/Cargo.lock
generated
@@ -225,6 +225,7 @@ dependencies = [
|
|||||||
"atty",
|
"atty",
|
||||||
"colored_json",
|
"colored_json",
|
||||||
"float-cmp",
|
"float-cmp",
|
||||||
|
"once_cell",
|
||||||
"predicates",
|
"predicates",
|
||||||
"regex",
|
"regex",
|
||||||
"serde",
|
"serde",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
atty = "0.2.14"
|
atty = "0.2.14"
|
||||||
colored_json = "5.0.0"
|
colored_json = "5.0.0"
|
||||||
|
once_cell = "1.20.2"
|
||||||
regex = "1.11.1"
|
regex = "1.11.1"
|
||||||
serde = "1.0.217"
|
serde = "1.0.217"
|
||||||
serde_json = "1.0.138"
|
serde_json = "1.0.138"
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ use std::io::{self, BufRead};
|
|||||||
use std::env;
|
use std::env;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use colored_json::{ColorMode, ToColoredJson};
|
use colored_json::{ColorMode, ToColoredJson};
|
||||||
use regex::Regex;
|
use regex::{Regex, Captures};
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
/// Finds the first '{' and tries to match nested braces until the corresponding '}'.
|
/// Finds the first '{' and tries to match nested braces until the corresponding '}'.
|
||||||
fn find_json_block(line: &str) -> Option<(usize, usize)> {
|
fn find_json_block(line: &str) -> Option<(usize, usize)> {
|
||||||
@@ -23,6 +24,10 @@ fn find_json_block(line: &str) -> Option<(usize, usize)> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static RE: Lazy<Regex> = Lazy::new(|| {
|
||||||
|
Regex::new(r"(?i)(^|[^A-Za-z])(?P<kw>ERROR|DEBUG|INFO|LOG|EXCEPTION|WARNING|NOTICE|HINT|FATAL|DETAIL|STATEMENT)(:)").unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
/// Applies color to known log keywords (e.g. ERROR, DEBUG) without coloring the colon.
|
/// Applies color to known log keywords (e.g. ERROR, DEBUG) without coloring the colon.
|
||||||
/// Captures the preceding boundary, the keyword, and the colon, then colors only the keyword.
|
/// Captures the preceding boundary, the keyword, and the colon, then colors only the keyword.
|
||||||
fn colorize_keywords(line: &str) -> String {
|
fn colorize_keywords(line: &str) -> String {
|
||||||
@@ -34,26 +39,24 @@ fn colorize_keywords(line: &str) -> String {
|
|||||||
let cyan = "\x1b[36m";
|
let cyan = "\x1b[36m";
|
||||||
let reset = "\x1b[0m";
|
let reset = "\x1b[0m";
|
||||||
|
|
||||||
let patterns = vec![
|
RE.replace_all(line, |caps: &Captures| {
|
||||||
(Regex::new(r"(?i)(^|[^A-Za-z])(ERROR)(:)").unwrap(), format!("$1{red}$2{reset}$3", red=red, reset=reset)),
|
let prefix = caps.get(1).unwrap().as_str();
|
||||||
(Regex::new(r"(?i)(^|[^A-Za-z])(DEBUG)(:)").unwrap(), format!("$1{blue}$2{reset}$3", blue=blue, reset=reset)),
|
let keyword = caps.name("kw").unwrap().as_str();
|
||||||
(Regex::new(r"(?i)(^|[^A-Za-z])(INFO)(:)").unwrap(), format!("$1{green}$2{reset}$3", green=green, reset=reset)),
|
let suffix = caps.get(3).unwrap().as_str();
|
||||||
(Regex::new(r"(?i)(^|[^A-Za-z])(LOG)(:)").unwrap(), format!("$1{green}$2{reset}$3", green=green, reset=reset)),
|
let key = match keyword.to_lowercase().as_str() {
|
||||||
(Regex::new(r"(?i)(^|[^A-Za-z])(EXCEPTION)(:)").unwrap(), format!("$1{magenta}$2{reset}$3", magenta=magenta, reset=reset)),
|
"error" => format!("{}{}{}{}", prefix, red, keyword, reset),
|
||||||
(Regex::new(r"(?i)(^|[^A-Za-z])(WARNING)(:)").unwrap(), format!("$1{yellow}$2{reset}$3", yellow=yellow, reset=reset)),
|
"debug" => format!("{}{}{}{}", prefix, blue, keyword, reset),
|
||||||
(Regex::new(r"(?i)(^|[^A-Za-z])(NOTICE)(:)").unwrap(), format!("$1{cyan}$2{reset}$3", cyan=cyan, reset=reset)),
|
"info" | "log"
|
||||||
(Regex::new(r"(?i)(^|[^A-Za-z])(HINT)(:)").unwrap(), format!("$1{cyan}$2{reset}$3", cyan=cyan, reset=reset)),
|
=> format!("{}{}{}{}", prefix, green, keyword, reset),
|
||||||
(Regex::new(r"(?i)(^|[^A-Za-z])(FATAL)(:)").unwrap(), format!("$1{magenta}$2{reset}$3", magenta=magenta, reset=reset)),
|
"exception" | "fatal"
|
||||||
(Regex::new(r"(?i)(^|[^A-Za-z])(DETAIL)(:)").unwrap(), format!("$1{cyan}$2{reset}$3", cyan=cyan, reset=reset)),
|
=> format!("{}{}{}{}", prefix, magenta, keyword, reset),
|
||||||
(Regex::new(r"(?i)(^|[^A-Za-z])(STATEMENT)(:)").unwrap(), format!("$1{cyan}$2{reset}$3", cyan=cyan, reset=reset)),
|
"warning" => format!("{}{}{}{}", prefix, yellow, keyword, reset),
|
||||||
];
|
"notice" | "hint" | "detail" | "statement"
|
||||||
|
=> format!("{}{}{}{}", prefix, cyan, keyword, reset),
|
||||||
let mut out = String::from(line);
|
_ => caps[0].to_string(),
|
||||||
for (re, replacement) in patterns {
|
};
|
||||||
// Replace all occurrences
|
key + suffix
|
||||||
out = re.replace_all(&out, replacement.as_str()).to_string();
|
}).to_string()
|
||||||
}
|
|
||||||
out
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn conditionally_colorize_keywords<'a>(line: &'a str, force_color: bool) -> String {
|
fn conditionally_colorize_keywords<'a>(line: &'a str, force_color: bool) -> String {
|
||||||
|
|||||||
Reference in New Issue
Block a user