nginx 本身不提供静态资源访问统计接口,但可通过四步实现:1. 独立 location 捕获静态请求并写入专用日志;2. 定义精简 log_format;3. 实时清洗 uri 归一化;4. 用 flask/express 暴露内存聚合的 http 统计接口。

Nginx 本身不直接提供“静态资源访问统计接口”这种开箱即用的 REST API,但可以通过组合配置 + 轻量级外部处理,实现准实时、可查询、带维度的静态资源访问统计能力。核心不是靠单个指令,而是分层设计:日志分离 → 格式精简 → 实时清洗 → 内存聚合 → 接口暴露。
以下四步是生产环境验证可行的落地路径:
1. 独立日志捕获静态请求
避免和动态接口日志混杂,用 location 精确匹配静态后缀,并写入专用日志文件:
location ~* \.(js|css|png|jpg|gif|woff2|ttf|svg|ico|eot|pdf)$ {
access_log /var/log/nginx/static_access.log static_log;
expires 1y;
add_header Cache-Control "public, immutable";
log_not_found off; # 过滤 404 干扰
}
注意:该 location 必须放在 proxy_pass 或通用 / 规则之前;static_log 是你自定义的日志格式(见下一步)。
2. 定义轻量但关键的日志格式
在 http{} 块中声明只保留必要字段,便于后续高速解析:
log_format static_log
'$time_iso8601|$remote_addr|$request_uri|$status|$body_bytes_sent|$http_referer|$request_time';
关键点:
- 用
$request_uri(原始路径)而非$uri,保留查询参数用于灰度识别(如?v=2.3.0) - 不记录
$http_user_agent或$http_x_forwarded_for,除非明确需要 UA 分析或 CDN 回源溯源 -
$request_time可辅助发现慢资源(如某张图片平均耗时 >1s)
3. 实时清洗 URI,归一化资源标识
原始日志中的 /static/v3.2.1/app.min.js?v=abc123 和 /static/app.min.js 应视为同一资源。可用 Python 脚本持续 tail 日志并标准化:
- 去掉
?后全部参数(或仅保留?v=开头的版本标记) - 将
/static/xxx统一转为/static/xxx(大小写归一、多余斜杠清理) - 输出结构化行:
clean_path|status|ip|timestamp
示例清洗后数据:
/static/app.js|200|192.168.1.101|2026-06-29T11:45:22+00:00 /static/logo.png|200|10.0.2.5|2026-06-29T11:45:23+00:00
4. 暴露 HTTP 统计接口(无需重架构)
用 Flask 或 Express 每 5 秒滚动聚合内存数据,提供简单 JSON 接口:
-
GET /api/static/stats?last=300→ 返回最近 5 分钟各资源 PV、UV(IP 去重)、错误率 -
GET /api/static/top?limit=10→ 返回访问量 Top 10 资源路径 -
GET /api/static/referer→ 返回主要引用来源域名(从$http_referer提取主域)
示例响应:
{
"/static/app.js": { "pv": 1247, "uv": 312, "error_rate": 0.002 },
"/static/theme.css": { "pv": 983, "uv": 287, "error_rate": 0.0 }
}
不需要引入 Kafka 或 ELK,中小规模(日均静态请求
不复杂但容易忽略:真正让统计“有用”的,不是日志量多,而是从 Nginx 配置第一行就开始做路径分离和字段瘦身——后面所有分析效率,都取决于这一步是否干净。











