This commit is contained in:
Robin Appelman 2024-07-28 16:17:19 +02:00
commit 6d4ec29d43
5 changed files with 40 additions and 23 deletions

View file

@ -15,7 +15,7 @@ impl StatementList {
StatementList { statements } StatementList { statements }
} }
pub fn iter(&self) -> impl Iterator<Item = &'static LoggingStatement> + '_ { pub fn iter(&self) -> impl Iterator<Item = &'static LoggingStatement> + Send + '_ {
self.statements self.statements
.iter() .iter()
.copied() .copied()

View file

@ -61,43 +61,40 @@ fn main() -> MainResult {
let lines = once(first).chain(lines); let lines = once(first).chain(lines);
let results: Vec<_> = lines let mut results: Vec<_> = lines
.enumerate() .enumerate()
.par_bridge() .par_bridge()
.filter(|(_, line)| line.starts_with('{')) .flat_map(|(index, line)| {
.map(|(index, line)| { let mut parsed = serde_json::from_str::<LogLine>(&line).ok()?;
let mut parsed = serde_json::from_str::<LogLine>(&line)?;
parsed.index = index; parsed.index = index;
Some(parsed)
})
.map(|parsed| {
let log_match = matcher.match_log(&parsed); let log_match = matcher.match_log(&parsed);
Result::<_, serde_json::Error>::Ok((parsed, log_match)) (parsed, log_match)
}) })
.collect(); .collect();
let mut error_count = 0; results.sort_by_key(|(line, _)| line.index);
let mut parsed_lines = Vec::with_capacity(1024); let mut parsed_lines = Vec::with_capacity(1024);
let mut unmatched_lines = Vec::with_capacity(256); let mut unmatched_lines = Vec::with_capacity(256);
let mut parsed_index = 0;
for result in results { for (parsed_index, result) in results.into_iter().enumerate() {
let parsed = match result { let parsed = match result {
Ok((parsed, Some(match_result))) => { (parsed, Some(match_result)) => {
counts.entry(match_result).or_default().push(parsed_index); counts.entry(match_result).or_default().push(parsed_index);
parsed parsed
} }
Ok((parsed, None)) => { (parsed, None) => {
unmatched_lines.push(parsed_index); unmatched_lines.push(parsed_index);
parsed parsed
} }
Err(_) => {
error_count += 1;
continue;
}
}; };
parsed_lines.push(parsed); parsed_lines.push(parsed);
parsed_index += 1;
} }
parsed_lines.sort_by_key(|line| line.index); let error_count = log_file.iter().count();
let mut matched_lines: Vec<(_, _)> = counts.into_iter().collect(); let mut matched_lines: Vec<(_, _)> = counts.into_iter().collect();
matched_lines.sort_by_key(|(_, lines)| lines.len()); matched_lines.sort_by_key(|(_, lines)| lines.len());
@ -111,7 +108,7 @@ fn main() -> MainResult {
let unmatched = LogMatch::new(None, unmatched_lines, &parsed_lines); let unmatched = LogMatch::new(None, unmatched_lines, &parsed_lines);
let matches = matched_lines let matches = matched_lines
.into_iter() .into_par_iter()
.map(|(result, lines)| LogMatch::new(Some(result), lines, &parsed_lines)) .map(|(result, lines)| LogMatch::new(Some(result), lines, &parsed_lines))
.collect(); .collect();

View file

@ -1,6 +1,7 @@
use crate::logline::LogLine; use crate::logline::LogLine;
use itertools::Either; use itertools::Either;
use logsmash_data::{LogLevel, LoggingStatement, StatementList}; use logsmash_data::{LogLevel, LoggingStatement, StatementList};
use rayon::prelude::*;
use regex::Regex; use regex::Regex;
use std::iter::once; use std::iter::once;
@ -41,6 +42,7 @@ impl Matcher {
let matches: Vec<_> = statements let matches: Vec<_> = statements
.iter() .iter()
.enumerate() .enumerate()
.par_bridge()
.map(|(index, statement)| LogMatch::new(index, statement)) .map(|(index, statement)| LogMatch::new(index, statement))
.collect(); .collect();
@ -89,12 +91,28 @@ impl Matcher {
} }
} }
#[derive(Debug, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Clone, Eq, Hash)]
pub enum MatchResult { pub enum MatchResult {
Single(usize), Single(usize),
List(Vec<usize>), List(Vec<usize>),
} }
impl PartialEq for MatchResult {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(MatchResult::Single(a), MatchResult::Single(b)) => a.eq(b),
(MatchResult::List(a), MatchResult::List(b)) => {
let mut a = a.clone();
let mut b = b.clone();
a.sort();
b.sort();
a.eq(&b)
}
_ => false,
}
}
}
impl MatchResult { impl MatchResult {
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
match self { match self {

View file

@ -6,7 +6,7 @@ use crate::ui::match_list::match_list;
use crate::ui::raw_logs::raw_logs; use crate::ui::raw_logs::raw_logs;
use crate::ui::single_log::single_log; use crate::ui::single_log::single_log;
use crate::ui::single_match::grouped_lines; use crate::ui::single_match::grouped_lines;
use crate::ui::state::{LogState, LogsState, MatchListState, MatchState, UiEvent, UiState}; use crate::ui::state::{LogState, LogsState, MatchListState, MatchState, UiEvent, UiPage, UiState};
use ratatui::crossterm::event::{Event, KeyCode, KeyModifiers}; use ratatui::crossterm::event::{Event, KeyCode, KeyModifiers};
use ratatui::crossterm::terminal::{ use ratatui::crossterm::terminal::{
disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen,
@ -36,7 +36,7 @@ pub fn run_ui(app: App) -> Result<(), UiError> {
while !matches!(ui_state, UiState::Quit) { while !matches!(ui_state, UiState::Quit) {
terminal.draw(|frame| ui(frame, &app, &mut ui_state))?; terminal.draw(|frame| ui(frame, &app, &mut ui_state))?;
if let Some(event) = handle_events()? { if let Some(event) = handle_events(ui_state.page())? {
ui_state = ui_state.process(event, &app); ui_state = ui_state.process(event, &app);
} }
} }
@ -46,7 +46,7 @@ pub fn run_ui(app: App) -> Result<(), UiError> {
Ok(()) Ok(())
} }
fn handle_events() -> io::Result<Option<UiEvent>> { fn handle_events(page: UiPage) -> io::Result<Option<UiEvent>> {
if event::poll(std::time::Duration::from_millis(50))? { if event::poll(std::time::Duration::from_millis(50))? {
if let Event::Key(key) = event::read()? { if let Event::Key(key) = event::read()? {
if key.kind == event::KeyEventKind::Press { if key.kind == event::KeyEventKind::Press {
@ -55,7 +55,8 @@ fn handle_events() -> io::Result<Option<UiEvent>> {
Some(UiEvent::Quit) Some(UiEvent::Quit)
} }
KeyCode::Char('q') => Some(UiEvent::Quit), KeyCode::Char('q') => Some(UiEvent::Quit),
KeyCode::Esc | KeyCode::Left => Some(UiEvent::Back), KeyCode::Esc => Some(UiEvent::Back),
KeyCode::Left if page != UiPage::MatchList => Some(UiEvent::Back),
KeyCode::Down => Some(UiEvent::Down(1)), KeyCode::Down => Some(UiEvent::Down(1)),
KeyCode::Up => Some(UiEvent::Up(1)), KeyCode::Up => Some(UiEvent::Up(1)),
KeyCode::PageDown => Some(UiEvent::Down(10)), KeyCode::PageDown => Some(UiEvent::Down(10)),

View file

@ -208,6 +208,7 @@ pub enum UiEvent {
Copy, Copy,
} }
#[derive(PartialEq)]
pub enum UiPage { pub enum UiPage {
MatchList, MatchList,
Match, Match,