需解析nginx access.log实现uv/pv统计:uv按ip去重、pv按行计数,通过logstash/filebeat+es或prometheus+nginx-log-exporter采集结构化数据,在grafana中用对应查询展示。

要让 Grafana 展示 Nginx 的每日独立访客(UV)和总请求量(PV),关键不是直接从 Nginx 内置状态页取数——stub_status 只提供实时连接与请求速率,不含 IP、日期或会话维度。必须依赖访问日志(access.log)做离线/准实时聚合,并通过合适的数据链路导入 Grafana。
用日志解析 + 时间序列数据库支撑 UV/PV 统计
UV(按 IP 去重)和 PV(按行计数)本质是日志分析任务,需先完成数据准备:
- 确保 Nginx 日志格式包含必要字段:IP(
$remote_addr)、时间($time_local),推荐使用标准log_format main或自定义含$http_x_forwarded_for(如走 CDN) - 不依赖客户端 Cookie——Nginx 日志中无 cookie 字段,UV 按 IP 统计更可靠(符合“独立 IP”定义)
- 用 Logstash / Filebeat + Elasticsearch 或 Prometheus + nginx-log-exporter 实现日志采集与结构化;若用 Prometheus,需借助 nginxlog-exporter 解析日志并暴露指标如:
nginx_log_entry_count_total{host="example.com", status=~"2.."}(PV)nginx_log_unique_ip_count_daily{date="2026-09-05"}(UV,需 exporter 支持或自定义脚本预计算)
在 Grafana 中配置对应面板
数据源就绪后,在 Grafana 创建两个核心面板:
-
总请求量(PV):用时间序列求和。例如 Prometheus 数据源下,写查询:
sum(rate(nginx_log_entry_count_total[1d])) by (host)
设置 X 轴为时间,Y 轴为值,图例显示 host;可叠加多站点对比 -
每日独立访客(UV):需指标已按天聚合。若 exporter 不原生支持,建议用 Logstash + ES 方案,在 Kibana 做好 daily-unique-IP 聚合后,用 Grafana 的 Elasticsearch 数据源查:
SELECT COUNT(DISTINCT(remote_addr)) FROM "nginx-log-*" WHERE @timestamp >= NOW-1d/d
或用 Prometheus 预计算每日去重结果并打标(如nginx_uv_daily{date="2026-09-05"}),再用last_over_time(nginx_uv_daily[7d])展示最近 7 天柱状图
避免常见误区
几个容易卡住的点:
- 别试图用
stub_status的Active connections或Accepted conn推算 UV/PV——它们是瞬时或累计连接数,无 IP 和时间粒度 - 不推荐 Grafana 直读原始日志文件(如用 Loki)做 UV 计算:Loki 不支持
COUNT(DISTINCT)类操作,UV 必须靠预处理或外部聚合 - 注意时区:Nginx 日志默认用服务器本地时间,Prometheus 抓取、Grafana 展示需统一设为 UTC 或东八区,否则“每日”统计错位
- CDN 场景下,
$remote_addr是 CDN 节点 IP,应改用$http_x_forwarded_for并取最左非内网 IP(需 Logstash / Lua 过滤)
真正落地时,小流量可用 Python 脚本每日解析 .gz 日志生成 CSV,再由 Grafana CSV 插件加载;中高流量务必走 ELK 或 Prometheus+exporter 链路。核心逻辑始终是:日志 → 结构化 → 按 date+ip 聚合 → 暴露为指标 → Grafana 可视化。











