核心是用$request_id作为唯一标识,从Nginx入口自动生成32位十六进制ID(需≥1.11.0),通过proxy_set_header X-Request-ID $request_id透传至后端,并在log_format中显式记录,配合各服务统一读取、复用和日志落盘,最终实现全链路日志聚合检索。

核心是用 $request_id 作为唯一标识,从 Nginx 入口开始生成、透传、记录,并在所有下游服务中复用该 ID,最终通过日志平台按 ID 聚合检索。
确保 Nginx 正确生成并记录 $request_id
Nginx 1.11.0 及以上版本原生支持 $request_id,每次请求自动产生一个 32 位小写十六进制字符串。不需要额外模块或 Lua 脚本。
- 在
http块中定义日志格式,显式包含$request_id,例如:log_format main '$request_id - $remote_addr [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"'; - 在
server或location块中启用该格式:access_log /var/log/nginx/access.log main; - 避免使用
$http_x_request_id替代 —— 它来自客户端,可能为空、被篡改或格式不一致。
把 request_id 透传到后端服务
ID 必须随请求一起发给下游,且不能被覆盖或丢弃。
- 在
location块内、紧邻proxy_pass的位置添加:proxy_set_header X-Request-ID $request_id; - 如果上游(如网关)已带
X-Request-ID,应优先复用,避免重复生成:
用map提取并兜底:map $http_x_request_id $forwarded_id { "" $request_id; default $http_x_request_id; }
再写proxy_set_header X-Request-ID $forwarded_id; - 确认后端服务(Spring Boot/Go/Node.js 等)实际读取了该 header,并注入日志上下文(如 MDC、Zap 字段、Winston metadata),而不是自行生成新 ID。
验证透传是否生效
链路是否完整,靠验证,不是靠配置完就默认成功。
- 用
curl -I http://your-domain/api查看响应头,确认返回了X-Request-ID,且值与 Nginx access.log 中对应行的$request_id完全一致。 - 检查 Nginx 错误日志是否有
upstream sent too big header类报错——可能是透传 header 导致响应头超长,需调大large_client_header_buffers。 - 若自定义 header 含下划线(如
X-Request-ID),务必在http块开头加:underscores_in_headers on;,否则 Nginx 默认忽略。
在各系统日志中统一检索该 ID
拿到用户投诉对应的 $request_id 后,不是只查 Nginx 日志,而是并行搜索所有环节。
- Nginx access log:看是否到达、状态码、耗时、真实 IP、上游地址
- 网关层日志(如 Kong、Spring Cloud Gateway):查路由匹配、鉴权失败、限流拦截
- 业务服务日志:定位参数解析异常、DB 查询慢、第三方接口超时或错误响应
- 建议所有服务日志中该字段名统一为
trace_id或request_id,值为 32 位小写 hex,便于 ELK / Loki 等平台提取和聚合


















