log_subrequest指令用于控制是否将子请求记录到access log,默认不记录;需Nginx≥1.19.4,置于http/server/location块中设为on,并确保在access_log之后生效。

在 Nginx 中,log_subrequest 指令用于控制是否将子请求(subrequest)的访问日志写入 access log。它本身不“开启”日志,而是决定已配置的日志格式是否记录由内部重定向(如 rewrite ... last、try_files、error_page、auth_request 或 Lua 的 ngx.location.capture)触发的子请求。默认情况下,子请求**不记入 access log**;启用该指令后,它们才会像主请求一样被记录,便于追踪内部跳转链路。
确认 Nginx 版本与模块支持
log_subrequest 自 Nginx 1.19.4 起正式引入(早期开发版已有),且仅对 HTTP 模块生效。需确保:
- 运行版本 ≥ 1.19.4(执行
nginx -v验证) - 未禁用标准 HTTP 日志模块(通常默认启用)
- 若使用 OpenResty,需 ≥ 1.19.3.2(对应 Nginx 内核版本)
在日志配置中启用子请求记录
该指令必须置于 http、server 或 location 块中,值为 on 或 off(默认 off)。例如:
}http {
log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'req_id:$request_id sub:$request_completion';
<pre class='brush:php;toolbar:false;'>access_log /var/log/nginx/access.log detailed;
log_subrequest on; # ← 关键:全局启用子请求日志
注意:log_subrequest on 必须出现在 access_log 指令之后或同级作用域,否则不生效。若只希望特定 location 记录子请求,可将其放在对应 location 块内。
识别日志中的子请求条目
启用后,子请求会在 access log 中出现,可通过以下特征区分:
-
$request_completion变量值为OK(主请求)或subrequest(子请求)——推荐在log_format中显式包含该变量 - 子请求的
$request通常是内部路径(如"GET /internal/auth HTTP/1.0"),协议版本常为HTTP/1.0 - 响应状态码可能为
200(内容被内部消费)、404(try_files后备失败)或301/302(内部重定向未终止) - 无真实客户端 IP 的子请求,
$remote_addr可能显示为127.0.0.1或空(取决于发起方式)
配合调试技巧定位重定向逻辑
单靠日志还不够,建议组合使用:
- 在关键
location中添加add_header X-Subrequest "true" always;,用响应头标记子请求响应 - 用
map构造自定义变量标识重定向来源,例如:map $request_uri $redirect_source { ~^/api/.* "api_proxy"; ~^/static/ "static_fallback"; default "-"; }
并在log_format中记录$redirect_source - 对
try_files或error_page触发的子请求,检查其目标location是否有internal;—— 有则不会对外暴露,但日志仍可记录

















