nginx可通过内置变量$gzip_ratio、$bytes_sent和$body_bytes_sent配合log_format记录压缩率及流量大小;需先启用gzip on,再定义含该三变量的日志格式,并在server或location中调用access_log输出。

要让 Nginx 在访问日志中记录每条请求的 Gzip 压缩率 和 压缩前后流量大小,核心是利用内置变量 $gzip_ratio、$bytes_sent 和 $body_bytes_sent,配合自定义 log_format 实现。Nginx 本身不直接提供“原始响应大小”,但可通过组合变量近似还原,并确保日志格式能稳定输出关键指标。
启用 Gzip 并确认变量可用
必须先在 http 块中启用 Gzip 模块,否则 $gzip_ratio 始终为空或为 “-”:
-
gzip on;—— 必须开启,否则无压缩行为,变量无值 -
gzip_vary on;—— 推荐开启,辅助缓存识别压缩状态 -
gzip_comp_level 3;—— 不必过高,避免 CPU 过载影响日志写入稳定性 - 确保编译时包含 zlib(默认主流发行版已满足)
定义含压缩信息的日志格式
使用 log_format 添加以下字段(放在 http 块内):
log_format gzip_detail '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'$bytes_sent $gzip_ratio '
'"$http_referer" "$http_user_agent"';
-
$body_bytes_sent:响应体字节数(不含响应头),即“原始传输内容大小”近似值 -
$bytes_sent:实际发送给客户端的总字节数(含响应头 + 压缩后响应体) -
$gzip_ratio:压缩比,格式为1.234(小数),未压缩时为 “-” - 注意:
$gzip_ratio仅对成功压缩的响应有效;静态文件若被缓存或未命中 gzip 条件(如小于gzip_min_length),该值为 “-”
配置 access_log 并验证字段输出
在 server 或 location 块中启用该格式日志:
access_log /var/log/nginx/gzip_access.log gzip_detail;
发起请求后检查日志示例:
192.168.1.100 - - [01/Oct/2026:01:55:22 +0000] "GET /app.js HTTP/1.1" 200 124567 125032 1.421 "https://example.com/" "Mozilla/5.0..."- 原始体大小 ≈ 124567 字节(
$body_bytes_sent) - 实际发送 ≈ 125032 字节(
$bytes_sent,含 header) - 压缩比 1.421 表示压缩后体积约为原始的 70.4%(1 ÷ 1.421)
补充说明与常见问题
几点关键细节需注意:
-
$gzip_ratio是 Nginx 内置变量,无需额外模块,但只在启用gzip on且实际执行压缩时有值 - 无法直接获取“纯响应体压缩前大小”,
$body_bytes_sent是最接近的代理指标(对动态内容基本准确,对静态文件可能略偏高) - 若需精确原始大小,需在应用层(如 PHP/Node)写入自定义 header,再用
$sent_http_x_original_size引用,但属进阶方案 - 日志中出现
-表示该请求未触发 Gzip(如返回 304、小文件、不匹配gzip_types等)











