如何按query_name生成直方图平均时长柱状仪表及解决Grafana问题
解决PromQL计算查询平均时长的NaN与排序问题
问题1:消除NaN值并计算时间范围内的平均时长
你当前用rate()计算的是每秒的耗时总和与请求计数速率,得到的是每秒平均耗时,但你需要的是整个所选时间范围内的平均时长,应该用sum_over_time()统计时间范围内的总耗时和总请求数,而非rate()。
出现NaN的核心原因:当某个query_name在时间范围内无请求时,sum_over_time(db_query_duration_ms_count{})返回0,导致0/0出现NaN;或部分query_name的sum与count时间序列不匹配。
修正后的查询
方案1:直接过滤无请求的query(推荐)
# 计算时间范围内每个query的平均耗时 sum_over_time(db_query_duration_ms_sum{}[$__range]) by (query_name) / sum_over_time(db_query_duration_ms_count{}[$__range]) by (query_name) # 过滤掉请求数为0的query,避免NaN unless sum_over_time(db_query_duration_ms_count{}[$__range]) by (query_name) == 0
方案2:将NaN替换为0
如果需要保留无请求的query并显示0值,可通过给空计数补1实现:
sum_over_time(db_query_duration_ms_sum{}[$__range]) by (query_name) / (sum_over_time(db_query_duration_ms_count{}[$__range]) by (query_name) or vector(1))
问题2:实现柱状图降序排序
sort_desc()无效通常是因为结果中存在NaN,或Grafana面板设置优先级高于PromQL排序,按以下步骤解决:
步骤1:在PromQL中过滤NaN后排序
确保输入排序的序列无NaN,用sort_desc()包裹修正后的查询:
sort_desc( sum_over_time(db_query_duration_ms_sum{}[$__range]) by (query_name) / (sum_over_time(db_query_duration_ms_count{}[$__range]) by (query_name) or vector(1)) )
步骤2:Grafana面板设置辅助排序
如果PromQL排序仍不生效,进入柱状图的「选项」面板:
- 找到「排序」选项,选择「降序」
- 排序依据选择「值」
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

