log_subrequest on 用于使子请求按主请求日志格式记录;需配合自定义日志格式(含$request_id、$pid等)、避免access_log off及启用SSI/auth_request等模块才能生效。

在 Nginx 中,log_subrequest 指令用于控制是否将子请求(subrequest)的访问日志写入 access log。它本身不开启日志记录功能,而是决定“已配置的日志格式是否应用于子请求”。要真正追踪内部转发(如 proxy_pass、fastcgi_pass 后的 upstream 请求)或 SSI(Server Side Include)引入的资源请求,需结合日志配置、子请求识别机制与调试手段协同使用。
理解子请求的本质与 log_subrequest 的作用
Nginx 的子请求是内部发起的、不暴露给客户端的请求,常见于:
- SSI 指令(如
<!--# include virtual="/header.html" -->)触发的内部 GET - 使用
auth_request进行鉴权时的后台校验请求 - 某些模块(如
ngx_http_image_filter_module)内部调用
log_subrequest on; 的作用是:当主请求已启用 access_log,且该子请求也满足日志条件(如未被 access_log off 禁用),则该子请求也会按相同格式记入日志。默认值为 off,即子请求不记日志。
启用子请求日志记录的必要配置步骤
仅设 log_subrequest on 不足以看到子请求日志——还需确保日志本身能区分主/子请求,并输出有意义的字段:
- 在
http或server块中添加:log_subrequest on; - 定义一个包含
$request_id和$pid(或$connection)的日志格式,便于关联父子请求 - 在日志格式中加入
$request_length、$upstream_http_content_type等,辅助判断是否为 SSI 或内部转发 - 确保子请求所在 location 未禁用日志(例如避免
access_log off;)
示例日志格式:
log_format subreq '[$time_local] $request_id $pid "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$upstream_http_content_type" $request_length';识别 SSI 与内部转发子请求的关键线索
子请求不会显示在客户端网络面板中,但可通过日志字段推断其来源:
-
SSI 子请求:通常路径为
virtual=...引入的 URI;$request字段会显示完整内部请求行(如GET /header.html HTTP/1.0);$http_user_agent为空或为"-";$request_length较小(无请求体) -
proxy_pass/fastcgi_pass 内部转发:若后端响应头含
X-Accel-Redirect或使用了internallocation,则对应子请求可能出现在日志中;注意$upstream_addr和$upstream_status字段是否非空 -
auth_request 子请求:常位于
/auth类 location;$request多为GET /auth HTTP/1.0;$status通常为 200 或 401/403
验证与调试建议
启用后,推荐通过以下方式确认子请求是否被记录:
- 在测试页面中嵌入 SSI:
<!--# include virtual="/ssi-test.txt" -->,并确保ssi on;已启用 - 使用
curl -v http://your-site/test.html触发请求,同时实时监听日志:tail -f /var/log/nginx/access.log - 观察是否有额外日志行出现,比对
$request_id是否与主请求一致(需在主请求中也注入该变量,例如用map或set配合random) - 若仍无子请求日志,请检查是否误将子请求路由到了
internallocation(该类 location 默认不记录 access log,除非显式启用)

















