Hello Mark Pearson,
Your query returns one static value (1440), so there’s nothing to aggregate per time slice hence it is not firing for the selected Measure = UptimeMinutes, Aggregation type = Total, and Granularity = 15 minutes.
Azure Monitor expects time-series data for aggregation, but your query returns a single static row (no timestamp column for grouping). So the alert engine never evaluates the condition properly.
How to Fix
Change to following
Measurement : Table rows
Aggregation Type: Empty
Aggregation granularity: You can keep default to 15 minutes.
Operator: Greater than
Threshold: 0
Split by dimensions: Leave blank (or remove Computer split since query already filters).
The reason behind the logic is
The query already filters for UptimeMinutes > 180.
If any row exists, the alert fires.
No dependency on time-series aggregation or granularity.
Updated KQL query, it's the same query you have used, the only change is update in threshold variable.
let threshold = 180; // 3 hours in minutes
Heartbeat
| where Computer == "<your-server-name>"
| summarize FirstSeen = min(TimeGenerated) by Computer
| extend UptimeMinutes = datetime_diff('minute', now(), FirstSeen)
| where UptimeMinutes > threshold
Try and let us know if any queries?
[Edited with screenshots]
Thanks.