cleanup
Some checks failed
CI / matrix (push) Failing after 2s
CI / ${{ matrix.check }} (push) Has been skipped
CI / build (push) Has been skipped
CI / build-nixpkgs (push) Has been skipped

This commit is contained in:
Robin Appelman 2024-09-27 18:17:54 +02:00
commit e17bbb4950
6 changed files with 60 additions and 69 deletions

View file

@ -4,11 +4,8 @@ use crate::matcher::MatchResult;
use crate::timegraph::TimeGraph; use crate::timegraph::TimeGraph;
use logsmash_data::StatementList; use logsmash_data::StatementList;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use time::OffsetDateTime;
pub struct App<'a> { pub struct App<'a> {
pub first_date: OffsetDateTime,
pub last_date: OffsetDateTime,
pub lines: Vec<LogLine<'a>>, pub lines: Vec<LogLine<'a>>,
pub log_statements: StatementList, pub log_statements: StatementList,
pub matches: Vec<LogMatch>, pub matches: Vec<LogMatch>,

View file

@ -137,6 +137,7 @@ pub struct Exception<'a> {
} }
#[derive(Deserialize, Clone)] #[derive(Deserialize, Clone)]
#[allow(dead_code)]
pub struct FullLogLine { pub struct FullLogLine {
#[serde(rename = "reqId")] #[serde(rename = "reqId")]
pub request_id: TinyAsciiStr<32>, pub request_id: TinyAsciiStr<32>,
@ -158,6 +159,7 @@ pub struct FullLogLine {
#[derive(Deserialize, Debug, Clone)] #[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]
#[allow(dead_code)]
pub struct FullException { pub struct FullException {
pub exception: String, pub exception: String,
pub message: String, pub message: String,
@ -170,6 +172,7 @@ pub struct FullException {
#[derive(Deserialize, Debug, Clone)] #[derive(Deserialize, Debug, Clone)]
#[serde(untagged)] #[serde(untagged)]
#[allow(dead_code)]
pub enum ExceptionCode { pub enum ExceptionCode {
Num(isize), Num(isize),
String(String), String(String),
@ -184,6 +187,7 @@ impl FullException {
} }
#[derive(Deserialize, Debug, Clone)] #[derive(Deserialize, Debug, Clone)]
#[allow(dead_code)]
pub struct Trace { pub struct Trace {
#[serde(default)] #[serde(default)]
pub file: String, pub file: String,

View file

@ -130,8 +130,6 @@ fn main() -> MainResult {
.collect(); .collect();
let app = App { let app = App {
first_date: parsed_lines[0].time,
last_date: parsed_lines.last().unwrap().time,
lines: parsed_lines, lines: parsed_lines,
log_statements: statements, log_statements: statements,
error_lines, error_lines,

View file

@ -184,10 +184,12 @@ fn ui(frame: &mut Frame, app: &App, state: &mut UiState) {
frame.render_widget(footer(app, page), layout[2]); frame.render_widget(footer(app, page), layout[2]);
} }
UiState::Log(LogState { UiState::Log(LogState {
log, table_state, .. table_state,
full_line,
..
}) => { }) => {
frame.render_stateful_widget( frame.render_stateful_widget(
single_log(app, log), single_log(full_line),
layout[0].union(layout[1]), layout[0].union(layout[1]),
table_state, table_state,
); );

View file

@ -1,28 +1,24 @@
use crate::app::App; use crate::logline::{format_time, FullException, FullLogLine, Trace};
use crate::logline::{format_time, FullException, FullLogLine, LogLine, Trace};
use crate::parse_line_full;
use crate::ui::style::TABLE_HEADER_STYLE; use crate::ui::style::TABLE_HEADER_STYLE;
use crate::ui::table::{ScrollbarTable, ScrollbarTableState}; use crate::ui::table::{ScrollbarTable, ScrollbarTableState};
use ratatui::prelude::*; use ratatui::prelude::*;
use ratatui::widgets::{Cell, Paragraph, Row, Wrap}; use ratatui::widgets::{Cell, Paragraph, Row, Wrap};
use std::iter::once; use std::iter::once;
pub fn single_log(app: &App, line: &LogLine) -> SingleLog { pub fn single_log(line: &FullLogLine) -> SingleLog {
let raw_line = app.get_line(line.index);
let line = raw_line.and_then(|raw_line| parse_line_full(raw_line).ok());
SingleLog::new(line) SingleLog::new(line)
} }
pub struct SingleLog { pub struct SingleLog<'a> {
line: Option<FullLogLine>, line: &'a FullLogLine,
path_prefix_length: usize, path_prefix_length: usize,
} }
impl SingleLog { impl<'a> SingleLog<'a> {
pub fn new(line: Option<FullLogLine>) -> Self { pub fn new(line: &'a FullLogLine) -> Self {
let path_prefix_length = line let path_prefix_length = line
.exception
.as_ref() .as_ref()
.and_then(|line| line.exception.as_ref())
.map(|ex| find_path_prefix_length(ex.trace.iter().map(|t| t.file.as_str()))) .map(|ex| find_path_prefix_length(ex.trace.iter().map(|t| t.file.as_str())))
.unwrap_or_default(); .unwrap_or_default();
SingleLog { SingleLog {
@ -32,65 +28,61 @@ impl SingleLog {
} }
} }
impl StatefulWidget for SingleLog { impl StatefulWidget for SingleLog<'_> {
type State = ScrollbarTableState; type State = ScrollbarTableState;
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State)
where where
Self: Sized, Self: Sized,
{ {
if let Some(line) = self.line { let line = self.line;
let par = Paragraph::new(format!( let par = Paragraph::new(format!(
"{}\n\n {} {}\n {}\n\n {} from {} by {} at {} - Nextcloud {}", "{}\n\n {} {}\n {}\n\n {} from {} by {} at {} - Nextcloud {}",
line.message, line.message,
line.method, line.method,
line.url, line.url,
line.user_agent, line.user_agent,
line.request_id, line.request_id,
line.remote_address, line.remote_address,
line.user, line.user,
format_time(line.time), format_time(line.time),
line.version, line.version,
)) ))
.wrap(Wrap::default()); .wrap(Wrap::default());
let layout = Layout::default() let layout = Layout::default()
.direction(Direction::Vertical) .direction(Direction::Vertical)
.constraints(vec![ .constraints(vec![
Constraint::Min(7), Constraint::Min(7),
Constraint::Min(5), Constraint::Min(5),
Constraint::Percentage(100), Constraint::Percentage(100),
]) ])
.split(area); .split(area);
par.render(layout[0], buf); par.render(layout[0], buf);
if let Some(exception) = &line.exception { if let Some(exception) = &line.exception {
if line.message.contains(&exception.message) { if line.message.contains(&exception.message) {
StatefulWidget::render( StatefulWidget::render(
render_exception(exception, self.path_prefix_length), render_exception(exception, self.path_prefix_length),
layout[1].union(layout[2]), layout[1].union(layout[2]),
buf, buf,
state, state,
); );
} else { } else {
let ex_par = Paragraph::new(format!( let ex_par = Paragraph::new(format!(
"\n{}:\n {}", "\n{}:\n {}",
exception.exception, exception.message exception.exception, exception.message
)) ))
.wrap(Wrap::default()); .wrap(Wrap::default());
ex_par.render(layout[1], buf); ex_par.render(layout[1], buf);
StatefulWidget::render( StatefulWidget::render(
render_exception(exception, self.path_prefix_length), render_exception(exception, self.path_prefix_length),
layout[2], layout[2],
buf, buf,
state, state,
); );
}
} }
} else {
let par = Paragraph::new("Failed to parse log line").wrap(Wrap::default());
par.render(area, buf);
} }
} }
} }

View file

@ -110,7 +110,6 @@ impl<'a> LogsState<'a> {
UiState::Log(LogState { UiState::Log(LogState {
log, log,
full_line, full_line,
trace_len,
table_state, table_state,
previous: Box::new(self.into()), previous: Box::new(self.into()),
}) })
@ -137,7 +136,6 @@ impl PartialEq for ErrorState<'_> {
#[derive(Clone)] #[derive(Clone)]
pub struct LogState<'a> { pub struct LogState<'a> {
pub trace_len: usize,
pub log: &'a LogLine<'a>, pub log: &'a LogLine<'a>,
pub full_line: FullLogLine, pub full_line: FullLogLine,
pub table_state: ScrollbarTableState, pub table_state: ScrollbarTableState,