Nginx可通过$sent_http_x_biz_trace_id等变量将后端设置的业务流水号(如X-Biz-Trace-ID、X-Request-ID)写入访问日志,需确保上游服务返回对应响应头,且log_format中正确引用小写下划线格式变量。

可以通过 Nginx 的 $sent_http_* 变量直接捕获响应头内容,并在 log_format 中引用,从而将业务流水号(如 X-Request-ID 或自定义的 X-Biz-Trace-ID)写入访问日志。
确认响应头已由后端设置
Nginx 本身不生成业务流水号,需确保上游服务(如 Spring Boot、Node.js 等)在响应中明确设置了该头字段,例如:
X-Biz-Trace-ID: abc123-def456X-Request-ID: 7f8e9a2b-1c4d-4e6f-8a0c-1234567890ab
若后端未设置,Nginx 日志中对应字段将为空或显示“-”。
在 log_format 中引用响应头变量
Nginx 提供 $sent_http_{header_name} 变量来获取已发送的响应头值,注意:header_name 需转为小写并用下划线替换短横线。例如:
-
X-Biz-Trace-ID→$sent_http_x_biz_trace_id -
X-Request-ID→$sent_http_x_request_id
在 http 块中定义日志格式:
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$sent_http_x_biz_trace_id;验证变量是否生效
重启 Nginx 后发起一次请求,检查日志输出是否包含预期值。若始终为空,请排查:
- 后端是否真的返回了该响应头(可用
curl -I验证) - 该响应头是否被 Nginx 缓存或代理层过滤(如启用了
underscores_in_headers on不影响$sent_http_*,但影响接收请求头) - 是否使用了
proxy_pass且后端响应尚未发出(如超时、502 错误),此时$sent_http_*不可用,可配合$upstream_http_*做 fallback
进阶:兼容缺失场景与多头 fallback
为避免日志中出现大量“-”,可用 map 指令构造更健壮的变量:
map $sent_http_x_biz_trace_id $log_trace_id {
"" $sent_http_x_request_id;
default $sent_http_x_biz_trace_id;
}
<p>log_format main '... $log_trace_id';</p>这样当 X-Biz-Trace-ID 缺失时,自动回退到 X-Request-ID,提升日志可追溯性。











