OpenTelemetry 通过注解驱动(@WithSpan) 应用于springboot项目
OpenTelemetry的@WithSpan注解简化SpringBoot应用埋点,只需添加依赖并标记方法即可自动生成Span。需配合JavaAgent使用,支持自定义Span名称、添加属性,并自动构建调用链路。启动时配置Agent参数即可在Jaeger等系统中查看完整追踪信息,实现无侵入式代码埋点。该方法相比手动创建Span更简洁高效,适合业务方法监控场景。
目录
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
五、验证效果
- 启动应用后,访问接口:
http://localhost:8080/order/123 - 在 Jaeger UI 中搜索服务名
order-service,可看到完整的追踪链路:- 顶层 Span:HTTP 请求(由 Agent 自动生成)
- 中层 Span:
processOrder(来自@WithSpan) - 子 Span:
checkOrderValidity和checkStock(嵌套的@WithSpan方法)
- 每个 Span 会显示耗时、属性等信息,点击可查看详情。
六、注意事项
- Agent 依赖:
@WithSpan必须配合 OpenTelemetry Java Agent 使用,仅引入依赖而不启动 Agent 会导致注解失效。 - 非 public 方法:默认情况下,Agent 可以增强 private/protected 方法的
@WithSpan(与普通方法一致)。 - 静态方法:
@WithSpan支持静态方法,但需确保调用时处于追踪上下文(有父 Span)中。 - 异常处理:若方法抛出异常,Agent 会自动将异常信息记录到 Span 中(标记为错误状态)。
通过 @WithSpan 注解,无需手动编写 Tracer.spanBuilder() 代码,即可快速实现业务方法的追踪埋点,兼顾了代码简洁性和可观测性。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)