最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
怎样配置 log_format 捕获 $body_bytes_sent 变量精准统计网站静态资源的外发流量带宽
时间:2026-06-17 09:09:46 编辑:袖梨 来源:一聚教程网
精准统计网站静态资源外发流量需在http块定义含$body_bytes_sent的log_format,各server块独立启用并指定唯一access_log路径,$body_bytes_sent准确记录压缩后响应体字节数,验证时检查日志第6字段是否为非零值。
要精准统计网站静态资源的外发流量带宽,核心是让 log_format 稳定捕获 $body_bytes_sent,并确保它能真实反映 JS、CSS、图片等静态内容发出的字节数(不含响应头)。这个变量本身不需额外模块,但必须显式写入日志格式,且配置位置和上下文要正确。
必须在 http 块中定义含 $body_bytes_sent 的自定义格式
不能依赖默认 combined 格式——它不含 $body_bytes_sent。需在 http{...} 区块内明确定义:
log_format static_flow '$host $remote_addr [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';
说明:
-
$host比$server_name更适合多租户场景,它取自请求头 Host 字段,能区分同一 IP 下不同域名; -
$body_bytes_sent是纯响应体字节数,对 200/304/206 均有效,gzip 压缩后的体积已自动计入; - 避免把
$body_bytes_sent放在日志末尾以外的位置,否则后续用awk提取时列数易错; - 若站点启用了 CDN 回源,该字段仍准确记录 Nginx 实际发出的字节数,可用于比对缓存命中率。
每个 server 块必须独立启用该格式并指定日志路径
不能多个站点共用一个 access_log 文件——否则无法按站分离统计。例如:
server {
server_name example.com;
root /var/www/example;
access_log /var/log/nginx/example.com-static.log static_flow;
}
关键点:
- 每个
server必须有唯一access_log路径,推荐按域名命名; - 静态资源(如
.js、.png)由 Nginx 直接返回时,天然计入$body_bytes_sent,无需额外location ~* .(js|css)配置; - 若使用了
try_files或alias,只要最终响应来自本地文件系统,该变量就有效。
验证是否生效与常见失效原因
重载配置后,立即访问一个静态资源(如 /style.css),检查日志是否出现非零数字:
example.com 192.168.1.100 [16/Jun/2026:19:30:22 +0800] "GET /style.css HTTP/1.1" 200 12480 "https://example.com/" "Mozilla/5.0..."
若第 6 字段(即 $body_bytes_sent)为 - 或 0,常见原因有:
- Nginx 版本低于 1.3.12(该变量自此时起稳定支持);
- 请求触发了 304(Not Modified)或 204(No Content)响应,此时响应体为空,值为 0 —— 这属于正常行为,不是配置错误;
- 日志路径所在目录不可写,或磁盘满导致日志未落盘,看似没输出;
- 配置修改后未执行
nginx -s reload,旧进程仍在运行。
轻量实时统计方法(不依赖外部系统)
日志就绪后,可用以下命令秒级查看各站点当前静态流量趋势:
tail -f /var/log/nginx/*.log | awk '$6 == 200 && $7 ~ /.(js|css|png|jpg|webp|woff2?)$/ {sum[$1] += $6} NR % 50 == 0 {for (h in sum) print h, sum[h] "B"; delete sum}'
说明:
- 过滤状态码 200 且路径匹配典型静态后缀,排除动态接口干扰;
-
$1是$host,$6是$body_bytes_sent(按上面定义的格式顺序); -
NR % 50 == 0表示每累计 50 条匹配日志输出一次汇总,适合中低流量站点; - 高流量场景建议改用
nginxlog-exporter接入 Prometheus,用rate(nginx_log_entry_body_bytes_sent_sum[1m])计算实时带宽(单位 bytes/sec)。