nginx 通过 access_log 记录 $request_id 实现链路串联,error_log 捕获中断点;需在 log_format 中显式包含 $request_id 并启用 log_subrequest on,二者协同才能完整还原请求路径。

Nginx 本身不生成分布式追踪的 span,但能作为全链路追踪的“锚点起点”和“日志枢纽”。真正实现请求级串联,靠的是 access_log 记录统一 trace ID + error_log 辅助定位中断点,二者分工明确、不可替代。
access_log 是链路对齐的主干道
它在请求生命周期结束时写入一行结构化日志,是唯一能稳定输出 $request_id 及上下游上下文的地方。
- 必须在
log_format中显式包含$request_id(不是$http_x_request_id),例如:log_format trace '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" "$http_user_agent" ' 'req_id:"$request_id" upstream:"$upstream_addr" ' 'rt:$request_time u_rt:$upstream_response_time'; - 在
server或location块中启用:access_log /var/log/nginx/trace.log trace; - 同时记录
$upstream_addr和$upstream_response_time,可直观看出请求转发到了哪台后端、耗时是否异常。
error_log 是链路断裂的听诊器
当请求卡在某个环节(如 upstream 连接失败、SSL 握手超时、header 过大),access_log 可能根本不会出现记录,此时 error_log 是唯一线索。
- 设置
error_log /var/log/nginx/error.log warn;可捕获 5xx 类错误源头; - 若需深挖 rewrite、proxy_pass 前后的变量变化,必须启用
debug级别(仅限调试环境):error_log /var/log/nginx/debug.log debug; # 并配合 debug_connection 指定 IP,避免日志爆炸 debug_connection 10.1.2.3;
- 注意:
error_log info不展开变量,看到的只是固定事件描述(如"upstream timed out"),不能替代access_log的字段记录。
两者协同才能还原完整路径
用户投诉某次请求失败,单查 access_log 可能为空(说明请求没走到记录阶段);单查 error_log 又缺乏 trace ID 关联。正确做法是:
- 先从客户端或网关拿到
X-Request-ID值; - 在
access_log中搜索该 ID,确认是否进入 Nginx、状态码、上游地址、响应耗时; - 若未命中,立即查
error_log,按时间范围筛选connect() failed、no live upstreams、client intended to send too large body等关键词,定位阻断位置; - 对于子请求(如
auth_request)、重试、内部重定向,需开启log_subrequest on,否则access_log默认不记录。
不复杂但容易忽略。











