Nginx默认不记录请求体,但可通过$request_body变量(需满足代理或缓冲配置前提)或lua-nginx-module主动读取并注入日志;须权衡性能、安全与日志膨胀风险,建议按需临时启用或交由应用层处理。

默认情况下,Nginx 不会记录请求体(request body)内容,这是出于性能、安全和隐私的考虑。但某些调试或审计场景下,确实需要捕获如 POST 表单、JSON 数据等原始请求体。Nginx 官方模块不直接支持“记录 body 到 access_log”,但可通过几种特殊手段间接实现,关键在于提前读取并缓存 body,再通过变量注入日志。
使用 $request_body 变量(最常用,但有前提)
该变量仅在 Nginx 已读取并解析请求体后才有效,常见于以下情况:
- 使用 proxy_pass 或 fastcgi_pass 等代理指令时,Nginx 默认会读取整个 body(除非显式禁用);
- 使用 client_body_buffer_size 和 client_max_body_size 控制缓冲与限制;
- 若 body 超出缓冲区且未启用 client_body_in_file_only off,则 $request_body 为空 —— 此时需确保 body 完全驻留内存。
配置示例:
log_format body_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'req_body:"$request_body"';
<p>server {
client_max_body_size 1M;
client_body_buffer_size 128k;
client_body_in_single_buffer on; # 强制将 body 存入单一内存缓冲区</p><pre class="brush:php;toolbar:false;">access_log /var/log/nginx/access_body.log body_log;
location /api/ {
proxy_pass https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e;
proxy_set_header X-Real-IP $remote_addr;
}}
配合 lua-nginx-module(更灵活可靠)
OpenResty 或编译了 lua-nginx-module 的 Nginx,可用 Lua 在 rewrite 或 access 阶段主动读取 body:
- 调用 ngx.req.read_body() 触发读取;
- 用 ngx.req.get_body_data() 获取内存中 body(小 body);
- 对大 body,用 ngx.req.get_body_file() 获取临时文件路径,再读取(注意权限与清理);
- 将内容存入自定义变量(如 $my_req_body),供 log_format 引用。
示例片段:
log_format lua_log '... req_body:"$my_req_body"';
<p>map $my_req_body $my_req_body { ~^(?s).{0,2048}$ $my_req_body; default "-"; }</p><p>server {
location /api/ {
access_by_lua_block {
ngx.req.read_body()
local data = ngx.req.get_body_data()
if data then
ngx.var.my_req_body = data
else
ngx.var.my_req_body = "-"
end
}
proxy_pass <a href="https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e">https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e</a>;
}
}注意边界与风险
记录请求体不是常规操作,务必权衡以下问题:
- 性能开销:读取、缓冲、复制 body 会增加 CPU 和内存压力,尤其高并发时;
- 敏感信息泄露:密码、token、身份证号等可能明文落盘,需严格管控日志权限、加密存储或脱敏;
- 日志膨胀:一个 1MB 的 JSON 请求会让单行日志暴涨,影响 grep、rotate 和 SIEM 分析;
- 二进制/非 UTF-8 内容:$request_body 可能含乱码或截断,Lua 中处理需注意编码与长度限制。
替代建议:按需触发 + 临时启用
不建议长期开启 body 记录。更稳妥的做法是:
- 通过特定 header(如 X-Debug-Log-Body: 1)或 IP 白名单动态启用;
- 用 map 指令控制是否写入 $request_body 到日志字段;
- 调试结束后立即关闭,避免遗漏;
- 生产环境优先使用应用层日志(如后端服务记录原始 payload),而非 Nginx 层。


















