make log parsing more reliable

This commit is contained in:
Robin Appelman 2024-07-30 14:17:12 +02:00
commit 7b8e8ec6cb
3 changed files with 41 additions and 6 deletions

View file

@ -1,7 +1,7 @@
use crate::app::{App, LogMatch}; use crate::app::{App, LogMatch};
use crate::error::LogError; use crate::error::LogError;
use crate::logfile::LogFile; use crate::logfile::LogFile;
use crate::logline::LogLine; use crate::logline::{Exception, FullException, FullLogLine, LogLine};
use crate::matcher::{MatchResult, Matcher}; use crate::matcher::{MatchResult, Matcher};
use crate::ui::run_ui; use crate::ui::run_ui;
use base64::prelude::*; use base64::prelude::*;
@ -48,7 +48,7 @@ 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 = match serde_json::from_str(first) { let first_parsed = match parse_line(first) {
Ok(first_parsed) => first_parsed, Ok(first_parsed) => first_parsed,
Err(e) => { Err(e) => {
eprintln!("Failed to parse the first line in the log: {:#}", e); eprintln!("Failed to parse the first line in the log: {:#}", e);
@ -72,7 +72,7 @@ fn main() -> MainResult {
.enumerate() .enumerate()
.par_bridge() .par_bridge()
.flat_map(|(index, line)| { .flat_map(|(index, line)| {
let mut parsed = serde_json::from_str::<LogLine>(line).ok()?; let mut parsed = parse_line(line).ok()?;
parsed.index = index; parsed.index = index;
Some(parsed) Some(parsed)
}) })
@ -143,3 +143,37 @@ fn main() -> MainResult {
fn copy_osc(text: &str) { fn copy_osc(text: &str) {
print!("\x1B]52;c;{}\x07", BASE64_STANDARD.encode(text)) print!("\x1B]52;c;{}\x07", BASE64_STANDARD.encode(text))
} }
fn parse_line(mut line: &str) -> Result<LogLine, serde_json::Error> {
if let Some(pos) = line.find('{') {
line = &line[pos..];
}
let mut res = serde_json::from_str::<LogLine>(line);
if let Ok(line) = &mut res {
if line.exception.is_none() && line.message.starts_with("{\"Exception\":") {
if let Ok(exception) = serde_json::from_str::<Exception>(&line.message) {
line.message = exception.message.clone();
line.exception = Some(exception);
}
}
}
res
}
fn parse_line_full(mut line: &str) -> Result<FullLogLine, serde_json::Error> {
if let Some(pos) = line.find('{') {
line = &line[pos..];
}
let mut res = serde_json::from_str::<FullLogLine>(line);
if let Ok(line) = &mut res {
if line.exception.is_none() && line.message.starts_with("{\"Exception\":") {
if let Ok(exception) = serde_json::from_str::<FullException>(&line.message) {
line.message = exception.message.clone();
line.exception = Some(exception);
}
}
}
res
}

View file

@ -1,5 +1,6 @@
use crate::app::App; use crate::app::App;
use crate::logline::{FullException, FullLogLine, LogLine, Trace}; use crate::logline::{FullException, FullLogLine, LogLine, Trace};
use crate::parse_line_full;
use crate::ui::style::{TABLE_HEADER_STYLE, TIME_FORMAT}; use crate::ui::style::{TABLE_HEADER_STYLE, TIME_FORMAT};
use crate::ui::table::{ScrollbarTable, ScrollbarTableState}; use crate::ui::table::{ScrollbarTable, ScrollbarTableState};
use ratatui::prelude::*; use ratatui::prelude::*;
@ -9,7 +10,7 @@ use time::format_description::well_known::Iso8601;
pub fn single_log(app: &App, line: &LogLine) -> SingleLog { pub fn single_log(app: &App, line: &LogLine) -> SingleLog {
let raw_line = app.get_line(line.index).unwrap(); let raw_line = app.get_line(line.index).unwrap();
let line: FullLogLine = serde_json::from_str(raw_line).unwrap(); let line = parse_line_full(raw_line).unwrap();
SingleLog { line } SingleLog { line }
} }

View file

@ -1,7 +1,7 @@
use crate::app::{App, LogMatch}; use crate::app::{App, LogMatch};
use crate::copy_osc;
use crate::logline::{FullLogLine, LogLine}; use crate::logline::{FullLogLine, LogLine};
use crate::ui::table::ScrollbarTableState; use crate::ui::table::ScrollbarTableState;
use crate::{copy_osc, parse_line_full};
use derive_more::From; use derive_more::From;
use ratatui::widgets::TableState; use ratatui::widgets::TableState;
@ -147,7 +147,7 @@ impl<'a> UiState<'a> {
let line = state.lines[selected]; let line = state.lines[selected];
let log = &app.lines[line]; let log = &app.lines[line];
let raw_line = app.get_line(log.index).unwrap(); let raw_line = app.get_line(log.index).unwrap();
let full_line: FullLogLine = serde_json::from_str(raw_line).unwrap(); let full_line = parse_line_full(raw_line).unwrap();
let trace_len = if let Some(exception) = &full_line.exception { let trace_len = if let Some(exception) = &full_line.exception {
exception.stack().map(|e| 1 + e.trace.len()).sum() exception.stack().map(|e| 1 + e.trace.len()).sum()
} else { } else {