基于InfluxDB的Grafana查询:统计连续100%丢包次数至值变更
统计连续100%丢包次数的InfluxDB查询方案
需求回顾
从当前时间回溯,统计第一个非100%丢包记录之前连续出现的100%丢包次数;若所有记录均为100%丢包,则统计全部次数。
方案一:InfluxDB 1.x(InfluxQL)
假设你的测量表名为packet_loss,丢包率字段为loss_percent,使用以下嵌套查询实现:
SELECT COALESCE( -- 统计第一个非100%丢包之后的连续100%次数 (SELECT COUNT(*) AS count FROM ( SELECT time, CASE WHEN loss_percent = 100 THEN 1 ELSE 0 END AS is_full_loss FROM packet_loss WHERE time >= now() - 1d -- 覆盖每日48次检测的时间范围 ORDER BY time DESC ) WHERE time > ( -- 获取最近一次非100%丢包的时间点 SELECT time FROM ( SELECT time, CASE WHEN loss_percent = 100 THEN 1 ELSE 0 END AS is_full_loss FROM packet_loss WHERE time >= now() - 1d ORDER BY time DESC ) WHERE is_full_loss = 0 LIMIT 1 )), -- 全为100%丢包时,统计总数 (SELECT COUNT(*) FROM packet_loss WHERE time >= now() - 1d AND loss_percent = 100) ) AS continuous_full_loss_count
逻辑说明
- 内层子查询:倒序获取最近1天的丢包数据,标记每条数据是否为100%丢包
- 中间子查询定位最近一次非100%丢包的时间点
- 外层统计该时间点之后(更靠近当前时间)的100%丢包数量
COALESCE处理全100%丢包的边界情况
方案二:InfluxDB 2.x(Flux)
Flux语法更简洁,适合2.x版本:
from(bucket: "你的存储桶名称") |> range(start: -1d) |> filter(fn: (r) => r._measurement == "packet_loss" and r._field == "loss_percent") |> sort(columns: ["_time"], desc: true) |> map(fn: (r) => ({ r with is_full_loss: if r._value == 100 then 1 else 0 })) |> cumulativeSum(fn: (r) => if r.is_full_loss == 0 then 0 else r.is_full_loss) |> filter(fn: (r) => r.is_full_loss == 1) |> count(column: "_value") |> fill(value: 0)
逻辑说明
- 筛选最近1天的丢包数据并倒序排列
- 标记每条数据是否为100%丢包
- 用
cumulativeSum实现连续计数:遇到非100%丢包时重置累加值为0,仅保留连续100%的分组 - 筛选连续100%的记录并统计数量,无匹配时填充0
Grafana配置建议
- 选择单数值面板展示统计结果
- 根据实际检测频率调整时间范围(比如若检测周期超过1天,将
-1d改为对应时长) - 若使用InfluxDB 2.x,需在Grafana数据源中启用Flux查询模式
内容的提问来源于stack exchange,提问作者Ivyand
相关产品推荐
相关产品推荐

