nginx通过自定义access_log格式记录服务维度请求数据,结合logrotate按天切分日志,并用shell/python等工具聚合归档至sqlite或对象存储;实时统计可选openresty+redis补充。

通过 Nginx 代理实现后端服务流量的统计归档,核心在于利用 Nginx 的日志模块记录详细请求数据,并结合外部工具或自定义逻辑完成聚合、存储与归档。Nginx 本身不内置数据库或长期统计分析能力,但其高精度、低开销的日志输出是理想的原始数据源。
配置自定义 access_log 格式,捕获关键维度
默认日志格式信息有限,需扩展字段以支持后续按服务、接口、状态码、响应时间等维度归档分析:
log_format stats '$time_iso8601|$remote_addr|$host|$request_uri|$status|$body_bytes_sent|$request_time|$upstream_http_x_service_name|$upstream_addr|$upstream_response_time'; access_log /var/log/nginx/stats.log stats;
-
$upstream_http_x_service_name:要求后端在响应头中返回服务标识(如
X-Service-Name: user-api),Nginx 可透传并记录 - $upstream_addr 和 $upstream_response_time:用于识别真实后端节点及链路耗时,便于故障归因
- 用竖线
|分隔字段,提升后续文本解析鲁棒性(避免空格/URL 编码干扰)
按时间切片轮转日志,便于归档管理
不加控制的日志会持续增长,影响读写性能和归档效率。推荐使用 logrotate 或 Nginx 内置的每日切分:
# 在 nginx.conf 的 http 块中添加
map $time_iso8601 $logdate {
~^(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2}) $y$m$d;
}
access_log /var/log/nginx/stats-$logdate.log stats;
</d></m></y>配合定时 reload(如每天 00:00 执行 nginx -s reload),可生成形如 stats-20240520.log 的文件,天然适配按天归档需求。
接入轻量级归档流水线(无需大数据平台)
对中小规模场景,可用 Shell + Logstash + SQLite 或直接 Python 脚本完成归档:
- 每日凌晨用
awk或csvkit提取关键指标(如各 service 的 QPS、5xx 比率、P95 延迟),生成汇总 CSV - 将 CSV 导入 SQLite 表(表结构含 date, service, status_5xx_count, p95_ms, total_req 等字段),便于长期查询
- 旧日志(如 30 天前)可压缩为
.gz并同步至对象存储(如 S3/MinIO),保留原始数据备查
补充:实时统计可选 OpenResty + Redis 方案
若需秒级监控看板(如每分钟各接口调用量),可在 Nginx 层嵌入 Lua 脚本:
-- 在 location 中
content_by_lua_block {
local service = ngx.var.upstream_http_x_service_name or "unknown"
local key = "stats:" .. os.date("%Y%m%d%H%M") .. ":" .. service
ngx.shared.dict:incr(key, 1)
}
再由外部程序定期拉取 Redis 中的计数器,写入时序数据库(如 Prometheus + Pushgateway)或归档表。此方式不替代日志归档,而是作为实时补充。











