factor out common loop that tests a sequence of limiters

This commit is contained in:
Chris Beck
2025-12-06 19:45:33 -07:00
parent 225b308a26
commit 12f0c99ef9
4 changed files with 27 additions and 20 deletions
+3 -6
View File
@@ -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
+1 -1
View File
@@ -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};
+6 -12
View File
@@ -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
+17 -1
View File
@@ -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.