Testing a SQL alert
Preview, Run now and Test notification are three different things. Which one to use, and when.
Three buttons, three different questions.
| Button | Runs the query | Evaluates conditions | Raises a real alert | Sends a message |
|---|---|---|---|---|
| Preview run | ✅ | ✅ (shown, not recorded) | ❌ | ❌ |
| Run now | ✅ | ✅ (recorded) | ✅ if it breaches | ✅ if it breaches |
| Test notification | ❌ | ❌ | ❌ (synthetic) | ✅ always |
Preview run
The safe one. Executes the query and shows you:
- the real result set — columns, types, the first rows
- what each condition would decide against it
- which rows would fire, and at what severity
- any faults: unmapped directions, non-numeric columns, half-written bands
Nothing is recorded and nobody is paged. Use it while writing the rule, and whenever you change a threshold.
Preview works before any condition is set. Look at the result shape first, then write conditions against what you actually have rather than what you expected the query to return.
Run now
A real evaluation, out of schedule. State is recorded, alerts are raised, and notifications go out.
Use it when you have fixed something and want to know whether the rule agrees — or to close an alert immediately rather than waiting for the next scheduled run.
For a clock-aligned rule, a manual run does not shift the schedule: the next scheduled run is still on the boundary.
Test notification
Sends a synthetic message through the real routing. It proves the channel, the network path and the formatting — not the rule.
Use it after changing routing, or after rotating a webhook.
These were once one button labelled "Run now" that raised a fake alert. They are separate because the two questions are different: "does my rule work" and "does my Slack channel work" have different answers and different fixes.
Reading the evaluation history
The rule page shows every recorded evaluation: the value, the raw reading, which condition it belonged to, whether the condition was met, the resulting state and any error.
For a rule with several conditions, the history can be filtered per condition — each has its own chart, because four conditions averaged into one line is not a reading of anything.
When a rule will not fire
Work down this list:
- Is it enabled? A disabled rule is not evaluated.
- Is it inside its run window? Outside it, the query is not run at all.
- Is it silenced? Check for an active silence or maintenance window.
- Does the query return rows? A query that returns nothing when healthy
cannot distinguish healthy from broken. Return
0instead. - Is the condition on a numeric column? Text and dates are context.
- Is a band half-written?
between/outsidewith one bound matches nothing. The editor marks it red. - Is
Forlonger than the interval × the number of runs so far? AForof 30 minutes on a rule that runs hourly needs two consecutive breaching runs. - Is a guard failing? Guards suppress the measurements deliberately — the fault says which one.
Preview run answers most of these in one click.
Where this behaviour lives: backend/internal/worker/dwh_alert_worker.go, frontend/src/app/dwh/alerts/. If the code and this page disagree, the code is right — please fix the page.
Part of Data warehouse — Querying the warehouse, and alerting on what the query returns.