KQL · failures
Failure rate by operation as a timechart
Chart the failed-request percentage over time for the five operations with the most failures, in 15-minute bins, sampling-adjusted.
requests failures
let lookback = 24h;
let topOperations = requests
| where timestamp > ago(lookback)
| summarize failed = sumif(itemCount, tostring(success) =~ "false") by operation_Name
| top 5 by failed desc
| project operation_Name;
requests
| where timestamp > ago(lookback)
| where operation_Name in (topOperations)
| summarize
total = sum(itemCount),
failed = sumif(itemCount, tostring(success) =~ "false")
by bin(timestamp, 15m), operation_Name
| extend failure_pct = round(100.0 * failed / total, 2)
| project timestamp, operation_Name, failure_pct
| order by timestamp asc
| render timechart Returns: One line per operation for the five operations with the most failed requests, showing the percentage of its requests that failed in each 15-minute interval.
Pitfalls
- A rate needs volume behind it. One failure out of two requests at 03:00 is 50% and dominates the chart; read the rate next to the counts, or add | where total >= 20 before the extend step.
- success is set by the SDK and can be changed by your own code. By default a web request counts as successful when the response code is below 400 or equal to 401, so 404s are failures unless you change that.
- The five operations are picked by failure count over the whole window, so a route that failed badly for ten minutes may not make the cut. Raise the top count or filter to the route you care about.
- The classic schema stores success as a string; tostring(success) =~ "false" works whether the column holds text or a boolean.
How it works
A failure count goes up when traffic goes up. A failure rate goes up when something breaks. This query charts the rate for the operations that fail most, so a deployment that broke one route shows as a step on one line rather than noise in a total.
Line by line
let lookback = 24h;sets the window for both parts of the query.let topOperations = ...;is a small query of its own: it sums failed requests per operation over the window, keeps the five with the most failures, and keeps only the name column. Charting every operation would draw dozens of lines.where operation_Name in (topOperations)uses that list as a filter. Theinoperator accepts a tabular expression and reads its first column.summarize ... by bin(timestamp, 15m), operation_Namebuilds one row per operation per 15 minutes, with the sampling-adjusted total (sum(itemCount)) and the failed count (sumifon the failed rows). The bin comes first because a timechart takes its x-axis from the first column.failure_pctis the failed share as a percentage, rounded to two decimals.projectkeeps the three columns the chart needs, andrender timechartdraws one line peroperation_Name.
Turning it into an alert
Alerts don’t need the chart. Keep the summarize with a single bin over the alert window, compute failure_pct, and add | where failure_pct > 5 and total >= 50. The total floor stops a quiet night from paging someone over two failures. The alerts guide covers the rest of the rule: frequency, window and action groups. For the failures themselves, break the worst line down with failed requests by result code.
If 404s from bots or old links dominate the chart, that’s the default success rule at work; the initializers and processors guide shows how to mark 404s on chosen routes as successful.
Variations
- All traffic as one line: drop
topOperationsandoperation_Namefrom thebyclause. - One service: add
| where cloud_RoleName == "orders-api"in both parts. - Workspace tables: use
AppRequests,TimeGenerated,Success == false,ItemCountandOperationName.