Add alert rules with FilterBar-based triggers and ntfy delivery (tickets 017-019)
Adds AlertRule/AlertCondition/AlertSink models with CRUD persisted on Settings (mirroring CssEntry's shape), per-line trigger evaluation hooked into the engine's ingest path (Immediate/Threshold/NewValue/Ratio conditions), and best-effort ntfy delivery spawned off the ingest hot path. Design notes: - Alert queries reuse FilterBar syntax but only support the regex()/sequence/timestamp subset (no metric[param] comparisons), since resolving those would require a full bucket rescan per alert per ingested line rather than cost proportional to new logs. - Ratio's zero-denominator case skips evaluation for that line rather than treating the ratio as infinite. - NewValue's seen-value set is in-memory only and does not survive a restart, matching the engine's other non-persisted runtime state. engine::run now takes a SettingsHandle (moved from api.rs to settings.rs so engine.rs can depend on it without a circular import) to read the current alert rules on each ingest. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XFUNZwCvz3kcod3352ZR2o
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
758feca780
commit
dd3320812c
+23
@@ -1,3 +1,4 @@
|
||||
use crate::alerts::{AlertCondition, AlertSink};
|
||||
use crate::data_value::{MetricPrimitiveKind, RegexToMetricPrimitiveMatcher};
|
||||
use crate::metric_primitive::MetricPrimitive;
|
||||
use crate::profile::{ChartType, Dashboard, Panel, Profile};
|
||||
@@ -236,6 +237,28 @@ where
|
||||
Option::<T>::deserialize(deserializer).map(Some)
|
||||
}
|
||||
|
||||
/// Request body for `POST /api/settings/alerts` (ticket 017): creates a new
|
||||
/// alert rule (see `crate::alerts::Settings::create_alert_rule`). `AlertRule`
|
||||
/// itself is returned directly as the response body (it already derives
|
||||
/// `Serialize`), so there's no separate response DTO here.
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct CreateAlertRuleRequest {
|
||||
pub name: String,
|
||||
pub enabled: bool,
|
||||
pub condition: AlertCondition,
|
||||
pub sink: AlertSink,
|
||||
}
|
||||
|
||||
/// Request body for `PUT /api/settings/alerts/:id`: replaces every field
|
||||
/// except `id` (taken from the URL, see `Settings::update_alert_rule`).
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct UpdateAlertRuleRequest {
|
||||
pub name: String,
|
||||
pub enabled: bool,
|
||||
pub condition: AlertCondition,
|
||||
pub sink: AlertSink,
|
||||
}
|
||||
|
||||
/// Summary of one profile for `GET /api/settings/profiles` (ticket 011):
|
||||
/// just the name and declaration/dashboard counts the Presets panel needs to
|
||||
/// render a list, rather than the full param/metric declaration bodies.
|
||||
|
||||
Reference in New Issue
Block a user