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
27 lines
683 B
TOML
27 lines
683 B
TOML
[package]
|
|
name = "ottyl"
|
|
version = "0.1.0"
|
|
edition = "2024"
|
|
|
|
[dependencies]
|
|
axum = { version = "0.8.9", features = ["json"] }
|
|
tokio = { version = "1.53.1", features = ["full"] }
|
|
tower-http = { version = "0.6", features = ["fs", "cors"] }
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
clap = { version = "4", features = ["derive"] }
|
|
regex = "1"
|
|
pest = "2"
|
|
pest_derive = "2"
|
|
chrono = "0.4"
|
|
humantime = "2"
|
|
directories = "6.0.0"
|
|
fs-embed = "0.2.4"
|
|
include_dir = "0.7.4"
|
|
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls"] }
|
|
|
|
[dev-dependencies]
|
|
tempfile = "3.27.0"
|
|
tower = { version = "0.5", features = ["util"] }
|
|
http-body-util = "0.1"
|