如何在Quarkus中编程定义数据源并对接OpenTelemetry?
解决方案
方案1:使用Quarkus官方OTel JDBC集成(推荐)
Quarkus已经内置了OpenTelemetry对JDBC数据源的自动集成能力,不需要手动包装DataSource或者修改JDBC URL:
- 首先在项目依赖中引入
quarkus-opentelemetry和quarkus-opentelemetry-jdbc扩展 - 确认配置项开启(默认已开启):
quarkus.opentelemetry.enabled=true quarkus.opentelemetry.instrumentation.jdbc.enabled=true
配置完成后Quarkus启动时会自动包装内置的Agroal数据源,自动采集JDBC相关的指标和链路数据,无需额外代码修改。
方案2:修复手动配置jdbc:otel前缀的NPE问题
你遇到的空指针异常是因为Flyway在应用启动早期执行数据库迁移时,Quarkus的OpenTelemetry上下文存储还未完成初始化,Vertx上下文不存在导致的。可以通过给Flyway单独配置原始JDBC URL解决:
# 业务数据源使用otel前缀 quarkus.datasource.jdbc.url=jdbc:otel:postgresql://localhost:5432/my_db # Flyway迁移使用原始JDBC地址,避开启动阶段OTel未初始化的问题 quarkus.flyway.jdbc.url=jdbc:postgresql://localhost:5432/my_db
方案3:手动编程覆写数据源
如果确实需要自行通过代码包装数据源,可以通过CDI生产者自定义DataSource Bean覆盖默认实例,参考代码如下:
import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.instrumentation.jdbc.datasource.OpenTelemetryDataSource; import jakarta.enterprise.inject.Produces; import jakarta.inject.Inject; import jakarta.inject.Singleton; import javax.sql.DataSource; import io.quarkus.arc.DefaultBean; import io.quarkus.arc.Priority; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class CustomDataSourceProducer { @Inject OpenTelemetry openTelemetry; @Inject @DefaultBean DataSource rawDataSource; @Produces @Singleton @Priority(1) public DataSource wrappedDataSource() { return new OpenTelemetryDataSource(rawDataSource, openTelemetry); } }
如果是多数据源场景,为每个数据源添加对应的@Named注解分别处理即可。
内容的提问来源于stack exchange,提问作者Sasha Shpota
相关产品推荐
相关产品推荐

