目录

一、核心依赖配置

二、使用 @WithSpan 注解标记业务方法

示例代码结构:

注解参数说明:

三、添加属性(Attributes)增强 Span 信息

四、启动配置(关键)

启动命令(JVM 参数方式):

环境变量方式(容器中):

五、验证效果

六、注意事项


OpenTelemetry 提供了 @WithSpan 注解(注解驱动方式),可以简化手动创建 Span 的过程,特别适合在 Spring Boot 项目中对关键业务方法进行追踪埋点。以下是详细的使用指南,包括依赖配置、代码示例和启动配置。

我的opentelemetry-javaagent.jar版本是2.15.0版本

一、核心依赖配置

使用 @WithSpan 注解需要引入 OpenTelemetry 的 API 和注解依赖(无需手动引入完整 SDK,Agent 会提供支持)。

Maven 依赖pom.xml):

<!-- OpenTelemetry 核心 API -->
<dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-api</artifactId>
    <version>1.53.0</version> <!-- 需与 Agent 版本兼容 -->
</dependency>

<!-- OpenTelemetry 注解支持 (WithSpan) -->
<dependency>
    <groupId>io.opentelemetry.instrumentation</groupId>
    <artifactId>opentelemetry-instrumentation-annotations</artifactId>
    <version>2.15.0</version>
</dependency>

<!-- Spring Boot 基础依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Lombok(可选,用于 @Slf4j 日志) -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

版本注意:API 和注解的版本必须与 OpenTelemetry Java Agent 版本保持一致(例如 Agent 用 1.33.0,依赖也用 1.33.0,这里我的jar包是2.15.0版本,依赖也是2.15.0)。

二、使用 @WithSpan 注解标记业务方法

@WithSpan 注解可以直接标记在方法上,OpenTelemetry Agent 会自动为该方法创建一个 Span,并将其加入当前追踪链路中。

示例代码结构:
// 1. 控制器层
@RestController
@Slf4j
public class OrderController {
    @Autowired
    private OrderService orderService;

    @GetMapping("/order/{id}")
    public String handleOrder(@PathVariable Long id) {
        log.info("接收订单请求,ID: {}", id);
        return orderService.processOrder(id);
    }
}

// 2. 服务层(核心:使用 @WithSpan)
@Service
public class OrderService {
    @Autowired
    private InventoryService inventoryService;

    // 标记方法为一个 Span,名称为 "processOrder"(默认使用方法名)
    @WithSpan
    public String processOrder(Long orderId) {
        // 业务逻辑
        checkOrderValid(orderId);
        // 调用另一个带 @WithSpan 的方法(自动成为子 Span)
        boolean hasStock = inventoryService.checkStock(orderId);
        return "订单处理完成,ID: " + orderId + ",库存状态: " + hasStock;
    }

    // 自定义 Span 名称(通过 value 指定)
    @WithSpan("checkOrderValidity")
    private void checkOrderValid(Long orderId) {
        // 验证订单有效性逻辑
        try {
            Thread.sleep(50); // 模拟耗时
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

// 3. 子服务层(嵌套 Span)
@Service
public class InventoryService {
    // 自动成为 processOrder 方法的子 Span
    @WithSpan
    public boolean checkStock(Long orderId) {
        // 检查库存逻辑
        try {
            Thread.sleep(100); // 模拟耗时
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return true;
    }
}
注解参数说明:
  • @WithSpan:默认使用方法名作为 Span 名称。
  • @WithSpan("customName"):通过 value 指定自定义 Span 名称。
  • 被注解的方法调用时,会自动创建 Span,并继承当前上下文的父 Span(形成调用链路)。

三、添加属性(Attributes)增强 Span 信息

可以通过 @SpanAttribute 注解为 Span 添加自定义属性(键值对),丰富追踪信息。

import io.opentelemetry.extension.annotations.SpanAttribute;

@Service
public class PaymentService {
    // 为 Span 添加属性:orderId 和 amount
    @WithSpan("processPayment")
    public void processPayment(
            @SpanAttribute("order.id") Long orderId,
            @SpanAttribute("payment.amount") BigDecimal amount) {
        log.info("处理支付,订单ID: {}, 金额: {}", orderId, amount);
        // 支付逻辑...
    }
}

在追踪系统(如 Jaeger)中,该 Span 会显示属性 order.id=123 和 payment.amount=99.99

四、启动配置(关键)

@WithSpan 注解需要通过 OpenTelemetry Java Agent 生效(无需手动初始化 Tracer),启动时必须指定 Agent JAR,并配置基础参数。

启动命令(JVM 参数方式):
java -javaagent:/path/to/opentelemetry-javaagent.jar \
  -Dotel.service.name=order-service \  # 服务名称(必填)
  -Dotel.exporter.otlp.endpoint=http://localhost:4317 \  # 导出地址(如 Jaeger/Collector)
  -Dotel.traces.sampler=parentbased_always_on \  # 全量采样(便于测试)
  -jar your-springboot-app.jar

环境变量方式(容器中):
# 配置环境变量
export OTEL_SERVICE_NAME="order-service"
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317"
export OTEL_TRACES_SAMPLER="parentbased_always_on"

# 启动应用
java -javaagent:/path/to/opentelemetry-javaagent.jar -jar your-springboot-app.jar

五、验证效果

  1. 启动应用后,访问接口:http://localhost:8080/order/123
  2. 在 Jaeger UI 中搜索服务名 order-service,可看到完整的追踪链路:
    • 顶层 Span:HTTP 请求(由 Agent 自动生成)
    • 中层 Span:processOrder(来自 @WithSpan
    • 子 Span:checkOrderValidity 和 checkStock(嵌套的 @WithSpan 方法)
  3. 每个 Span 会显示耗时、属性等信息,点击可查看详情。

六、注意事项

  1. Agent 依赖@WithSpan 必须配合 OpenTelemetry Java Agent 使用,仅引入依赖而不启动 Agent 会导致注解失效。
  2. 非 public 方法:默认情况下,Agent 可以增强 private/protected 方法的 @WithSpan(与普通方法一致)。
  3. 静态方法@WithSpan 支持静态方法,但需确保调用时处于追踪上下文(有父 Span)中。
  4. 异常处理:若方法抛出异常,Agent 会自动将异常信息记录到 Span 中(标记为错误状态)。

通过 @WithSpan 注解,无需手动编写 Tracer.spanBuilder() 代码,即可快速实现业务方法的追踪埋点,兼顾了代码简洁性和可观测性。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐