OpenTelemetry SDK 使用

OpenTelemetry(OTel)是 CNCF 的可观测性标准项目,提供了 Metrics、Logging、Tracing 的统一采集 SDK。在链路追踪领域,OTel 已成为事实标准,Jaeger、Zipkin、Tempo 等后端都支持 OTLP 协议接收 OTel 数据。

OTel SDK 的设计理念是模块化:核心 API 定义了抽象接口,各语言的具体实现提供能力,扩展库提供与特定框架(HTTP、gRPC、数据库)的集成。这种分层设计让 SDK 既轻量又可扩展。

SDK 架构概览

OTel SDK 的核心组件:

API 层:定义 Tracer、Span、Context 的抽象接口。API 是无状态的,只负责数据结构的定义,不涉及实际的数据采集。开发者在代码中使用 API 进行埋点。

SDK 层:提供 API 的具体实现,包括 Span 管理、采样决策、Context 传播、批量导出等能力。SDK 可以配置,如设置导出间隔、采样率、资源信息等。

SDK 扩展层:提供与特定框架的自动集成(如 Spring Boot、gRPC),以及导出器(OTLP、Jaeger、Zipkin)。

基本配置

Java SDK 的基本配置:

// 创建 Resource,描述服务信息
Resource resource = Resource.getDefault()
    .merge(Resource.create(Attributes.of(
        AttributeKey.stringKey("service.name"), "order-service",
        AttributeKey.stringKey("service.version"), "1.0.0",
        AttributeKey.stringKey("deployment.environment"), "production"
    )));

// 创建 TracerProvider
SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
    .setResource(resource)
    .setSampler(Sampler.alwaysOn())
    .addSpanProcessor(BatchSpanProcessor.builder(
        OtlpGrpcSpanExporter.builder()
            .setEndpoint("http://otel-collector:4317")
            .build()
    ).build())
    .build();

// 设置全局 TracerProvider
OpenTelemetry.setOpenTelemetrySdk(
    OpenTelemetrySdk.builder()
        .setTracerProvider(tracerProvider)
        .build()
);

Tracer 与 Span 创建

获取 Tracer 实例:

// 推荐在类初始化时获取 Tracer,避免重复查找
private static final Tracer tracer = 
    OpenTelemetry.getGlobalTracer("com.example.order", "1.0.0");

创建带属性的 Span:

Span span = tracer.spanBuilder("order.create")
    .setAttribute("order.type", "purchase")
    .setAttribute("order.channel", "mobile")
    .setAttribute("customer.id", customerId)
    .setSpanKind(SpanKind.CLIENT)  // 区分入口/出口 Span
    .startSpan();

SpanKind 用于描述 Span 的角色:SERVER(入口请求处理)、CLIENT(出口调用)、PRODUCER(消息发送)、CONSUMER(消息消费)、INTERNAL(内部操作)。正确的 Kind 设置对于 Trace 可视化非常重要。