Java 应用通过 OpenTelemetry API 实现手动埋点( 四 )

在上述代码中,我们定义了一个 @Configuration 类,并使用 @Bean 注解为 OpenTelemetry 创建了一个 Bean,Spring 会管理这个 Bean 的生命周期,并在需要时自动注入 。
这样,你的 Spring Boot 应用每次启动时,都会执行这些初始化代码,从而确保了 OpenTelemetry 的正确配置 。
在真正初始化的代码中,我们首先从环境变量中获取 OTLP Exporter 的地址,然后初始化 OTLP Exporter,接着初始化 TracerProvider,最后初始化并返回 OpenTelemetry SDK 。
比如现在我们在 OrderController 中的 getAllOrders 处理器中来手动埋点,代码如下所示:
// src/main/java/com/youdianzhishi/orderservice/controller/OrderController.javapackage com.youdianzhishi.orderservice.controller;// ......import io.opentelemetry.api.OpenTelemetry;import io.opentelemetry.api.trace.StatusCode;import io.opentelemetry.api.trace.Tracer;@RestController@RequestMapping("/api/orders")public class OrderController {    private static final Logger logger = LoggerFactory.getLogger(OrderserviceApplication.class);    @Autowired    private OrderRepository orderRepository;    @Autowired    private WebClient webClient;    @Autowired    private Tracer tracer;  // 注入 Tracer    @GetMapping    public ResponseEntity<List<OrderDto>> getAllOrders(HttpServletRequest request) {        // 创建一个新的 Span 并设置 Span 名称为 "GET /api/orders"        var span = tracer.spanBuilder("GET /api/orders").startSpan();        // 将 Span 注入到上下文中        try (var scope = span.makeCurrent()) {            // 从拦截器中获取用户信息            User user = (User) request.getAttribute("user");            // 要根据 orderDate 倒序排列            List<Order> orders = orderRepository.findByUserIdOrderByOrderDateDesc(user.getId());            // 将Order转换为OrderDto            List<OrderDto> orderDtos = orders.stream().map(order -> {                try {                    return order.toOrderDto(webClient);                } catch (Exception e) {                    throw new RuntimeException(e);                }            }).collect(Collectors.toList());            span.setAttribute("user_id", user.getId());            span.setAttribute("order_count", orders.size());            return new ResponseEntity<>(orderDtos, HttpStatus.OK);        } catch (Exception e) {            // 记录 Span 错误            span.recordException(e).setStatus(StatusCode.ERROR, e.getMessage());            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);        } finally {            // 记录 Span 结束时间            span.end();        }    }    // 忽略其他......}


推荐阅读