我们知道对于 JAVA 应用可以通过 OpenTelemetry 提供的 Java agent 来实现自动埋点功能,在大多数场景下也完全足够了,但是有时候我们需要更加精细的控制,这时候我们就需要使用手动埋点的方式来实现了 。
使用注解埋点我们可以在 Java 应用通过手动埋点的方式来实现链路追踪,但如果我们不希望进行太多的代码更改,那么可以使用注解的方式来实现,OpenTelemetry 提供了一些注解来帮助我们实现手动埋点,比如 @WithSpan
、@SpanAttribute
。
首先我们需要添加依赖库 opentelemetry-instrumentation-annotations
。
<dependencies> <dependency> <groupId>io.opentelemetry.instrumentation</groupId> <artifactId>opentelemetry-instrumentation-annotations</artifactId> <version>1.29.0</version> </dependency></dependencies>
开发人员可以使用 @WithSpan
注解来向 OpenTelemetry 自动检测发送信号,每当标记的方法被执行时都应创建一个新的 span 。
比如我们在 Order Service 中的 IndexController
中添加一个 @WithSpan
注解,代码如下所示:
// src/mAIn/java/com/youdianzhishi/orderservice/controller/IndexController.javapackage com.youdianzhishi.orderservice.controller;// ......import io.opentelemetry.instrumentation.annotations.WithSpan;@RestController@RequestMApping("/")public class IndexController { @GetMapping @WithSpan public ResponseEntity<String> home(HttpServletRequest request) { return new ResponseEntity<>("Hello OpenTelemetry!", HttpStatus.OK); }}
然后我们重建镜像,重新启动容器,当我们访问首页的时候就可以看到 Jaeger UI 中多了一个 IndexController.home
的 span 了 。
每次应用程序调用有注解的方法时,它都会创建一个表示其持续时间并提供任何抛出异常的 span 。默认情况下,span 名称是 <className>.<methodName>
,当然也可以在注解中提供了一个名称作为参数,比如可以使用 @WithSpan("indexSpan")
来指定 span 的名称,这样在 Jaeger UI 中就可以看到 indexSpan
的 span 了 。
此外当为一个带注解的方法创建一个 span 时,可以通过使用 @SpanAttribute
注解来自动将方法调用的参数值添加为创建 span 的属性 。
比如我们在 IndexController
中添加一个 fetchId
函数,并接收一个 id 参数,我们就可以使用 @SpanAttribute
注解来将接收的 id 参数添加为 indexSpanWithAttr
这个 span 的属性,代码如下所示:
// src/main/java/com/youdianzhishi/orderservice/controller/IndexController.javapackage com.youdianzhishi.orderservice.controller;// ......import io.opentelemetry.instrumentation.annotations.WithSpan;import io.opentelemetry.instrumentation.annotations.SpanAttribute;@RestController@RequestMapping("/")public class IndexController { @GetMapping @WithSpan("indexSpan") public ResponseEntity<String> home(HttpServletRequest request) { return new ResponseEntity<>("Hello OpenTelemetry!", HttpStatus.OK); } @GetMapping("/{id}") @WithSpan("indexSpanWithAttr") public ResponseEntity<String> fetchId(@SpanAttribute("id") @PathVariable Long id) { return new ResponseEntity<>("Hello OpenTelemetry:" + id, HttpStatus.OK); }}
然后我们重建镜像,重新启动容器,当我们访问 http://localhost:8081/123
的时候就可以看到 Jaeger UI 中多了一个 indexSpanWithAttr
的 span 了,并且该 span 的属性中包含了我们传递的 id 参数 。
推荐阅读
- 通过诗经楚辞取的公司名字
- 动量定理的应用 动量定理的应用视频讲解
- 深入浅出、玩转Java多线程
- 揭秘十个必知的 JavaScript 3D 库,打造顶级3D炫酷效果!
- 图灵测试已死!ChatGPT通过人类考试也不算,超强AI评估新秀「逻辑谜题」
- 王者荣耀的段位排行榜是通过Redis实现的?
- 我不再写Javascript了
- Java 单元测试及常用语句
- 构建高效的Java网络应用,体验秒级响应
- 谷歌推出 AlloyDB AI,帮助开发者创建生成式 AI 应用