mirror of
https://codeberg.org/icewind/logsmash.git
synced 2026-06-03 18:14:11 +02:00
log time
This commit is contained in:
parent
6e0c662fb4
commit
e7b70fd00e
6 changed files with 41 additions and 8 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
|
@ -207,6 +207,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"time",
|
||||||
"tinystr",
|
"tinystr",
|
||||||
"zip",
|
"zip",
|
||||||
]
|
]
|
||||||
|
|
@ -324,6 +325,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"powerfmt",
|
"powerfmt",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -989,10 +991,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
|
checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deranged",
|
"deranged",
|
||||||
|
"itoa",
|
||||||
"num-conv",
|
"num-conv",
|
||||||
"powerfmt",
|
"powerfmt",
|
||||||
"serde",
|
"serde",
|
||||||
"time-core",
|
"time-core",
|
||||||
|
"time-macros",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1001,6 +1005,16 @@ version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-macros"
|
||||||
|
version = "0.2.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
|
||||||
|
dependencies = [
|
||||||
|
"num-conv",
|
||||||
|
"time-core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tinystr"
|
name = "tinystr"
|
||||||
version = "0.7.6"
|
version = "0.7.6"
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ zip = "2.1.5"
|
||||||
itertools = "0.13.0"
|
itertools = "0.13.0"
|
||||||
ratatui = "0.27.0"
|
ratatui = "0.27.0"
|
||||||
tinystr = { version = "0.7.6", features = ["serde"] }
|
tinystr = { version = "0.7.6", features = ["serde"] }
|
||||||
|
time = { version = "0.3.36", features = ["serde", "serde-well-known"] }
|
||||||
|
|
||||||
[profile.dev.package."*"]
|
[profile.dev.package."*"]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
use cloud_log_analyser_data::LogLevel;
|
use cloud_log_analyser_data::LogLevel;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use time::OffsetDateTime;
|
||||||
use tinystr::TinyAsciiStr;
|
use tinystr::TinyAsciiStr;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct LogLine {
|
pub struct LogLine {
|
||||||
pub version: TinyAsciiStr<8>,
|
pub version: TinyAsciiStr<16>,
|
||||||
pub level: LogLevel,
|
pub level: LogLevel,
|
||||||
pub message: String,
|
pub message: String,
|
||||||
pub exception: Option<Exception>,
|
pub exception: Option<Exception>,
|
||||||
pub app: TinyAsciiStr<16>,
|
pub app: TinyAsciiStr<32>,
|
||||||
|
#[serde(with = "time::serde::iso8601")]
|
||||||
|
pub time: OffsetDateTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LogLine {
|
impl LogLine {
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,13 @@ fn main() -> MainResult {
|
||||||
|
|
||||||
let mut counts: HashMap<MatchResult, Vec<usize>> = HashMap::new();
|
let mut counts: HashMap<MatchResult, Vec<usize>> = HashMap::new();
|
||||||
let first = lines.next().unwrap();
|
let first = lines.next().unwrap();
|
||||||
let first_parsed: LogLine = serde_json::from_str(&first).unwrap();
|
let first_parsed: LogLine = match serde_json::from_str(&first) {
|
||||||
|
Ok(first_parsed) => first_parsed,
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Failed to parse the first line in the log: {:#}", e);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let statements = get_statements(first_parsed.major_version().unwrap_or(MAX_VERSION));
|
let statements = get_statements(first_parsed.major_version().unwrap_or(MAX_VERSION));
|
||||||
let matcher = Matcher::new(&statements);
|
let matcher = Matcher::new(&statements);
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
use crate::app::{App, LogMatch};
|
use crate::app::{App, LogMatch};
|
||||||
use crate::logline::LogLine;
|
use crate::logline::LogLine;
|
||||||
use crate::ui::style::{TABLE_HEADER_STYLE, TABLE_SELECTED_STYLE};
|
use crate::ui::style::{TABLE_HEADER_STYLE, TABLE_SELECTED_STYLE, TIME_FORMAT};
|
||||||
use ratatui::layout::Constraint;
|
use ratatui::layout::Constraint;
|
||||||
use ratatui::widgets::{Cell, HighlightSpacing, Row, Table};
|
use ratatui::widgets::{Cell, HighlightSpacing, Row, Table};
|
||||||
|
use time::format_description::well_known::Iso8601;
|
||||||
|
|
||||||
pub fn single_match<'a>(app: &'a App, matches: &'a LogMatch) -> Table<'a> {
|
pub fn single_match<'a>(app: &'a App, matches: &'a LogMatch) -> Table<'a> {
|
||||||
let lines = matches.lines.iter().map(|i| &app.lines[*i]);
|
let lines = matches.lines.iter().map(|i| &app.lines[*i]);
|
||||||
|
|
||||||
let header = ["Level", "App", "Message"]
|
let header = ["Level", "App", "Message", "Date"]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Cell::from)
|
.map(Cell::from)
|
||||||
.collect::<Row>()
|
.collect::<Row>()
|
||||||
|
|
@ -18,6 +19,7 @@ pub fn single_match<'a>(app: &'a App, matches: &'a LogMatch) -> Table<'a> {
|
||||||
Constraint::Min(10),
|
Constraint::Min(10),
|
||||||
Constraint::Min(20),
|
Constraint::Min(20),
|
||||||
Constraint::Percentage(100),
|
Constraint::Percentage(100),
|
||||||
|
Constraint::Min(30),
|
||||||
];
|
];
|
||||||
let table = Table::new(lines.map(|line| log_row(line)), widths)
|
let table = Table::new(lines.map(|line| log_row(line)), widths)
|
||||||
.header(header)
|
.header(header)
|
||||||
|
|
@ -28,8 +30,9 @@ pub fn single_match<'a>(app: &'a App, matches: &'a LogMatch) -> Table<'a> {
|
||||||
|
|
||||||
fn log_row(line: &LogLine) -> Row {
|
fn log_row(line: &LogLine) -> Row {
|
||||||
Row::new([
|
Row::new([
|
||||||
line.level.as_str(),
|
line.level.as_str().to_string(),
|
||||||
line.app.as_str(),
|
line.app.to_string(),
|
||||||
line.message.as_str(),
|
line.message.clone(),
|
||||||
|
line.time.format(&Iso8601::<TIME_FORMAT>).unwrap(),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
use ratatui::prelude::Style;
|
use ratatui::prelude::Style;
|
||||||
use ratatui::style::palette::tailwind;
|
use ratatui::style::palette::tailwind;
|
||||||
|
use time::format_description::well_known::iso8601::{Config, EncodedConfig, TimePrecision};
|
||||||
|
|
||||||
pub const TABLE_HEADER_STYLE: Style = Style::new().bg(tailwind::BLACK).fg(tailwind::GREEN.c600);
|
pub const TABLE_HEADER_STYLE: Style = Style::new().bg(tailwind::BLACK).fg(tailwind::GREEN.c600);
|
||||||
pub const TABLE_SELECTED_STYLE: Style = Style::new().fg(tailwind::BLACK).bg(tailwind::GREEN.c600);
|
pub const TABLE_SELECTED_STYLE: Style = Style::new().fg(tailwind::BLACK).bg(tailwind::GREEN.c600);
|
||||||
|
pub const TIME_FORMAT: EncodedConfig = Config::DEFAULT
|
||||||
|
.set_time_precision(TimePrecision::Second {
|
||||||
|
decimal_digits: None,
|
||||||
|
})
|
||||||
|
.encode();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue