目录
[二、创建 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 的官方下载地址可以通过以下渠道获取:
-
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 -
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 参数配置(适合本地测试)
- 先打包 Spring Boot 项目:
bash
mvn clean package -DskipTests
- 生成的 JAR 路径:
target/otel-spring-demo-0.0.1-SNAPSHOT.jar
- 启动命令(指定 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
-
参数说明:
-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_
- 点
.
改为下划线_
- 全大写字母
- 配置环境变量(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"
- 启动应用(无需重复传
-D
参数):
bash
java -javaagent:/path/to/opentelemetry-javaagent.jar -jar target/otel-spring-demo-0.0.1-SNAPSHOT.jar
- 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"]
五、验证效果
-
启动应用后,访问接口:
http://localhost:8080/order/123
-
查看控制台日志,会看到类似输出(包含
trace_id
和span_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
-
若配置了
otel.exporter.otlp.endpoint
指向追踪系统(如 Jaeger),可在 UI 中看到完整的调用链路:- HTTP 请求 -> Controller -> Service -> 模拟的 DB 调用(自动生成的 Span)
六、关键注意事项
- 版本兼容性:Agent 版本需与 Spring Boot 版本兼容(官方推荐 Agent 版本 ≥ 1.20.0 支持 Spring Boot 3.x)。
- 自动追踪范围:Agent 会自动追踪常见组件(Spring MVC、JDBC、Redis、Kafka 等),无需代码侵入。
- 自定义追踪 :若需手动创建 Span(如业务埋点),需引入
opentelemetry-api
依赖(见前文示例)。 - 调试技巧 :通过
-Dotel.javaagent.debug=true
开启 Agent 调试日志,排查配置问题。
通过以上步骤,即可实现 Spring Boot 项目的无侵入式可观测性,无需修改业务代码即可收集追踪数据。