如何在Grafana中展示按日历日统计的Nginx 400请求柱状图
问题:如何展示从00:00开始的日历日柱状图?
我通过Promtail采集Nginx的access.log并存储到Loki中,现需在Grafana仪表板创建面板,展示每个日历日的400(Bad Request)响应数量。
我已能通过pattern解析日志行,用标签过滤表达式筛选数据,也可应用日志范围聚合,但无法将仪表板配置为按日历日展示柱状图。
当前使用的Loki查询语句:
sum(count_over_time({job="nginx", filename="/var/log/nginx/access.log"} | pattern `<ip> - - <_> "<method> <uri> <_>" <status> <size> <_> "<agent>" <_>` | status = `400` [$__interval]))
我已将查询选项的Min interval改为1d以获取24小时柱状图,但面板时间标签不从00:00开始,柱状图与时间标签不匹配,且无400响应的日期未显示。尝试用now/d替代now后结果无变化;面板时间标签显示UTC而非本地时区(UTC+2),但时间选择器已正确设置本地时区,且已知Grafana需UTC时间戳、Loki存储的是UTC时间戳。
解决方案
1. 用日志时间分组对齐日历日
替换原查询逻辑,通过strftime将日志时间转换为日历日标签,结合固定1d窗口的count_over_time实现精准分组:
sum by (day) ( count_over_time( {job="nginx", filename="/var/log/nginx/access.log"} | pattern `<ip> - - <_> "<method> <uri> <_>" <status> <size> <_> "<agent>" <_>` | status = `400` | day = strftime("%Y-%m-%d", time()) [1d] ) )
strftime("%Y-%m-%d", time())将每条日志的UTC时间转换为YYYY-MM-DD格式的日期标签,确保按自然日聚合。count_over_time窗口固定为1d,保证每个统计周期严格对应一个完整日历日。
2. 调整面板时间对齐与显示设置
- 时间范围配置:在面板时间选择器中,选择相对时间范围(如
Last 7 days),或手动设置起始/结束时间为完整日历日(例如2024-05-01 00:00:00至2024-05-08 00:00:00)。 - 面板参数调整:
- 进入面板
Options标签页,将Time zone设为Browser(跟随本地时区)或直接指定UTC+2。 - 在
Axes设置中,将X轴Mode设为Time,开启Align to time选项,强制时间标签对齐到00:00。
- 进入面板
- 查询选项锁定:在查询编辑器
Options中,保持Min interval为1d,关闭Auto interval,避免Grafana自动调整窗口大小破坏日粒度统计。
3. 显示无数据的空日期
Loki默认不返回无数据的日期,需通过Grafana转换功能补全:
- 进入面板
Transform标签页,点击Add transformation,选择Add field from calculation。 - 计算类型选
Binary operation,字段选择计数字段,操作设为Replace nulls with,值填0。 - 依次添加
Time series to rows和Fill missing转换:Fill missing设置中,Time range选Full panel,Frequency设为1d,确保所有日历日都被填充,空值替换为0。
4. 修正时区显示问题
- 在Grafana全局设置(
Configuration > Preferences)中,将Time zone设为Browser或对应本地时区(如(UTC+02:00) Europe/Paris)。 - 确保面板
Time zone设置继承全局配置,或手动指定对应时区,让时间标签以本地时区的00:00显示。
内容的提问来源于stack exchange,提问作者dur
相关产品推荐
相关产品推荐

