如何在Grafana+Prometheus中按自然周统计CPU使用率并生成柱状图?
实现基于Prometheus的周维度CPU使用率统计Grafana面板
完全可以实现这个需求,核心是通过PromQL的时间范围函数与聚合逻辑,将最近30天的时间拆分为指定的四个周期,分别计算每个周期的CPU使用率,最终在Grafana中用柱状图展示。
一、基础CPU使用率计算
首先基于container_cpu_usage_seconds_total(计数器类型指标)计算CPU使用率百分比,用irate获取每秒使用率并平滑波动,示例PromQL:
100 * avg by (instance) (irate(container_cpu_usage_seconds_total[5m]))
irate[5m]:取最近5分钟的速率,可根据业务波动调整为1m/10m;avg by (instance):按实例维度聚合,若需全局聚合可去掉该分句;- 乘以100将结果转为百分比格式。
二、拆分四个周期的PromQL
针对四个目标周期,分别编写带周期标签的查询,方便Grafana识别系列:
1. 第1周(最近30天内最早的完整周一至周日)
label_replace( avg_over_time( (100 * avg by (instance) (irate(container_cpu_usage_seconds_total[5m]))) [7d offset 21d] ), "period", "第1周(周一至周日)", "", "" )
[7d offset 21d]:从当前时间往回推21天,取连续7天的完整周数据;avg_over_time:计算该周期内的平均CPU使用率;label_replace:给系列添加period标签,用于图表图例显示。
2. 第2周(次早的完整周一至周日)
label_replace( avg_over_time( (100 * avg by (instance) (irate(container_cpu_usage_seconds_total[5m]))) [7d offset 14d] ), "period", "第2周(周一至周日)", "", "" )
- 仅调整
offset为14d,对应往回推14天的7天周期。
3. 第3周(上一个完整周一至周日)
label_replace( avg_over_time( (100 * avg by (instance) (irate(container_cpu_usage_seconds_total[5m]))) [7d offset 7d] ), "period", "第3周(周一至周日)", "", "" )
offset为7d,对应上周的完整7天周期。
4. 第4周(最近的周一至当前时间)
label_replace( avg_over_time( (100 * avg by (instance) (irate(container_cpu_usage_seconds_total[5m]))) [1d * day_of_week(now()) offset (1 - day_of_week(now()))d] ), "period", "第4周(周一至今)", "", "" )
day_of_week(now()):返回当前是周几(1=周一,7=周日);[1d * day_of_week(now())]:取从周一到今天的天数范围;offset (1 - day_of_week(now()))d:将时间起点偏移到最近的周一。
三、Grafana面板配置
- 面板类型:选择「柱状图(Bar chart)」;
- 查询配置:添加上述4个PromQL查询,每个查询的Legend设置为
{{period}},确保图例显示周期名称; - 时间范围:设置为「最近30天」,保证四个周期均在查询范围内;
- 聚合调整:若需合并多实例数据,可在Grafana面板的「Transform」中选择「Reduce」,聚合方式选「Average」或「Total」。
四、注意事项
- Prometheus数据保留:确保Prometheus的retention时间≥30天,否则无法查询到最早的第1周数据;
- 标签过滤:若为Kubernetes环境,建议给
container_cpu_usage_seconds_total添加namespace、pod等标签过滤,避免查询无关容器; - 平滑参数:
irate的时间范围可根据业务场景调整,波动大的场景用更小的窗口(如1m),需平滑趋势则用更大窗口(如10m)。
内容的提问来源于stack exchange,提问作者54vault
相关产品推荐
相关产品推荐

