优化Azure Monitor告警KQL查询:检测服务从运行转停止
简化KQL查询并配置Azure Monitor告警规则
简化后的KQL查询
针对你的需求,使用Kusto窗口函数替代多次Join操作,大幅降低查询复杂度,同时精准检测服务状态变更:
写法一(基于row_number分组聚合)
workspace(<workspaceId>).TCServiceStatus_CL // 过滤最近10分钟日志,覆盖每3分钟一次的两条记录 | where TimeGenerated > ago(10m) // 可选:指定目标计算机,缩小查询范围 // | where ComputerName == "Computer005" // 按计算机、服务分组,时间倒序排列 | order by ComputerName, ServiceName, TimeGenerated desc // 为每个服务+计算机组分配行号,最新记录为1,上一条为2 | partition by ComputerName, ServiceName (row_number() over (order by TimeGenerated desc) as RowNum) // 仅保留最近两条状态记录 | where RowNum <= 2 // 聚合出最新状态与上一次状态 | summarize LatestStatus = max_if(ServiceStatus, RowNum == 1), PrevStatus = max_if(ServiceStatus, RowNum == 2) by ComputerName, ServiceName // 筛选从Running变为Stopped的状态变更 | where LatestStatus == "Stopped" and PrevStatus == "Running"
写法二(基于prev()窗口函数)
更简洁的实现方式,直接获取上一条状态记录:
workspace(<workspaceId>).TCServiceStatus_CL | where TimeGenerated > ago(10m) // 可选:指定目标计算机 // | where ComputerName == "Computer005" // 按计算机、服务分组,时间正序排列 | order by ComputerName, ServiceName, TimeGenerated asc // 分组后获取上一条状态,同时标记最新记录 | partition by ComputerName, ServiceName ( prev(ServiceStatus) as PrevStatus, ServiceStatus as LatestStatus, row_number() over (order by TimeGenerated desc) as RowNum ) // 仅保留最新的状态对比记录 | where RowNum == 1 // 筛选目标状态变更 | where LatestStatus == "Stopped" and PrevStatus == "Running" | project ServiceName, ComputerName, LatestStatus, PrevStatus
关键优化点
- 移除原查询中多次
join操作,改用partition by+窗口函数,Kusto可高效优化这类查询,满足告警规则的评估频率要求 - 时间范围限定为10分钟,刚好覆盖每3分钟一次日志的最近两条记录,避免不必要的数据扫描
- 按
ComputerName和ServiceName分组,确保仅对比同一服务在同一机器上的状态变化
告警规则配置步骤
- 登录Azure门户,进入Monitor > Alerts > Create > Alert rule
- 选择你的Log Analytics Workspace作为告警关联资源
- 在Condition环节:
- 信号类型选择Custom log search
- 粘贴上述简化后的KQL查询
- 配置评估参数:
- 评估频率:设置为1分钟(查询已优化,支持该频率)
- 窗口大小:设置为10分钟(与查询中的
ago(10m)匹配) - 阈值规则:当结果数大于0时触发告警
- 配置Action groups,添加所需的通知方式(邮件、短信、Webhook等)
- 填写告警规则名称、描述、严重级别等信息,完成规则创建
内容的提问来源于stack exchange,提问作者TempoClick
相关产品推荐
相关产品推荐

