mirror of
https://codeberg.org/icewind/logsmash.git
synced 2026-06-03 18:14:11 +02:00
group by user agent
This commit is contained in:
parent
181559d841
commit
cbdc59d591
3 changed files with 44 additions and 0 deletions
|
|
@ -3,12 +3,14 @@ mod remote;
|
||||||
mod unique;
|
mod unique;
|
||||||
mod url;
|
mod url;
|
||||||
mod user;
|
mod user;
|
||||||
|
mod useragent;
|
||||||
|
|
||||||
use crate::app::{Filter, LineSet};
|
use crate::app::{Filter, LineSet};
|
||||||
use crate::grouping::app::{AppGrouping, APP_GROUPING_UI};
|
use crate::grouping::app::{AppGrouping, APP_GROUPING_UI};
|
||||||
use crate::grouping::remote::{RemoteGrouping, REMOTE_GROUPING_UI};
|
use crate::grouping::remote::{RemoteGrouping, REMOTE_GROUPING_UI};
|
||||||
use crate::grouping::url::{UrlGrouping, URL_GROUPING_UI};
|
use crate::grouping::url::{UrlGrouping, URL_GROUPING_UI};
|
||||||
use crate::grouping::user::{UserGrouping, USER_GROUPING_UI};
|
use crate::grouping::user::{UserGrouping, USER_GROUPING_UI};
|
||||||
|
use crate::grouping::useragent::{UserAgentGrouping, USER_AGENT_GROUPING_UI};
|
||||||
use crate::logfile::LogLine;
|
use crate::logfile::LogLine;
|
||||||
use crate::matcher::MatchResult;
|
use crate::matcher::MatchResult;
|
||||||
use crate::timegraph::{SparkLine, TimeGraph};
|
use crate::timegraph::{SparkLine, TimeGraph};
|
||||||
|
|
@ -132,6 +134,7 @@ pub enum Groupings<'logs> {
|
||||||
App(AppGrouping<'logs>),
|
App(AppGrouping<'logs>),
|
||||||
User(UserGrouping<'logs>),
|
User(UserGrouping<'logs>),
|
||||||
Remote(RemoteGrouping<'logs>),
|
Remote(RemoteGrouping<'logs>),
|
||||||
|
UserAgent(UserAgentGrouping<'logs>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'logs> GroupingResult<'logs> for Groupings<'logs> {
|
impl<'logs> GroupingResult<'logs> for Groupings<'logs> {
|
||||||
|
|
@ -142,6 +145,7 @@ impl<'logs> GroupingResult<'logs> for Groupings<'logs> {
|
||||||
Groupings::App(r) => r.matches(filter),
|
Groupings::App(r) => r.matches(filter),
|
||||||
Groupings::User(r) => r.matches(filter),
|
Groupings::User(r) => r.matches(filter),
|
||||||
Groupings::Remote(r) => r.matches(filter),
|
Groupings::Remote(r) => r.matches(filter),
|
||||||
|
Groupings::UserAgent(r) => r.matches(filter),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,6 +158,7 @@ impl<'logs> GroupingResult<'logs> for Groupings<'logs> {
|
||||||
Groupings::App(r) => Box::new(r.render()),
|
Groupings::App(r) => Box::new(r.render()),
|
||||||
Groupings::User(r) => Box::new(r.render()),
|
Groupings::User(r) => Box::new(r.render()),
|
||||||
Groupings::Remote(r) => Box::new(r.render()),
|
Groupings::Remote(r) => Box::new(r.render()),
|
||||||
|
Groupings::UserAgent(r) => Box::new(r.render()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -164,6 +169,7 @@ pub enum GroupingOptions {
|
||||||
App,
|
App,
|
||||||
User,
|
User,
|
||||||
Remote,
|
Remote,
|
||||||
|
UserAgent,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GroupingOptions {
|
impl GroupingOptions {
|
||||||
|
|
@ -173,6 +179,7 @@ impl GroupingOptions {
|
||||||
GroupingOptions::App,
|
GroupingOptions::App,
|
||||||
GroupingOptions::User,
|
GroupingOptions::User,
|
||||||
GroupingOptions::Remote,
|
GroupingOptions::Remote,
|
||||||
|
GroupingOptions::UserAgent,
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
}
|
}
|
||||||
|
|
@ -184,6 +191,7 @@ impl GroupingOptions {
|
||||||
GroupingOptions::App => line.app.hash(&mut hasher),
|
GroupingOptions::App => line.app.hash(&mut hasher),
|
||||||
GroupingOptions::User => line.user.hash(&mut hasher),
|
GroupingOptions::User => line.user.hash(&mut hasher),
|
||||||
GroupingOptions::Remote => line.remote.hash(&mut hasher),
|
GroupingOptions::Remote => line.remote.hash(&mut hasher),
|
||||||
|
GroupingOptions::UserAgent => line.user_agent.hash(&mut hasher),
|
||||||
}
|
}
|
||||||
hasher.finish()
|
hasher.finish()
|
||||||
}
|
}
|
||||||
|
|
@ -202,6 +210,9 @@ impl GroupingOptions {
|
||||||
GroupingOptions::Remote => Groupings::Remote(RemoteGrouping {
|
GroupingOptions::Remote => Groupings::Remote(RemoteGrouping {
|
||||||
remote: line.remote.as_str(),
|
remote: line.remote.as_str(),
|
||||||
}),
|
}),
|
||||||
|
GroupingOptions::UserAgent => Groupings::UserAgent(UserAgentGrouping {
|
||||||
|
user_agent: line.user_agent.as_ref(),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,6 +222,7 @@ impl GroupingOptions {
|
||||||
GroupingOptions::App => "App",
|
GroupingOptions::App => "App",
|
||||||
GroupingOptions::User => "User",
|
GroupingOptions::User => "User",
|
||||||
GroupingOptions::Remote => "Remote",
|
GroupingOptions::Remote => "Remote",
|
||||||
|
GroupingOptions::UserAgent => "User Agent",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -220,6 +232,7 @@ impl GroupingOptions {
|
||||||
GroupingOptions::App => APP_GROUPING_UI,
|
GroupingOptions::App => APP_GROUPING_UI,
|
||||||
GroupingOptions::User => USER_GROUPING_UI,
|
GroupingOptions::User => USER_GROUPING_UI,
|
||||||
GroupingOptions::Remote => REMOTE_GROUPING_UI,
|
GroupingOptions::Remote => REMOTE_GROUPING_UI,
|
||||||
|
GroupingOptions::UserAgent => USER_AGENT_GROUPING_UI,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
29
src/grouping/useragent.rs
Normal file
29
src/grouping/useragent.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
use crate::app::Filter;
|
||||||
|
use crate::grouping::{GroupingResult, GroupingUi};
|
||||||
|
use ratatui::layout::{Alignment, Constraint};
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone)]
|
||||||
|
pub struct UserAgentGrouping<'a> {
|
||||||
|
pub user_agent: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const USER_AGENT_GROUPING_UI: GroupingUi = GroupingUi {
|
||||||
|
header: &[("User Agent", Alignment::Left)],
|
||||||
|
widths: &[Constraint::Percentage(100)],
|
||||||
|
};
|
||||||
|
|
||||||
|
impl<'a> GroupingResult<'a> for UserAgentGrouping<'a> {
|
||||||
|
fn matches(&self, filter: &Filter) -> bool {
|
||||||
|
if filter.is_empty() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
filter
|
||||||
|
.parts()
|
||||||
|
.all(|filter_part| filter_part.is_match(self.user_agent))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&self) -> impl Iterator<Item = Cow<'a, str>> {
|
||||||
|
[self.user_agent.into()].into_iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -43,6 +43,8 @@ pub struct LogLine<'a> {
|
||||||
pub message: Cow<'a, str>,
|
pub message: Cow<'a, str>,
|
||||||
pub exception: Option<Exception<'a>>,
|
pub exception: Option<Exception<'a>>,
|
||||||
pub app: Cow<'a, str>,
|
pub app: Cow<'a, str>,
|
||||||
|
#[serde(rename = "userAgent")]
|
||||||
|
pub user_agent: Cow<'a, str>,
|
||||||
#[serde(with = "date")]
|
#[serde(with = "date")]
|
||||||
pub time: OffsetDateTime,
|
pub time: OffsetDateTime,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue