需启用 log_subrequest on 并配合 $request_completion 和 $request_id 字段,使 nginx 将 ssi 子请求及 upstream 转发细节写入 access log,实现全链路追踪。

要利用 log_subrequest 追踪反向代理中 SSI(Server Side Include)请求和 upstream 转发细节,核心是让 Nginx 将子请求(subrequest)也写入 access log,而默认情况下这些内部请求是被忽略的。
确认 Nginx 版本与模块支持
log_subrequest 指令自 Nginx 1.19.4 起正式引入,且需启用 --with-http_subrequest_module(通常默认编译进主模块)。可通过以下命令验证:
nginx -V 2>&1 | grep -o 'with-http_subrequest_module'
若无输出,说明当前版本不支持或模块未启用,需升级或重编译。
在日志配置中启用 subrequest 记录
在 http 或 server 块中添加:
log_subrequest on;
该指令作用于整个上下文,开启后所有子请求(包括 SSI 的 include virtual、auth_request、mirror、以及 proxy_pass 内部发起的上游探测等)都会触发 access log 记录。注意:它不会影响 error log,仅控制 access log 行为。
定制 log_format 区分主请求与子请求
为清晰识别子请求,建议在 log_format 中加入 $request_length、$upstream_http_x_request_id 等字段,并重点使用 $request_completion 和 $request_id 辅助判断:
log_format trace '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent<br>"$http_referer" "$http_user_agent" $request_id $request_completion';
-
$request_completion:值为OK表示主请求完成;子请求则为""(空字符串),可据此过滤 -
$request_id:每个请求(含子请求)有唯一 ID,SSI 包含的子请求会继承父请求的$request_id(若父请求已设),便于链路串联 - 搭配
$upstream_addr和$upstream_response_time可定位具体转发目标与耗时
配合 SSI 与 proxy_pass 的典型调试场景
例如一个启用了 SSI 的页面通过 proxy_pass 转发到后端,同时嵌入 <!--# include virtual="/api/status" -->:
- 主请求(如
GET /index.html)会记录一行,$request_completion为OK - SSI 发起的子请求(
GET /api/status)也会单独记录一行,$request_completion为空,但$request_id与主请求一致 - 若该子请求又经
proxy_pass转发,则其$upstream_addr和$upstream_response_time字段将体现真实 upstream 地址与延迟
这样就能在日志中完整还原“页面请求 → SSI 子请求 → 反向代理转发 → 后端响应”的全链路行为。










