OpenTelemetry 通过自动埋点(Java Agent) 应用于springboot项目

目录

一、准备工作

[二、创建 Spring Boot 示例项目](#二、创建 Spring Boot 示例项目)

[1. 项目结构(Maven)](#1. 项目结构(Maven))

[2. 示例代码](#2. 示例代码)

[三、配置日志输出 Trace ID(可选但推荐)](#三、配置日志输出 Trace ID(可选但推荐))

[四、启动应用并配置 OpenTelemetry Agent](#四、启动应用并配置 OpenTelemetry Agent)

[方式 1:通过 JVM 参数配置(适合本地测试)](#方式 1:通过 JVM 参数配置(适合本地测试))

[方式 2:通过环境变量配置(适合容器 / K8s)](#方式 2:通过环境变量配置(适合容器 / K8s))

五、验证效果

六、关键注意事项


一、准备工作

OpenTelemetry Java Agent 是一个独立的 JAR 文件,无需集成到项目代码中,只需在启动时通过 JVM 参数指定即可。

下载地址

OpenTelemetry Java Agent 的官方下载地址可以通过以下渠道获取:

  1. GitHub Releases 页面(推荐)

    官方发布地址:
    https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases

    在该页面中,找到最新版本(通常是页面顶部的版本),下载名为 opentelemetry-javaagent.jar 的文件即可。

    例如,对于版本 v1.32.0,直接下载链接为:
    https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.32.0/opentelemetry-javaagent.jar

  2. Maven 中央仓库

    也可以从 Maven 中央仓库下载特定版本,地址格式为:
    Central Repository: io/opentelemetry/javaagent/opentelemetry-javaagent{版本号}/opentelemetry-javaagent-{版本号}.jar

    例如,版本 1.32.0 的下载地址:
    https://repo1.maven.org/maven2/io/opentelemetry/javaagent/opentelemetry-javaagent/1.32.0/opentelemetry-javaagent-1.32.0.jar

  • 也可通过命令行下载(以 v1.32.0 为例):
bash 复制代码
# Linux/macOS
curl -L https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.32.0/opentelemetry-javaagent.jar -o opentelemetry-javaagent.jar

# Windows (PowerShell)
Invoke-WebRequest -Uri https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.32.0/opentelemetry-javaagent.jar -OutFile opentelemetry-javaagent.jar

二、创建 Spring Boot 示例项目

为了演示,我们先创建一个简单的 Spring Boot 项目,包含一个 REST 接口用于测试追踪效果。

1. 项目结构(Maven)

pom.xml 依赖(无需添加 OpenTelemetry 相关依赖):

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
        <relativePath/>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>otel-spring-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>otel-spring-demo</name>
    <description>Demo project for OpenTelemetry Java Agent</description>
    
    <dependencies>
        <!-- 仅需 Spring Web 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 日志依赖(可选,用于输出 Trace ID) -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

如果项目中已包含 Lombok(支持 @Slf4j)和日志框架(以 Logback 为例,OpenTelemetry 对其支持最佳):

XML 复制代码
<!-- Lombok(提供 @Slf4j 注解) -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

<!-- Logback(日志框架,默认已包含在 spring-boot-starter-web 中) -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
</dependency>

<!-- OpenTelemetry 日志适配器(关键:将 trace_id 注入日志上下文) -->
<dependency>
    <groupId>io.opentelemetry.instrumentation</groupId>
    <artifactId>opentelemetry-logback-mdc-1.0</artifactId>
    <version>1.32.0</version> <!-- 版本需与 Agent 一致 -->
</dependency>
2. 示例代码

创建一个简单的 Controller 和 Service:

java 复制代码
// src/main/java/com/example/otel/controller/OrderController.java
package com.example.otel.controller;

import com.example.otel.service.OrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class OrderController {
    private static final Logger log = LoggerFactory.getLogger(OrderController.class);
    
    @Autowired
    private OrderService orderService;

    @GetMapping("/order/{id}")
    public String getOrder(@PathVariable Long id) {
        log.info("Received request for order: {}", id);
        return orderService.getOrderDetails(id);
    }
}
java 复制代码
// src/main/java/com/example/otel/service/OrderService.java
package com.example.otel.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class OrderService {
    private static final Logger log = LoggerFactory.getLogger(OrderService.class);

    public String getOrderDetails(Long orderId) {
        log.info("Processing order: {}", orderId);
        // 模拟数据库操作(Agent 会自动追踪 JDBC 调用,此处简化)
        simulateDbCall(orderId);
        return "Order details for ID: " + orderId;
    }

    private void simulateDbCall(Long orderId) {
        try {
            // 模拟数据库查询延迟
            Thread.sleep(100);
            log.info("Fetched data for order: {} from DB", orderId);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}
java 复制代码
// src/main/java/com/example/otel/OtelSpringDemoApplication.java
package com.example.otel;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class OtelSpringDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(OtelSpringDemoApplication.class, args);
    }
}

三、配置日志输出 Trace ID(可选但推荐)

为了在日志中看到追踪信息(Trace ID/Span ID),需配置日志格式。创建 src/main/resources/logback-spring.xml

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!-- 日志格式中添加 Trace ID 和 Span ID -->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - [%X{trace_id}/%X{span_id}] %msg%n</pattern>
        </encoder>
    </appender>
    
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
    </root>
</configuration>

或者

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 引入 OpenTelemetry 日志适配器(关键步骤) -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="net.logstash.logback.encoder.LogstashEncoder">
            <!-- 普通文本格式(推荐) -->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - [%X{trace_id}/%X{span_id}] %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 若使用 JSON 格式日志(可选) -->
    <!--
    <appender name="JSON_CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="net.logstash.logback.encoder.LogstashEncoder">
            <includeMdcKeyName>trace_id</includeMdcKeyName>
            <includeMdcKeyName>span_id</includeMdcKeyName>
        </encoder>
    </appender>
    -->

    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <!-- 若启用 JSON 格式,替换为 JSON_CONSOLE -->
        <!-- <appender-ref ref="JSON_CONSOLE" /> -->
    </root>
</configuration>

说明%X{trace_id}%X{span_id} 会从 MDC 中获取 OpenTelemetry 注入的追踪信息,无需额外代码。

四、启动应用并配置 OpenTelemetry Agent

方式 1:通过 JVM 参数配置(适合本地测试)
  1. 先打包 Spring Boot 项目:
bash 复制代码
mvn clean package -DskipTests
  • 生成的 JAR 路径:target/otel-spring-demo-0.0.1-SNAPSHOT.jar
  1. 启动命令(指定 Agent 和配置参数):
bash 复制代码
java -javaagent:/path/to/opentelemetry-javaagent.jar \
  -Dotel.service.name=order-service \  # 服务名称(必填)
  -Dotel.exporter.otlp.endpoint=http://localhost:4317 \  # 数据导出地址(如 OpenTelemetry Collector)
  -Dotel.resource.attributes=env=dev,version=1.0.0 \  # 自定义标签
  -Dotel.traces.sampler=parentbased_always_on \  # 采样策略(全量采样)
  -jar target/otel-spring-demo-0.0.1-SNAPSHOT.jar
  1. 参数说明

    • -javaagent:指定 Agent JAR 路径(替换为实际下载路径)。
    • otel.service.name:服务名称(用于在追踪系统中标识服务)。
    • otel.exporter.otlp.endpoint:数据导出端点(通常指向 OpenTelemetry Collector 或直接指向 Jaeger/Zipkin 等)。
    • 若没有 Collector,可临时输出到控制台调试:-Dotel.exporter.otlp.protocol=console
方式 2:通过环境变量配置(适合容器 / K8s)

环境变量与 JVM 参数的对应规则:

  • 前缀 otel. 改为 OTEL_
  • . 改为下划线 _
  • 全大写字母
  1. 配置环境变量(Linux/macOS):
bash 复制代码
export OTEL_SERVICE_NAME="order-service"
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317"
export OTEL_RESOURCE_ATTRIBUTES="env=dev,version=1.0.0"
export OTEL_TRACES_SAMPLER="parentbased_always_on"
  1. 启动应用(无需重复传 -D 参数):
bash 复制代码
java -javaagent:/path/to/opentelemetry-javaagent.jar -jar target/otel-spring-demo-0.0.1-SNAPSHOT.jar
  1. Docker 容器示例(Dockerfile):
bash 复制代码
FROM openjdk:17-jdk-slim
WORKDIR /app

# 复制 Agent 和应用 JAR
COPY opentelemetry-javaagent.jar /app/agent.jar
COPY target/otel-spring-demo-0.0.1-SNAPSHOT.jar /app/app.jar

# 配置环境变量
ENV OTEL_SERVICE_NAME="order-service"
ENV OTEL_EXPORTER_OTLP_ENDPOINT="http://otel-collector:4317"
ENV OTEL_RESOURCE_ATTRIBUTES="env=prod,version=1.0.0"

# 启动命令
CMD ["java", "-javaagent:/app/agent.jar", "-jar", "/app/app.jar"]

五、验证效果

  1. 启动应用后,访问接口:http://localhost:8080/order/123

  2. 查看控制台日志,会看到类似输出(包含 trace_idspan_id):

    复制代码
    2024-01-01 10:00:00.123 [http-nio-8080-exec-1] INFO  c.e.o.controller.OrderController - [4f8d8a8f8d7e6b5c4a3b2c1d0e9f8a7b/1a2b3c4d5e6f7g8h] Received request for order: 123
    2024-01-01 10:00:00.234 [http-nio-8080-exec-1] INFO  c.e.o.service.OrderService - [4f8d8a8f8d7e6b5c4a3b2c1d0e9f8a7b/2b3c4d5e6f7g8h9i] Processing order: 123
  3. 若配置了 otel.exporter.otlp.endpoint 指向追踪系统(如 Jaeger),可在 UI 中看到完整的调用链路:

    • HTTP 请求 -> Controller -> Service -> 模拟的 DB 调用(自动生成的 Span)

六、关键注意事项

  1. 版本兼容性:Agent 版本需与 Spring Boot 版本兼容(官方推荐 Agent 版本 ≥ 1.20.0 支持 Spring Boot 3.x)。
  2. 自动追踪范围:Agent 会自动追踪常见组件(Spring MVC、JDBC、Redis、Kafka 等),无需代码侵入。
  3. 自定义追踪 :若需手动创建 Span(如业务埋点),需引入 opentelemetry-api 依赖(见前文示例)。
  4. 调试技巧 :通过 -Dotel.javaagent.debug=true 开启 Agent 调试日志,排查配置问题。

通过以上步骤,即可实现 Spring Boot 项目的无侵入式可观测性,无需修改业务代码即可收集追踪数据。

相关推荐
沙子迷了蜗牛眼22 分钟前
当展示列表使用 URL.createObjectURL 的创建临时图片、视频无法加载问题
java·前端·javascript·vue.js
ganshenml24 分钟前
【Android】 开发四角版本全解析:AS、AGP、Gradle 与 JDK 的配套关系
android·java·开发语言
我命由我1234525 分钟前
Kotlin 运算符 - == 运算符与 === 运算符
android·java·开发语言·java-ee·kotlin·android studio·android-studio
小途软件31 分钟前
ssm327校园二手交易平台的设计与实现+vue
java·人工智能·pytorch·python·深度学习·语言模型
alonewolf_9935 分钟前
Java类加载机制深度解析:从双亲委派到热加载实战
java·开发语言
追梦者12336 分钟前
springboot整合minio
java·spring boot·后端
云游39 分钟前
Jaspersoft Studio community edition 7.0.3的应用
java·报表
帅气的你1 小时前
Spring Boot 集成 AOP 实现日志记录与接口权限校验
java·spring boot
zhglhy1 小时前
Spring Data Slice使用指南
java·spring
win x1 小时前
Redis 主从复制
java·数据库·redis