cp_tools / trace_kit
Framework-agnostic trace context propagation and structured logging toolkit.
dev-master
2026-01-26 02:30 UTC
Requires
- php: >=8.1
Suggests
- psr/log: Required to use TraceLogger with PSR-3 compatible loggers.
This package is not auto-updated.
Last update: 2026-01-27 00:58:01 UTC
README
一个框架无关的 Trace Context 传播与结构化日志工具包,帮助你在 HTTP / CLI / MQ 等场景下,以极小改动实现链路追踪与日志关联。
该包聚焦三件事:
- 统一的 Trace 上下文管理(TraceContext)
- 标准化的传播机制(Propagation)
- 自动日志增强与结构化输出(Logging Enrichment)
适用场景
- HTTP 服务:从请求头提取 trace,日志自动带 trace 字段,响应头可回写 trace
- 队列生产/消费:生产侧注入 trace,消费侧延续 trace
- CLI/定时任务:启动即生成 trace,全程贯穿任务日志
核心能力总览
1) Trace 生命周期管理(Tracer)
通过 Tracer::start() / Tracer::end() 形成统一生命周期:
- 自动提取或生成
trace_id - 自动生成
span_id - 自动生成
request_id - 自动记录开始时间并在结束时计算
latency_ms - 自动清理上下文,避免污染下一次执行单元
主要方法:
Tracer::configure(array $config): voidTracer::start(array $carrier = [], array $initialFields = []): TraceStateTracer::startFromServer(array $server, array $initialFields = []): TraceStateTracer::end(array $finalFields = []): arrayTracer::withSpan(string $name, callable $fn, array $fields = [])Tracer::inject(array &$carrier): voidTracer::contextFields(): array
2) 全局上下文访问(TraceContext)
在任意位置读写当前 trace 上下文:
TraceContext::get(string $key)TraceContext::set(string $key, $value): voidTraceContext::all(): arrayTraceContext::clear(): void
默认基于 InMemoryStorage,适用于 PHP-FPM / CLI。
3) 标准传播机制(Propagation)
已内置:
W3C Trace Context(默认)
- 类:
W3CTraceContextPropagator - Header:
traceparent - 行为:
- 入站存在
traceparent时延续trace_id - 出站注入标准
traceparent
- 入站存在
兼容旧 Header
- 类:
LegacyHeaderPropagator - 支持:
X-Trace-IdX-Span-IdX-Parent-Span-Id
4) Carrier 规范化(CarrierNormalizer)
解决大小写与 $_SERVER 提取问题:
CarrierNormalizer::normalize(array $carrier): arrayCarrierNormalizer::fromServerArray(array $server): array
5) 日志增强与结构化输出
JsonLineLogger(开箱即用)
无需任何第三方依赖:
- 每条日志一行 JSON
- 自动注入 trace 上下文字段
- 可直接输出到 stdout 或文件
类:JsonLineLogger
TraceLogger(装饰已有 Logger)
用于包装已有 logger(建议具备 log() 或各级别方法):
类:TraceLogger
说明:本包不强依赖
psr/log,但如果你要对接 PSR-3 生态,建议安装psr/log。
6) 字段治理与安全(FieldPolicy)
内置默认策略:DefaultFieldPolicy
能力包括:
- 敏感字段过滤(如 password/token/authorization 等)
- 最大深度限制
- 最大字符串长度裁剪
- 最大字段数量限制
你可以:
- 直接使用默认策略
- 通过配置数组调整策略
- 传入自定义
FieldPolicyInterface实现
结构化日志字段(推荐)
日志将稳定包含这些关键字段(视调用时机而定):
tslevelmsgserviceenvtrace_idspan_idparent_span_id(可能存在)request_idlatency_ms(在 end 后可获得)
建议在不同场景补充字段:
- HTTP:
method,uri,ip,user_agent - MQ:
queue,topic,message_id - 运行时:
host,pid,php_sapi
安装
composer require cp_tools/trace_kit
如果你希望更好地对接 PSR-3:
composer require psr/log
快速开始(CLI)
<?php
use CpTools\TraceKit\JsonLineLogger;
use CpTools\TraceKit\Tracer;
Tracer::configure([
'service' => 'order-service',
'env' => 'prod',
]);
$logger = new JsonLineLogger();
Tracer::start([], ['command' => 'sync:orders']);
$logger->info('任务开始');
Tracer::withSpan('fetch-remote', function () use ($logger): void {
$logger->info('正在拉取远程数据', ['step' => 1]);
});
$endFields = Tracer::end(['result' => 'ok']);
$logger->info('任务结束', $endFields);
HTTP 接入(纯 PHP)
<?php
use CpTools\TraceKit\CarrierNormalizer;
use CpTools\TraceKit\JsonLineLogger;
use CpTools\TraceKit\Tracer;
Tracer::configure([
'service' => 'api-gateway',
'env' => 'prod',
]);
$carrier = CarrierNormalizer::fromServerArray($_SERVER);
Tracer::start($carrier, [
'method' => $_SERVER['REQUEST_METHOD'] ?? null,
'uri' => $_SERVER['REQUEST_URI'] ?? null,
'ip' => $_SERVER['REMOTE_ADDR'] ?? null,
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? null,
]);
$logger = new JsonLineLogger();
$logger->info('请求进入');
// 业务逻辑...
$responseHeaders = [];
Tracer::inject($responseHeaders); // 可按需回写到响应头
$endFields = Tracer::end(['status' => 200]);
$logger->info('请求结束', $endFields);
队列接入(生产 / 消费)
生产侧(注入 headers)
Tracer::start([], ['topic' => 'orders']);
$headers = [];
Tracer::inject($headers);
// 将 $headers 放入消息 meta 后发送
Tracer::end();
消费侧(提取 headers)
Tracer::start($headersFromMessage, [
'queue' => 'orders',
'message_id' => $messageId,
]);
// 处理消息...
Tracer::end(['handled' => true]);
配置说明(Tracer::configure)
支持以下配置项:
service(建议必填)env(建议必填)propagator(默认 W3CTraceContextPropagator)id_generator(默认 HexTraceIdGenerator)storage(默认 InMemoryStorage)field_policy(可传策略对象或配置数组)clock(默认 SystemClock)
示例:
use CpTools\TraceKit\Tracer;
Tracer::configure([
'service' => 'order-service',
'env' => 'prod',
'field_policy' => [
'max_depth' => 3,
'max_string_length' => 500,
'max_items' => 50,
'sensitive_keys' => ['password', 'token', 'authorization'],
],
]);
本地示例
仓库已提供可直接运行的示例:
php examples/cli.php
php examples/http.php
php examples/queue_producer.php
php examples/queue_consumer.php
设计原则
- 框架无关
- 默认可用
- 传播标准化(优先 W3C)
- 出错不影响业务(内部异常降级/吞并)
- 强调字段治理,避免日志失控