factor out common loop that tests a sequence of limiters
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use super::{
|
||||
LimitResult, Limiter, LimiterSet, SignalAlertMessage, Summary,
|
||||
LimitResult, Limiter, LimiterSet, SignalAlertMessage, Summary, evaluate_limiter_sequence,
|
||||
log_buffer::LogBuffer,
|
||||
route::{Destination, Limit, Route},
|
||||
};
|
||||
@@ -262,11 +262,8 @@ impl LogHandler {
|
||||
};
|
||||
|
||||
// At least one route passed, now check overall limits
|
||||
for (idx, (filter, limiter)) in self.overall_limits.iter().enumerate() {
|
||||
// Only evaluate the limiter if the message matches the filter
|
||||
if filter.matches(log_msg) && !limiter.evaluate(log_msg) {
|
||||
return Err(SuppressionReason::Overall(LimitResult::OverallLimiter(idx)));
|
||||
}
|
||||
if let Err(i) = evaluate_limiter_sequence(&self.overall_limits, log_msg) {
|
||||
return Err(SuppressionReason::Overall(LimitResult::OverallLimiter(i)));
|
||||
}
|
||||
|
||||
// All checks passed
|
||||
|
||||
@@ -39,7 +39,7 @@ mod rate_limiter_set;
|
||||
pub use rate_limiter_set::{LimitResult, LimiterSet};
|
||||
|
||||
mod route;
|
||||
pub use route::{Destination, Limit, Route};
|
||||
pub use route::{Destination, Limit, Route, evaluate_limiter_sequence};
|
||||
|
||||
pub use crate::rate_limiter::{Limiter, RateThreshold};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//! Rate limiter set for managing per-route rate limiting.
|
||||
|
||||
use super::evaluate_limiter_sequence;
|
||||
use crate::{
|
||||
concurrent_map::LazyMap,
|
||||
log_message::{LogFilter, LogMessage, Origin},
|
||||
@@ -54,13 +55,9 @@ impl LimiterSet {
|
||||
pub fn evaluate(&self, log_msg: &LogMessage, origin: &Origin) -> LimitResult {
|
||||
// Check per-origin limiters
|
||||
let origin_result = self.limiters.get(origin, |origin_limiters| {
|
||||
for (i, (filter, limiter)) in origin_limiters.iter().enumerate() {
|
||||
// Only evaluate the limiter if the message matches the filter
|
||||
if filter.matches(log_msg) && !limiter.evaluate(log_msg) {
|
||||
return Some(LimitResult::Limiter(i));
|
||||
}
|
||||
}
|
||||
None
|
||||
evaluate_limiter_sequence(origin_limiters, log_msg)
|
||||
.err()
|
||||
.map(LimitResult::Limiter)
|
||||
});
|
||||
|
||||
if let Some(result) = origin_result {
|
||||
@@ -68,11 +65,8 @@ impl LimiterSet {
|
||||
}
|
||||
|
||||
// Check global limiters
|
||||
for (i, (filter, limiter)) in self.global_limiters.iter().enumerate() {
|
||||
// Only evaluate the limiter if the message matches the filter
|
||||
if filter.matches(log_msg) && !limiter.evaluate(log_msg) {
|
||||
return LimitResult::GlobalLimiter(i);
|
||||
}
|
||||
if let Err(i) = evaluate_limiter_sequence(&self.global_limiters, log_msg) {
|
||||
return LimitResult::GlobalLimiter(i);
|
||||
}
|
||||
|
||||
LimitResult::Passed
|
||||
|
||||
@@ -5,11 +5,27 @@
|
||||
|
||||
use super::LimiterSet;
|
||||
use crate::{
|
||||
log_message::{Level, LogFilter},
|
||||
log_message::{Level, LogFilter, LogMessage},
|
||||
rate_limiter::{Limiter, RateThreshold},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
/// Evaluate a sequence of (filter, limiter) pairs against a log message.
|
||||
///
|
||||
/// Returns `Ok(())` if no limiter blocks the message.
|
||||
/// Returns `Err(index)` if the limiter at `index` blocked the message.
|
||||
pub fn evaluate_limiter_sequence(
|
||||
seq: &[(LogFilter, Limiter)],
|
||||
log_msg: &LogMessage,
|
||||
) -> Result<(), usize> {
|
||||
for (i, (filter, limiter)) in seq.iter().enumerate() {
|
||||
if filter.matches(log_msg) && !limiter.evaluate(log_msg) {
|
||||
return Err(i);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// A rate limit rule for suppressing repeated alerts.
|
||||
///
|
||||
/// Combines a filter to match specific log messages with a rate threshold.
|
||||
|
||||
Reference in New Issue
Block a user