Nginx通过log_format定义含$http_x_request_id等变量的日志格式,并在access_log中启用,配合map指令可为缺失头设默认值“-”,确保调用链追踪头正确记录。

在 Nginx 中记录自定义请求头(如 X-Request-ID、X-B3-TraceId 等)用于微服务调用链追踪,核心是通过 log_format 指令在日志格式中引用请求头变量,再配合 access_log 启用该格式。
配置 log_format 引用自定义请求头
Nginx 提供 $http_XXX 变量来获取请求头,其中 XXX 是请求头名称转为小写并用下划线替换连字符后的形式。例如:
-
X-Request-ID→$http_x_request_id -
X-B3-TraceId→$http_x_b3_traceid -
X-B3-SpanId→$http_x_b3_spanid
在 http 块中定义日志格式:
log_format trace_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_x_request_id" "$http_x_b3_traceid" "$http_x_b3_spanid"';在 server 或 location 中启用该日志格式
指定使用刚定义的 trace_log 格式记录访问日志:
server {
listen 80;
server_name example.com;
<pre class='brush:php;toolbar:false;'>access_log /var/log/nginx/access_trace.log trace_log;
# 其他配置...}
注意:确保 Nginx 有权限向目标日志路径写入,且磁盘空间充足。
可选:对缺失头做默认值处理
若上游未携带某些追踪头,Nginx 日志中会显示破折号 -,影响日志解析。可用 map 指令提供默认值:
map $http_x_request_id $log_request_id {
"" "-";
default $http_x_request_id;
}
<p>map $http_x_b3_traceid $log_traceid {
"" "-";
default $http_x_b3_traceid;
}</p><p>log_format trace_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$log_request_id" "$log_traceid" "$http_x_b3_spanid"';这样即使请求头为空,日志中也会输出明确的 -,而非留空或异常字符。
验证与排查要点
发送带追踪头的请求,检查日志是否正确记录:
curl -H "X-Request-ID: req-123" \
-H "X-B3-TraceId: abcdef0123456789" \
-H "X-B3-SpanId: 9876543210fedcba" \
http://example.com/api/v1/users查看日志输出是否包含对应值。常见问题包括:
- 请求头名大小写不匹配(Nginx 中必须全小写+下划线)
- 日志路径权限不足,导致日志写入失败(查 error_log)
- 未重载 Nginx 配置(
nginx -s reload) - 客户端或中间代理剥离了自定义头(确认头确实到达 Nginx)


















