cp_tools/trace_kit

Framework-agnostic trace context propagation and structured logging toolkit.

Maintainers

Details

gitee.com/p87/cp_tools

Installs: 0

Dependents: 0

Suggesters: 0

Security: 0

pkg:composer/cp_tools/trace_kit

dev-master 2026-01-26 02:30 UTC

This package is not auto-updated.

Last update: 2026-01-27 00:58:01 UTC


README

一个框架无关的 Trace Context 传播与结构化日志工具包,帮助你在 HTTP / CLI / MQ 等场景下,以极小改动实现链路追踪与日志关联。

该包聚焦三件事:

  1. 统一的 Trace 上下文管理(TraceContext)
  2. 标准化的传播机制(Propagation)
  3. 自动日志增强与结构化输出(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): void
  • Tracer::start(array $carrier = [], array $initialFields = []): TraceState
  • Tracer::startFromServer(array $server, array $initialFields = []): TraceState
  • Tracer::end(array $finalFields = []): array
  • Tracer::withSpan(string $name, callable $fn, array $fields = [])
  • Tracer::inject(array &$carrier): void
  • Tracer::contextFields(): array

2) 全局上下文访问(TraceContext)

在任意位置读写当前 trace 上下文:

  • TraceContext::get(string $key)
  • TraceContext::set(string $key, $value): void
  • TraceContext::all(): array
  • TraceContext::clear(): void

默认基于 InMemoryStorage,适用于 PHP-FPM / CLI。

3) 标准传播机制(Propagation)

已内置:

W3C Trace Context(默认)

  • 类:W3CTraceContextPropagator
  • Header:traceparent
  • 行为:
    • 入站存在 traceparent 时延续 trace_id
    • 出站注入标准 traceparent

兼容旧 Header

  • 类:LegacyHeaderPropagator
  • 支持:
    • X-Trace-Id
    • X-Span-Id
    • X-Parent-Span-Id

4) Carrier 规范化(CarrierNormalizer)

解决大小写与 $_SERVER 提取问题:

  • CarrierNormalizer::normalize(array $carrier): array
  • CarrierNormalizer::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 实现

结构化日志字段(推荐)

日志将稳定包含这些关键字段(视调用时机而定):

  • ts
  • level
  • msg
  • service
  • env
  • trace_id
  • span_id
  • parent_span_id(可能存在)
  • request_id
  • latency_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)
  • 出错不影响业务(内部异常降级/吞并)
  • 强调字段治理,避免日志失控