Nginx可通过log_format配合$http_*变量记录自定义请求头,如Trace-ID转为$http_trace_id;需在http块定义格式、server中启用access_log,并可选map指令提供默认值避免空字段。

Nginx 默认日志不记录请求头(Header)信息,但可以通过 log_format 指令配合 $http_* 变量,将任意请求头(包括自定义 Header 如 Trace-ID、X-Request-ID 等)写入访问日志。
1. 在 log_format 中引用自定义 Header 变量
Nginx 会自动将所有 HTTP 请求头映射为变量:$http_头名,其中头名需转为小写,并用下划线替代短横线(-)。例如:
-
Trace-ID→$http_trace_id -
X-Request-ID→$http_x_request_id -
X-B3-Traceid→$http_x_b3_traceid
在 http 块中定义日志格式(如名为 main_with_trace):
log_format main_with_trace '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_trace_id" "$http_x_request_id"';
注意:若 Header 不存在,对应字段值为空字符串,不会报错。
2. 在 server 或 location 中启用该日志格式
使用 access_log 指令指定日志路径和刚才定义的格式名:
server {
listen 80;
server_name example.com;
<pre class="brush:php;toolbar:false;">access_log /var/log/nginx/access.log main_with_trace;
location / {
proxy_pass http://backend;
# 可选:透传 Trace-ID 到后端
proxy_set_header Trace-ID $http_trace_id;
}
}
3. 验证 Header 是否被正确捕获
发送带自定义 Header 的请求测试:
curl -H "Trace-ID: abc123xyz" http://example.com/
然后查看日志输出,最后一列应显示 "abc123xyz"(注意引号是日志格式中显式添加的)。若为空,检查:
- Header 名拼写是否与
$http_*变量一致(全小写+下划线) - 客户端是否确实发送了该 Header(可用
curl -v确认) - Nginx 配置是否重载:
nginx -s reload
4. 进阶:为缺失 Header 提供默认值(可选)
使用 map 指令定义更健壮的变量,避免日志中出现大量空字段:
map $http_trace_id $log_trace_id {
"" "-"; # 空值时记为 "-"
default $http_trace_id;
}
<p>log_format main_with_trace '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$log_trace_id"';</p>这样即使请求没带 Trace-ID,日志中也会显示 "-" 而非空引号。











