Files
ottyl/tickets/018-alert-trigger-evaluation.md
T
2026-09-05 16:17:18 +01:00

2.4 KiB

018 — Alert trigger evaluation

Summary

Evaluate AlertRule conditions (017) against the live log stream and fire a delivery (019) when one matches, without re-scanning already-ingested logs — hook into the same ingest path engine.rs already uses to update timelines/metrics/dashboards on each new log.

Scope

Condition types to support, all built on primitives ottyl already has (the FilterBar query language, 005, and metric declarations, 002) rather than a new syntax:

  • Immediate — fire once per log line matching a FilterBar query, as soon as it's ingested.
  • Threshold — a declared metric's value, or a FilterBar query's match count, crosses a fixed level within a rolling time window.
  • New value — a specified log field takes on a value that hasn't appeared before (within the alert's lifetime, or a bounded lookback — decide and document which).
  • Ratio — the match counts of two FilterBar queries, compared over the same rolling window, cross a configured ratio.

Each condition stores its own window/threshold parameters (already sketched as an opaque value on AlertRule in 017 — this ticket defines and parses that shape).

  • Evaluation runs inline on ingest (or on bucket update, whichever the engine already does per-log) — no polling loop and no periodic full re-scan.
  • Rolling-window state (counts, last-seen values) is kept in memory per rule; it does not need to survive a restart.
  • On a match, hand off to the configured sink (019) — this ticket owns deciding to fire, not delivering.
  • Respect AlertRule.enabled: disabled rules are skipped entirely.

Acceptance criteria

  • Each of the four condition types fires exactly when its condition is met, and not otherwise (covered by unit tests per type, feeding synthetic logs through the same ingest path).
  • Evaluation cost is proportional to new logs ingested, not to total log volume — no scan of the full log history per evaluation.
  • A disabled rule never fires.

Depends on

Depended on by