mirror of
https://codeberg.org/icewind/logsmash.git
synced 2026-06-03 18:14:11 +02:00
full line parse error page
This commit is contained in:
parent
ba88701f5e
commit
eec9d1aa00
4 changed files with 55 additions and 8 deletions
13
src/error.rs
13
src/error.rs
|
|
@ -30,3 +30,16 @@ pub enum ReadError {
|
||||||
#[error("log file contained non-utf8 characters: {0:#}")]
|
#[error("log file contained non-utf8 characters: {0:#}")]
|
||||||
Utf8(#[from] FromUtf8Error),
|
Utf8(#[from] FromUtf8Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
#[error("Error while parsing log line '{line}': {err:#}")]
|
||||||
|
pub struct ParseError {
|
||||||
|
pub err: serde_json::Error,
|
||||||
|
pub line: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for ParseError {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.line == other.line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ fn help(page: UiPage) -> &'static str {
|
||||||
"«Q» Exit - «Esc» Back - «R» Toggle raw - «C» Copy log line - «R» Show logs for request"
|
"«Q» Exit - «Esc» Back - «R» Toggle raw - «C» Copy log line - «R» Show logs for request"
|
||||||
}
|
}
|
||||||
UiPage::Errors => "«Q» Exit - «Esc» Back - «C» Copy log line",
|
UiPage::Errors => "«Q» Exit - «Esc» Back - «C» Copy log line",
|
||||||
|
UiPage::Error => "«Q» Exit - «Esc» Back",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use crate::ui::match_list::match_list;
|
||||||
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::{
|
use crate::ui::state::{
|
||||||
ErrorState, GroupedLogsState, LogState, MatchListState, MatchState, UiState,
|
ErrorLinesState, ErrorState, GroupedLogsState, LogState, MatchListState, MatchState, UiState,
|
||||||
};
|
};
|
||||||
use ratatui::crossterm::event::{DisableMouseCapture, EnableMouseCapture};
|
use ratatui::crossterm::event::{DisableMouseCapture, EnableMouseCapture};
|
||||||
use ratatui::crossterm::terminal::{
|
use ratatui::crossterm::terminal::{
|
||||||
|
|
@ -17,7 +17,9 @@ use ratatui::crossterm::terminal::{
|
||||||
};
|
};
|
||||||
use ratatui::crossterm::ExecutableCommand;
|
use ratatui::crossterm::ExecutableCommand;
|
||||||
use ratatui::prelude::*;
|
use ratatui::prelude::*;
|
||||||
|
use ratatui::widgets::Paragraph;
|
||||||
use ratatui::Terminal;
|
use ratatui::Terminal;
|
||||||
|
use serde_json::Value;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::stdout;
|
use std::io::stdout;
|
||||||
use std::panic::{set_hook, take_hook};
|
use std::panic::{set_hook, take_hook};
|
||||||
|
|
@ -171,9 +173,17 @@ fn ui(frame: &mut Frame, app: &App, state: &mut UiState) {
|
||||||
);
|
);
|
||||||
frame.render_widget(footer(app, state.footer_params()), layout[2]);
|
frame.render_widget(footer(app, state.footer_params()), layout[2]);
|
||||||
}
|
}
|
||||||
UiState::Errors(ErrorState { table_state, .. }) => {
|
UiState::Errors(ErrorLinesState { table_state, .. }) => {
|
||||||
frame.render_stateful_widget(error_list(app), layout[0].union(layout[1]), table_state);
|
frame.render_stateful_widget(error_list(app), layout[0].union(layout[1]), table_state);
|
||||||
frame.render_widget(footer(app, state.footer_params()), layout[2]);
|
frame.render_widget(footer(app, state.footer_params()), layout[2]);
|
||||||
}
|
}
|
||||||
|
UiState::Error(ErrorState { error, .. }) => {
|
||||||
|
let pretty =
|
||||||
|
serde_json::to_string_pretty(&serde_json::from_str::<Value>(&error.line).unwrap())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let par = Paragraph::new(format!("{:#}\n\n{pretty}", error.err));
|
||||||
|
frame.render_widget(par, layout[0].union(layout[1]))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::app::{App, Filter, LogMatch, EMPTY_FILTER};
|
use crate::app::{App, Filter, LogMatch, EMPTY_FILTER};
|
||||||
|
use crate::error::ParseError;
|
||||||
use crate::logfile::logline::{FullLogLine, LogLine};
|
use crate::logfile::logline::{FullLogLine, LogLine};
|
||||||
use crate::ui::footer::FooterParams;
|
use crate::ui::footer::FooterParams;
|
||||||
use crate::ui::input::{PopMode, UiEvent};
|
use crate::ui::input::{PopMode, UiEvent};
|
||||||
|
|
@ -9,6 +10,7 @@ use derive_more::From;
|
||||||
use ratatui::widgets::TableState;
|
use ratatui::widgets::TableState;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[derive(Clone, From, PartialEq)]
|
#[derive(Clone, From, PartialEq)]
|
||||||
pub enum UiState<'a> {
|
pub enum UiState<'a> {
|
||||||
|
|
@ -16,7 +18,8 @@ pub enum UiState<'a> {
|
||||||
Match(MatchState<'a>),
|
Match(MatchState<'a>),
|
||||||
GroupedLogs(GroupedLogsState<'a>),
|
GroupedLogs(GroupedLogsState<'a>),
|
||||||
Log(LogState<'a>),
|
Log(LogState<'a>),
|
||||||
Errors(ErrorState<'a>),
|
Errors(ErrorLinesState<'a>),
|
||||||
|
Error(ErrorState<'a>),
|
||||||
Quit,
|
Quit,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,7 +162,18 @@ impl<'a> GroupedLogsState<'a> {
|
||||||
fn enter(self, selected: usize, app: &'a App<'a>) -> UiState<'a> {
|
fn enter(self, selected: usize, app: &'a App<'a>) -> UiState<'a> {
|
||||||
let log = self.get_selected(selected, app);
|
let log = self.get_selected(selected, app);
|
||||||
let raw_line = app.get_line(log.index).unwrap();
|
let raw_line = app.get_line(log.index).unwrap();
|
||||||
let full_line = parse_line_full(raw_line).unwrap();
|
let full_line = match parse_line_full(raw_line) {
|
||||||
|
Ok(line) => line,
|
||||||
|
Err(err) => {
|
||||||
|
return UiState::Error(ErrorState {
|
||||||
|
error: Arc::new(ParseError {
|
||||||
|
err,
|
||||||
|
line: raw_line.into(),
|
||||||
|
}),
|
||||||
|
previous: Box::new(self.into()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
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 {
|
||||||
|
|
@ -198,12 +212,12 @@ impl PartialEq for GroupedLogsState<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ErrorState<'a> {
|
pub struct ErrorLinesState<'a> {
|
||||||
pub table_state: ScrollbarTableState,
|
pub table_state: ScrollbarTableState,
|
||||||
pub previous: Box<UiState<'a>>,
|
pub previous: Box<UiState<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for ErrorState<'_> {
|
impl PartialEq for ErrorLinesState<'_> {
|
||||||
fn eq(&self, _other: &Self) -> bool {
|
fn eq(&self, _other: &Self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
@ -258,6 +272,7 @@ impl<'a> UiState<'a> {
|
||||||
UiState::GroupedLogs(_) => UiPage::Logs,
|
UiState::GroupedLogs(_) => UiPage::Logs,
|
||||||
UiState::Log(_) => UiPage::Log,
|
UiState::Log(_) => UiPage::Log,
|
||||||
UiState::Errors(_) => UiPage::Errors,
|
UiState::Errors(_) => UiPage::Errors,
|
||||||
|
UiState::Error(_) => UiPage::Error,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -373,6 +388,7 @@ impl<'a> UiState<'a> {
|
||||||
UiState::GroupedLogs(_) => UI_HEADER_SIZE + 1,
|
UiState::GroupedLogs(_) => UI_HEADER_SIZE + 1,
|
||||||
UiState::Log(_) => 0,
|
UiState::Log(_) => 0,
|
||||||
UiState::Errors(_) => 0,
|
UiState::Errors(_) => 0,
|
||||||
|
UiState::Error(_) => 0,
|
||||||
UiState::Quit => 0,
|
UiState::Quit => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -422,7 +438,7 @@ impl<'a> UiState<'a> {
|
||||||
let table_state = ScrollbarTableState::new(app.error_lines.len());
|
let table_state = ScrollbarTableState::new(app.error_lines.len());
|
||||||
(
|
(
|
||||||
true,
|
true,
|
||||||
UiState::Errors(ErrorState {
|
UiState::Errors(ErrorLinesState {
|
||||||
table_state,
|
table_state,
|
||||||
previous: Box::new(state.into()),
|
previous: Box::new(state.into()),
|
||||||
}),
|
}),
|
||||||
|
|
@ -513,7 +529,7 @@ impl<'a> UiState<'a> {
|
||||||
UiState::Match(MatchState { previous, .. })
|
UiState::Match(MatchState { previous, .. })
|
||||||
| UiState::GroupedLogs(GroupedLogsState { previous, .. })
|
| UiState::GroupedLogs(GroupedLogsState { previous, .. })
|
||||||
| UiState::Log(LogState { previous, .. })
|
| UiState::Log(LogState { previous, .. })
|
||||||
| UiState::Errors(ErrorState { previous, .. }),
|
| UiState::Errors(ErrorLinesState { previous, .. }),
|
||||||
UiEvent::Back,
|
UiEvent::Back,
|
||||||
) => (true, *previous),
|
) => (true, *previous),
|
||||||
(state, _) => (false, state),
|
(state, _) => (false, state),
|
||||||
|
|
@ -538,4 +554,11 @@ pub enum UiPage {
|
||||||
Logs,
|
Logs,
|
||||||
Log,
|
Log,
|
||||||
Errors,
|
Errors,
|
||||||
|
Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq)]
|
||||||
|
pub struct ErrorState<'a> {
|
||||||
|
pub error: Arc<ParseError>,
|
||||||
|
pub previous: Box<UiState<'a>>,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue