W3C Trace Context 支持
本 HTTP 客户端完全支持 W3C Trace Context 规范,允许你在分布式系统中进行跨服务的链路追踪。
什么是 Trace Context?
W3C Trace Context 定义了标准的 HTTP 头格式,用于在分布式系统中传播追踪上下文信息。核心是 traceparent 头,格式如下:
traceparent: version-trace-id-parent-id-trace-flags
例如:
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
其中:
version(2位):当前固定为00trace-id(32位十六进制):唯一标识整个追踪链路parent-id(16位十六进制):唯一标识当前 span/操作trace-flags(2位十六进制):标志位,01表示已采样,00表示未采样
基础使用
1. 在请求中传递 traceparent
import { NsHttpClient, TraceContext } from 'nstarter-http-request';
const client = new NsHttpClient();
// 生成新的 traceparent
const traceparent = TraceContext.generate();
// 在请求中使用
const response = await client.get('https://api.example.com/users', {
traceparent
});
2. 传播现有的 traceparent
在微服务架构中,你通常需要从上游服务接收 traceparent 并传递给下游服务:
// 从上游请求中获取 traceparent
const incomingTraceparent = request.headers.traceparent;
// 创建子 span 并传递给下游服务
const childTraceparent = TraceContext.createChild(incomingTraceparent);
const response = await client.post('https://downstream-service.com/api', data, {
traceparent: childTraceparent
});
3. 自定义 traceparent 生成
// 生成未采样的 traceparent
const unsampled = TraceContext.generate({ sampled: false });
// 使用自定义的 trace ID
const customTrace = TraceContext.generate({
traceId: '0af7651916cd43dd8448eb211c80319c',
sampled: true
});
TraceContext 工具类
TraceContext 类提供了完整的工具方法来处理 W3C Trace Context:
生成方法
// 生成新的 traceparent
const traceparent = TraceContext.generate({
traceId?: string, // 可选,自定义 trace ID
parentId?: string, // 可选,自定义 parent/span ID
sampled?: boolean // 可选,是否采样,默认 true
});
// 生成 trace ID(32位十六进制)
const traceId = TraceContext.generateTraceId();
// 生成 span ID(16位十六进制)
const spanId = TraceContext.generateSpanId();
解析和验证
// 解析 traceparent
const parsed = TraceContext.parse('00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01');
// 返回:
// {
// version: '00',
// traceId: '0af7651916cd43dd8448eb211c80319c',
// parentId: 'b7ad6b7169203331',
// traceFlags: '01'
// }
// 验证 traceparent 是否有效
const isValid = TraceContext.isValid('00-...-...-01'); // true or false
// 验证 trace ID
const isValidTraceId = TraceContext.isValidTraceId('0af7651916cd43dd8448eb211c80319c');
// 验证 span ID
const isValidSpanId = TraceContext.isValidSpanId('b7ad6b7169203331');
创建子 Span
// 从父 traceparent 创建子 span
const parentTraceparent = '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01';
const childTraceparent = TraceContext.createChild(parentTraceparent);
// 子 span 会继承父 span 的 trace ID 和采样决策
// 但会生成新的 span ID
// 覆盖采样决策
const unsampledChild = TraceContext.createChild(parentTraceparent, false);
检查采样状态
// 检查 traceparent 是否已采样
const sampled = TraceContext.isSampled('00-...-...-01'); // true
const notSampled = TraceContext.isSampled('00-...-...-00'); // false