基于Azure App Insights的动态异常计数告警KQL实现问询
用KQL实现Azure App Insights动态异常告警(基于历史基线)
完全可以只用KQL实现这种基于历史常规值的动态告警,不用依赖其他工具。下面给两种实用的实现方案,你可以根据业务需求调整:
方案1:基于历史均值+标准差的动态阈值
这种方法适合业务量有波动但无明显季节性的场景,通过计算过往评估周期的均值和标准差,设置动态触发条件:
exceptions | where customDimensions.EventName == 'FunctionCompleted' // 按告警评估的时间粒度划分窗口(比如告警每5分钟跑一次,就设为5m) | summarize Count = count() by bin(TimeGenerated, 5m), operation_Name // 按函数名分组,收集所有历史周期的计数数据 | partition by operation_Name ( order by TimeGenerated asc | extend HistoryCounts = dynamic([]) | extend HistoryCounts = array_concat(HistoryCounts, pack_array(Count)) // 只保留当前周期的数据,同时带上所有历史计数 | take -1 ) // 计算排除当前周期的历史均值和标准差(避免当前值影响基线) | extend HistoryMean = array_avg(remove(HistoryCounts, array_length(HistoryCounts)-1)), HistoryStdDev = array_stddev(remove(HistoryCounts, array_length(HistoryCounts)-1)) // 触发条件:当前计数超过均值+2倍标准差(可根据实际调整倍数) | where Count > HistoryMean + 2*HistoryStdDev | project 函数名=operation_Name, 当前异常数=Count, 历史均值=HistoryMean, 动态阈值=HistoryMean + 2*HistoryStdDev
关键说明:
- 时间窗口
bin(TimeGenerated, 5m)要和你的告警评估频率完全一致,比如告警每10分钟评估一次就改成10m。 - 历史数据范围由查询的时间范围控制,比如设置查询过去1小时,就能拿到12个5分钟周期的历史数据,保证基线计算的准确性。
- 如果想更严格,也可以用历史95分位数替代均值+标准差,把最后几行换成:
| extend HistoryP95 = array_percentile(remove(HistoryCounts, array_length(HistoryCounts)-1), 95) | where Count > HistoryP95 | project 函数名=operation_Name, 当前异常数=Count, 历史95分位数=HistoryP95
方案2:时序分解异常检测
如果你的业务量有明显的日/周季节性波动,用series_decompose_anomalies函数更合适,它会自动识别趋势、季节性,精准标记异常:
exceptions | where customDimensions.EventName == 'FunctionCompleted' | summarize Count = count() by bin(TimeGenerated, 5m), operation_Name | order by TimeGenerated asc | partition by operation_Name ( // 生成时序数组,历史范围设为过去1天(覆盖一个完整的业务周期) | make-series CountSeries=avg(Count) on TimeGenerated from ago(1d) to now() step 5m // 分解时序并检测异常,第二个参数1.5是敏感度(值越高越严格) | extend (anomalies, score, baseline) = series_decompose_anomalies(CountSeries, 1.5) // 展开时序数据,只取当前周期的结果 | mv-expand TimeGenerated to typeof(datetime), CountSeries to typeof(long), anomalies to typeof(double) | take -1 // 只保留被标记为异常的记录 | where anomalies > 0 ) | project 函数名=operation_Name, 当前异常数=CountSeries, 基线值=baseline, 异常得分=score
注意事项:
- 历史范围建议覆盖至少一个完整的业务周期(比如日活业务设为1天,周活设为1周),这样函数能准确识别季节性。
- 敏感度参数(示例中的1.5)可调整:值越大,只有偏离基线越远的情况才会被标记为异常,减少误报;值越小,对波动越敏感。
- 对于新上线的函数,因为历史数据不足,可能会出现基线不准的情况,你可以加个判断,比如只有历史周期数大于N才触发告警。
内容的提问来源于stack exchange,提问作者PGM
相关产品推荐
相关产品推荐

