PHP 通过 trace_id 实现全链路追踪
PHP 通过 trace_id 实现全链路追踪(Distributed Tracing),是将一次用户请求在多个服务(Nginx、PHP-FPM、MySQL、Redis、第三方 API)间传递的唯一标识。它让工程师从'日志大海捞针'升级为'一键穿透故障',是高可用系统必备能力。
一、核心原理:trace_id 如何串联全链路?
1. 分布式追踪三要素
| 元素 | 作用 | 示例 |
|---|
本文介绍了 PHP 系统中通过 trace_id 实现全链路追踪的核心原理与工程实践。内容包括分布式追踪三要素(trace_id, span_id, parent_span_id)、上下文透传机制(HTTP 头、Redis、cURL)、日志注入方法(Monolog、JSON 格式)以及与 APM 系统(Datadog, Jaeger, ELK)的集成方案。同时总结了统一标准、监控告警及常见误区,旨在帮助工程师从单点日志升级为全链路故障定位。
PHP 通过 trace_id 实现全链路追踪(Distributed Tracing),是将一次用户请求在多个服务(Nginx、PHP-FPM、MySQL、Redis、第三方 API)间传递的唯一标识。它让工程师从'日志大海捞针'升级为'一键穿透故障',是高可用系统必备能力。
| 元素 | 作用 | 示例 |
|---|
| trace_id | 唯一标识一次完整请求 | a1b2c3d4-... |
| span_id | 标识链路中的一个操作(如 SQL 查询) | e5f6g7h8 |
| parent_span_id | 标识父操作(构建调用树) | a1b2c3d4 |
trace_id → 透传给 PHP;trace_id 放入请求头;关键头:
X-Request-ID: a1b2c3d4-... // 通用
Traceparent: 00-a1b2c3d4-...-01 // W3C Trace Context 标准
核心:
trace_id是请求的'身份证',贯穿所有系统。
方案 2:PHP 生成
// public/index.php
$traceId = $_SERVER['HTTP_X_REQUEST_ID'] ?? uniqid('', true);
$_SERVER['HTTP_X_REQUEST_ID'] = $traceId;
方案 1:Nginx 生成(推荐)
# nginx.conf
location / {
set $trace_id $http_x_request_id;
if ($trace_id = '') {
set $trace_id "$pid-$msec-$remote_addr";
}
proxy_set_header X-Request-ID $trace_id;
fastcgi_param HTTP_X_REQUEST_ID $trace_id;
}
Redis 客户端(需支持):
// Predis 不直接支持,但可记录日志
Log::info('Redis GET', ['trace_id' => $traceId, 'key' => $key]);
cURL 调用第三方 API:
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, ['X-Request-ID: ' . ($traceId ?? ''))];
输出 JSON 日志:
{"message":"User login","context":{"user_id":123,"trace_id":"a1b2c3d4"}}
Monolog 示例:
use Monolog\Processor\ProcessorInterface;
class TraceIdProcessor implements ProcessorInterface
{
public function __invoke(array $record): array
{
$record['context']['trace_id'] = $_SERVER['HTTP_X_REQUEST_ID'] ?? null;
return $record;
}
}
$logger->pushProcessor(new TraceIdProcessor());
dd.trace_id、dd.span_id;安装 dd-trace 扩展:
sudo apt-get install datadog-php-tracer
使用 OpenTelemetry PHP SDK:
use OpenTelemetry\API\Trace\TracerProvider;
use OpenTelemetry\SDK\Trace\TracerProvider as SdkTracerProvider;
$tracer = (new SdkTracerProvider())->getTracer('my-app');
$span = $tracer->spanBuilder('http-request')->startSpan();
$span->setAttribute('http.method', $_SERVER['REQUEST_METHOD']);
// 透传到下游
$propagator = new TraceContextPropagator();
$propagator->inject($span->getContext(), new RequestHeadersSetter($_SERVER));
Kibana 中用 trace_id 聚合日志:
trace_id: "a1b2c3d4" → 显示全链路日志
Filebeat 解析 trace_id:
# filebeat.yml
processors:
- dissect:
tokenizer: '{"trace_id":"%{trace_id}}'
field: "message"
target_prefix: "log"
错误率告警:
rate(trace.php.request.errors{service:api}) / rate(trace.php.request.hits{service:api}) > 0.01
慢请求告警:
avg(last_5m):trace.php.request.duration{service:api} > 1000

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online