space separated filter parts

This commit is contained in:
Robin Appelman 2024-12-17 20:15:27 +01:00
commit af9db2fa09
2 changed files with 43 additions and 41 deletions

View file

@ -87,18 +87,20 @@ impl LogMatch {
return true; return true;
} }
self.statements(app).any(|statement| { self.statements(app).any(|statement| {
filter.matches(statement.pattern) filter.parts().all(|filter_part| {
|| filter.matches(statement.path) filter_part.is_match(statement.pattern)
|| filter.matches(statement.path_prefix) || filter_part.is_match(statement.path)
|| filter_part.is_match(statement.path_prefix)
|| statement || statement
.placeholders .placeholders
.iter() .iter()
.any(|placeholder| filter.matches(placeholder)) .any(|placeholder| filter_part.is_match(placeholder))
|| statement || statement
.exception .exception
.filter(|exception| filter.matches(exception)) .filter(|exception| filter_part.is_match(exception))
.is_some() .is_some()
}) })
})
} }
} }
@ -155,46 +157,44 @@ impl GroupedLines {
return true; return true;
} }
let line = &app.lines[self.lines[0]]; let line = &app.lines[self.lines[0]];
filter.matches(&line.message) filter
.parts()
.all(|filter_part| filter_part.is_match(&line.message))
} }
} }
#[derive(Default, Clone)] #[derive(Default, Clone)]
pub struct Filter { pub struct Filter {
filter: String, filter: String,
regex: Option<Regex>, regexes: Vec<Regex>,
} }
pub static EMPTY_FILTER: Filter = Filter { pub static EMPTY_FILTER: Filter = Filter {
filter: String::new(), filter: String::new(),
regex: None, regexes: Vec::new(),
}; };
impl Filter { impl Filter {
fn build_regex(filter: &str) -> Option<Regex> { fn build_regex(filter: &str) -> Vec<Regex> {
if filter.is_empty() { filter
None .split(' ')
} else { .map(|part| {
Some( RegexBuilder::new(&escape(part))
RegexBuilder::new(&escape(&filter))
.case_insensitive(true) .case_insensitive(true)
.build() .build()
.unwrap(), .unwrap()
) })
} .collect()
} }
#[allow(dead_code)] #[allow(dead_code)]
pub fn new(filter: String) -> Self { pub fn new(filter: String) -> Self {
let regex = Self::build_regex(&filter); let regexes = Self::build_regex(&filter);
Filter { filter, regex } Filter { filter, regexes }
} }
pub fn matches(&self, string: &str) -> bool { pub fn parts(&self) -> impl Iterator<Item = &Regex> {
match &self.regex { self.regexes.iter()
Some(regex) => regex.is_match(string),
None => true,
}
} }
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
@ -203,24 +203,24 @@ impl Filter {
pub fn push(&mut self, c: char) { pub fn push(&mut self, c: char) {
self.filter.push(c); self.filter.push(c);
self.regex = Self::build_regex(&self.filter); self.regexes = Self::build_regex(&self.filter);
} }
pub fn pop(&mut self) { pub fn pop(&mut self) {
self.filter.pop(); self.filter.pop();
self.regex = Self::build_regex(&self.filter); self.regexes = Self::build_regex(&self.filter);
} }
pub fn pop_word(&mut self) { pub fn pop_word(&mut self) {
let previous_word_boundary = self.filter.trim().rfind(' ').map(|i| i + 1); let previous_word_boundary = self.filter.trim().rfind(' ').map(|i| i + 1);
self.filter self.filter
.truncate(previous_word_boundary.unwrap_or_default()); .truncate(previous_word_boundary.unwrap_or_default());
self.regex = Self::build_regex(&self.filter); self.regexes = Self::build_regex(&self.filter);
} }
pub fn clear(&mut self) { pub fn clear(&mut self) {
self.filter.clear(); self.filter.clear();
self.regex = None; self.regexes = Vec::new();
} }
} }

View file

@ -139,13 +139,15 @@ impl<'a> LogLine<'a> {
return true; return true;
} }
// todo: exception, more? // todo: exception, more?
filter.matches(&self.app) filter.parts().all(|filter_part| {
|| filter.matches(&self.message) filter_part.is_match(&self.app)
|| filter.matches(self.request_id.as_str()) || filter_part.is_match(&self.message)
|| filter.matches(&self.url) || filter_part.is_match(self.request_id.as_str())
|| filter.matches(&self.method) || filter_part.is_match(&self.url)
|| filter.matches(&self.remote) || filter_part.is_match(&self.method)
|| filter.matches(&self.user) || filter_part.is_match(&self.remote)
|| filter_part.is_match(&self.user)
})
} }
} }