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