OpenTelemetry 是一套 API、库、代理和检测工具,用于提供应用程序及其相互交互的可观察性。它使开发人员能够检测其代码,以便他们可以导出可观察性数据,包括跟踪、指标和日志,从而提高分析、调试和测试的粒度。
OpenTelemetry 项目为 JDBC 库提供了自动检测功能。但是,在分布式跟踪方面,自动检测无法将上下文传播到数据库层,导致跟踪链断裂。此外,自动检测仅适用于 JDBC 检测的可见层,而排除了值得跟踪的任何内部操作。
MySQL Enterprise Server 8.4.0 具有以 OpenTelemetry 格式收集服务器操作可观察性数据的功能(有关详细信息,请参阅 遥测)。该功能由 component_telemetry 支持。MySQL Connector/J 8.4.0 引入了客户端对应功能,它能够将上下文传播到其连接到的 MySQL 服务器,并允许对应用程序堆栈进行更完整的可观察性。
使用 Connector/J 的应用程序如果希望启用 OpenTelemetry 跟踪,需要以下第三方库
如果您选择手动检测,则需要 opentelemetry-sdk 库,或者如果您更喜欢自动检测,则需要 opentelemetry-javaagent。
Connector/J 连接属性 openTelemetry 控制如何在每个连接的基础上处理可观察性数据生成。此选项接受以下值
REQUIRED
:运行时必须有 OpenTelemetry 库可用,否则连接到 MySQL 服务器将失败。请注意,仅opentelemtry-api
库不会生成任何输出跟踪。PREFERRED
:启用生成 OpenTelemetry 检测,前提是在运行时有 OpenTelemetry 库可用;如果库不可用,则会发出警告。DISABLED
:关闭 Connector/J 生成 OpenTelemetry 检测。但是,这不会阻止外部检测方式,例如 OpenTelemetry Java 代理提供的自动检测。
未设置该属性的值等同于将其设置为 PREFERRED
,只是在运行时没有 OpenTelemetry 库可用时不会发出警告。
请注意,MySQL Connector/J 不提供任何配置其自身 OpenTelemetry 导出程序的方法,它完全依赖于调用应用程序进行导出程序配置。
以下是关于如何使用 OpenTelemetry 的演示。假设客户端应用程序、MySQL 服务器和可观察性后端都在同一台机器上运行。还假设 component_telemetry 已启用并在 MySQL 服务器上正确配置。为了简单起见,使用 Java 代理。还使用了 opentelemetry-instrumentation-annotations 库,因此无需在示例类中编写任何 OpenTelemetry 代码。
这个简单的演示包含一个类 OTelDemo
,它创建一个连接到 Sakila 数据库 并执行一个 SQL SELECT
语句,该语句从 film
表中返回五行。该演示的目的是生成一系列跟踪,而不是生成任何实际有用的内容。以下是源文件 src/demo/OTelDemo.java
的内容
package demo;
import java.sql.*;
import io.opentelemetry.instrumentation.annotations.WithSpan;
public class OTelDemo {
public static void main(String[] args) throws Exception {
listFiveFilms();
}
@WithSpan
private static void listFiveFilms() throws Exception {
try (Connection conn = DriverManager.getConnection("jdbc:mysql://johndoe:s3cr3t@localhost:3306/sakila")) {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM film LIMIT 5");
while (rs.next()) {
System.out.println(rs.getString(2));
}
}
}
}
通过注释 @WithSpan
,将在应用程序代码中创建将观察到的顶级跟踪。此跟踪成为 JDBC 驱动程序中创建的任何后续跨度的当前上下文(父级)。随后,通过与执行的命令一起传播上下文,驱动程序创建的跟踪成为 MySQL 服务器中创建的跨度的父级。
可以通过发出以下命令来编译代码
$ javac -classpath "lib/*" -d bin src/demo/OTelDemo.java
在运行演示之前,请使用例如 Jaeger 设置可观察性后端。然后,您可以使用以下命令执行代码
$ java -javaagent:agent/opentelemetry-javaagent.jar \
-Dotel.traces.exporter=jaeger \
-Dotel.metrics.exporter=none \
-Dotel.service.name=OTelDemo \
-Dotel.instrumentation.common.default-enabled=false \
-Dotel.instrumentation.opentelemetry-api.enabled=true \
-Dotel.instrumentation.opentelemetry-instrumentation-annotations.enabled=true \
-classpath "bin:lib/*" \
demo.OTelDemo
[otel.javaagent 2024-04-12 16:10:32:140 +0100]
[main] INFO io.opentelemetry.javaagent.tooling.VersionLogger - opentelemetry-javaagent - version: 1.32.0
ACADEMY DINOSAUR
ACE GOLDFINGER
ADAPTATION HOLES
AFFAIR PREJUDICE
AFRICAN EGG
现在,您可以在 Web 浏览器中打开 Jaeger 后端,并搜索 OTelDemo
服务的跟踪。
MySQL 中的分布式跟踪仅限于语句执行。此限制来自以下事实:上下文传播是通过 查询属性 实现的,并且仅支持查询执行。在运行时,服务器也会为其他操作生成跨度。这些跨度也可以在可观察性后端中看到,但它们与客户端应用程序或库启动的任何跟踪都没有关联。同样,Connector/J 创建的跨度,不会生成服务器命令,或者生成不支持查询属性的命令,在跟踪图中显示为终端节点。例如,PING
命令操作。尽管如此,服务器仍然会为相应操作生成一个跨度,只是它看起来与源跟踪没有关联。然而,服务器仍然会为相应操作生成一个跨度,只是它看起来与源跟踪没有关联。