nginx 可通过日志+命令行工具统计 pv 和 uv:pv 用 awk '{print $1}' access.log | wc -l,uv 用 awk '{print $1}' access.log | sort -u | wc -l,按天统计需提取日期并去重 ip;提升准确性可结合 $http_x_uid、$cookie_uid 或 realip 模块。

在 Nginx 中统计 UV(独立访客数)和 PV(页面浏览量),不依赖外部服务(如 Google Analytics),最直接的方式是结合 Nginx 自带日志 + 命令行工具(如 awk、sort、uniq)进行快速分析。无需部署复杂系统,一条命令就能跑出结果。
确认 Nginx 日志格式并启用必要字段
Nginx 默认 access_log 记录 IP、时间、路径、状态码等,但要准确统计 UV,需确保日志中能区分“同一用户不同请求”。真实场景中,纯靠 IP 会高估(多个用户共用公网 IP)或低估(用户换网络/IP),但作为快速估算,IP 是最常用且免配置的标识符。
检查你的 nginx.conf 中 log_format 是否包含 $remote_addr(客户端真实 IP)。推荐使用如下精简格式:
log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time';
确保站点 server 块中启用了该格式:
access_log /var/log/nginx/access.log main;
用 shell 命令快速统计 PV 和 UV(基于 IP)
进入日志所在目录(如 /var/log/nginx/),运行以下命令:
-
PV 统计(总请求数):
awk '{print $1}' access.log | wc -l -
UV 统计(去重 IP 数):
awk '{print $1}' access.log | sort -u | wc -l -
按天统计 PV/UV:
awk '{print substr($4,2,11), $1}' access.log | awk '{pv[$1]++; ip[$1,$2]++} END {for (d in pv) print d, pv[d], length(ip[d])}' | sort
说明:$1 是 IP,$4 是带方括号的时间字段(如 [01/Jan/2024:10:20:30),substr 提取日期部分;第二段 awk 分别累计每日 PV 和构建“日期+IP”组合去重,最后输出“日期 PV UV”三列。
提升 UV 准确性的实用技巧
若业务对 UV 要求稍高(例如含移动端、App 流量),可借助 Nginx 提取更稳定标识:
- 如果后端注入了 用户唯一 ID(如 uid=12345) 到 URL 或 header,可用
$args或$http_x_uid替代 $remote_addr - 启用 realip 模块 并配置 set_real_ip_from,确保反向代理(如 CDN、LB)后仍能拿到真实客户端 IP
- 对含 Cookie 的请求,可提取
$cookie_uid(需前端写入可信 UID),命令改为:awk -F'"' '{for(i=1;i
进阶:用 GoAccess 实时可视化分析
不想写 awk?GoAccess 是轻量、终端友好的日志分析工具,支持实时 PV/UV 统计和地理分布、浏览器等维度:
- 安装:
apt install goaccess(Ubuntu/Debian)或brew install goaccess(macOS) - 运行:
goaccess /var/log/nginx/access.log --log-format=COMBINED -a - 输出 HTML 报告:
goaccess /var/log/nginx/access.log --log-format=COMBINED -o report.html
它默认将 IP 作为访客标识,也支持通过 --real-ip-header 指定 X-Forwarded-For 等头字段,比纯命令行更直观,且支持过滤时间段、状态码等。
不复杂但容易忽略:日志轮转后需指定具体文件(如 access.log.1.gz),用 zcat 配合管道;高频业务建议用日志采样(如每 10 行取 1 行)再统计,避免卡顿。











