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::error::LogError;
use crate::logfile::LogFile;
use crate::logline::LogLine;
use crate::logline::{Exception, FullException, FullLogLine, LogLine};
use crate::matcher::{MatchResult, Matcher};
use crate::ui::run_ui;
use base64::prelude::*;
@ -48,7 +48,7 @@ fn main() -> MainResult {
let mut counts: HashMap<MatchResult, Vec<usize>> = HashMap::new();
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,
Err(e) => {
eprintln!("Failed to parse the first line in the log: {:#}", e);
@ -72,7 +72,7 @@ fn main() -> MainResult {
.enumerate()
.par_bridge()
.flat_map(|(index, line)| {
let mut parsed = serde_json::from_str::<LogLine>(line).ok()?;
let mut parsed = parse_line(line).ok()?;
parsed.index = index;
Some(parsed)
})
@ -143,3 +143,37 @@ fn main() -> MainResult {
fn copy_osc(text: &str) {
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::logline::{FullException, FullLogLine, LogLine, Trace};
use crate::parse_line_full;
use crate::ui::style::{TABLE_HEADER_STYLE, TIME_FORMAT};
use crate::ui::table::{ScrollbarTable, ScrollbarTableState};
use ratatui::prelude::*;
@ -9,7 +10,7 @@ use time::format_description::well_known::Iso8601;
pub fn single_log(app: &App, line: &LogLine) -> SingleLog {
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 }
}

View file

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