如何用Kusto查询筛选flag持续为FALSE超30分钟的NodeId?
筛选flag持续为FALSE超过半小时的NodeId
当然可以用Kusto查询实现这个需求,核心思路是识别每个NodeId对应的连续FALSE状态时间段,再筛选出持续时长超过30分钟的节点。以下是具体的查询方案:
基础实现(适用于已结束的FALSE时间段)
let YourTableName = "your_table_name"; // 替换为实际表名 YourTableName | order by NodeId, timestamp asc | extend prev_flag = prev(flag), prev_timestamp = prev(timestamp) | extend is_new_segment = (flag != prev_flag) or isempty(prev_flag) | partition by NodeId ( extend segment_id = row_cumsum(toint(is_new_segment)) | summarize start_time = min(timestamp), end_time = max(timestamp), flag_value = take_any(flag) by segment_id | where flag_value == false | extend duration = end_time - start_time | where duration > 30m ) | distinct NodeId
代码说明:
- 先按
NodeId和timestamp排序,保证每个节点的记录按时间顺序排列 - 使用
prev()函数获取上一条记录的flag和时间戳,判断是否进入新的连续状态段 - 按
NodeId分区,用row_cumsum()为每个连续状态段生成唯一ID - 对每个状态段聚合,计算段的起始/结束时间和对应的flag值
- 筛选出flag为FALSE且持续时长超过30分钟的段,最后去重得到目标NodeId
进阶实现(包含当前仍处于FALSE状态的节点)
如果需要涵盖那些当前flag仍为FALSE、还未出现后续TRUE记录的节点,可以调整结束时间为当前时间:
let YourTableName = "your_table_name"; // 替换为实际表名 let latest_global_time = toscalar(YourTableName | summarize max(timestamp)); YourTableName | order by NodeId, timestamp asc | extend prev_flag = prev(flag), prev_timestamp = prev(timestamp) | extend is_new_segment = (flag != prev_flag) or isempty(prev_flag) | partition by NodeId ( extend segment_id = row_cumsum(toint(is_new_segment)) | summarize start_time = min(timestamp), end_time = max(timestamp), flag_value = take_any(flag) by segment_id | where flag_value == false // 若当前段的结束时间是全局最新时间,说明状态仍在持续,用当前时间计算时长 | extend end_time = iif(end_time == latest_global_time, now(), end_time) | extend duration = end_time - start_time | where duration > 30m ) | distinct NodeId
代码说明:
- 先获取表中最新的记录时间
latest_global_time - 对每个FALSE状态段,判断其结束时间是否为全局最新时间,若是则用当前时间
now()作为结束时间,确保计算出的是从状态开始到现在的持续时长
内容的提问来源于stack exchange,提问作者Tanya Linder
相关产品推荐
相关产品推荐

