精准统计网站静态资源外发流量需在http块定义含$body_bytes_sent的log_format,各server块独立启用并指定唯一access_log路径,$body_bytes_sent准确记录压缩后响应体字节数,验证时检查日志第6字段是否为非零值。
要精准统计网站静态资源的外发流量带宽,核心是让 log_format 稳定捕获 $body_bytes_sent,并确保它能真实反映 JS、CSS、图片等静态内容发出的字节数(不含响应头)。这个变量本身不需额外模块,但必须显式写入日志格式,且配置位置和上下文要正确。
不能依赖默认 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 提取时列数易错;不能多个站点共用一个 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 -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}'
说明:
$1 是 $host,$6 是 $body_bytes_sent(按上面定义的格式顺序);NR % 50 == 0 表示每累计 50 条匹配日志输出一次汇总,适合中低流量站点;nginxlog-exporter 接入 Prometheus,用 rate(nginx_log_entry_body_bytes_sent_sum[1m]) 计算实时带宽(单位 bytes/sec)。