Skip to content

Commit

Permalink
Merge pull request #45359 from brunobat/disable-jdbc-span
Browse files Browse the repository at this point in the history
Ensure there are no jdbc spans if otel sdk is disabled
  • Loading branch information
gsmet authored Jan 23, 2025
2 parents 1755671 + a978058 commit e38b5d9
Show file tree
Hide file tree
Showing 19 changed files with 213 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.quarkus.agroal.deployment;

import static io.quarkus.agroal.deployment.AgroalDataSourceBuildUtil.qualifiers;
import static io.quarkus.arc.deployment.OpenTelemetrySdkBuildItem.isOtelSdkEnabled;
import static io.quarkus.deployment.Capability.OPENTELEMETRY_TRACER;

import java.sql.Driver;
Expand All @@ -26,6 +27,7 @@
import io.agroal.api.AgroalPoolInterceptor;
import io.quarkus.agroal.DataSource;
import io.quarkus.agroal.runtime.AgroalDataSourceSupport;
import io.quarkus.agroal.runtime.AgroalOpenTelemetryWrapper;
import io.quarkus.agroal.runtime.AgroalRecorder;
import io.quarkus.agroal.runtime.DataSourceJdbcBuildTimeConfig;
import io.quarkus.agroal.runtime.DataSources;
Expand All @@ -34,9 +36,9 @@
import io.quarkus.agroal.runtime.TransactionIntegration;
import io.quarkus.agroal.spi.JdbcDataSourceBuildItem;
import io.quarkus.agroal.spi.JdbcDriverBuildItem;
import io.quarkus.agroal.spi.OpenTelemetryInitBuildItem;
import io.quarkus.arc.BeanDestroyer;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.OpenTelemetrySdkBuildItem;
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
import io.quarkus.arc.deployment.UnremovableBeanBuildItem;
import io.quarkus.arc.processor.DotNames;
Expand Down Expand Up @@ -127,7 +129,7 @@ void build(
// at least one datasource is using OpenTelemetry JDBC instrumentation,
// therefore we register the OpenTelemetry data source wrapper bean
additionalBeans.produce(new AdditionalBeanBuildItem.Builder()
.addBeanClass("io.quarkus.agroal.runtime.AgroalOpenTelemetryWrapper")
.addBeanClass(AgroalOpenTelemetryWrapper.class)
.setDefaultScope(DotNames.SINGLETON).build());
}

Expand Down Expand Up @@ -244,13 +246,13 @@ void generateDataSourceSupportBean(AgroalRecorder recorder,

@Record(ExecutionTime.RUNTIME_INIT)
@BuildStep
@Consume(OpenTelemetryInitBuildItem.class)
@Consume(NarayanaInitBuildItem.class)
void generateDataSourceBeans(AgroalRecorder recorder,
DataSourcesRuntimeConfig dataSourcesRuntimeConfig,
List<AggregatedDataSourceBuildTimeConfigBuildItem> aggregatedBuildTimeConfigBuildItems,
SslNativeConfigBuildItem sslNativeConfig,
Capabilities capabilities,
Optional<OpenTelemetrySdkBuildItem> openTelemetrySdkBuildItem,
BuildProducer<SyntheticBeanBuildItem> syntheticBeanBuildItemBuildProducer,
BuildProducer<JdbcDataSourceBuildItem> jdbcDataSource) {
if (aggregatedBuildTimeConfigBuildItems.isEmpty()) {
Expand All @@ -275,7 +277,8 @@ void generateDataSourceBeans(AgroalRecorder recorder,
.checkActive(recorder.agroalDataSourceCheckActiveSupplier(dataSourceName))
// pass the runtime config into the recorder to ensure that the DataSource related beans
// are created after runtime configuration has been set up
.createWith(recorder.agroalDataSourceSupplier(dataSourceName, dataSourcesRuntimeConfig))
.createWith(recorder.agroalDataSourceSupplier(
dataSourceName, dataSourcesRuntimeConfig, isOtelSdkEnabled(openTelemetrySdkBuildItem)))
.destroyer(BeanDestroyer.AutoCloseableDestroyer.class);

if (!DataSourceUtil.isDefault(dataSourceName)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,15 @@ public ActiveResult get() {

public Function<SyntheticCreationalContext<AgroalDataSource>, AgroalDataSource> agroalDataSourceSupplier(
String dataSourceName,
@SuppressWarnings("unused") DataSourcesRuntimeConfig dataSourcesRuntimeConfig) {
@SuppressWarnings("unused") DataSourcesRuntimeConfig dataSourcesRuntimeConfig,
Optional<RuntimeValue<Boolean>> otelEnabled) {
return new Function<>() {
@SuppressWarnings("deprecation")
@Override
public AgroalDataSource apply(SyntheticCreationalContext<AgroalDataSource> context) {
DataSources dataSources = context.getInjectedReference(DataSources.class);
return dataSources.createDataSource(dataSourceName);
return dataSources.createDataSource(dataSourceName,
otelEnabled.isPresent() ? otelEnabled.get().getValue() : false);
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public AgroalDataSource getDataSource(String dataSourceName) {
}

@SuppressWarnings("resource")
public AgroalDataSource createDataSource(String dataSourceName) {
public AgroalDataSource createDataSource(String dataSourceName, boolean otelEnabled) {
if (!agroalDataSourceSupport.entries.containsKey(dataSourceName)) {
throw new IllegalArgumentException("No datasource named '" + dataSourceName + "' exists");
}
Expand Down Expand Up @@ -221,7 +221,9 @@ public AgroalDataSource createDataSource(String dataSourceName) {
dataSource.setPoolInterceptors(interceptorList);
}

if (dataSourceJdbcBuildTimeConfig.telemetry() && dataSourceJdbcRuntimeConfig.telemetry().orElse(true)) {
if (dataSourceJdbcBuildTimeConfig.telemetry() &&
dataSourceJdbcRuntimeConfig.telemetry().orElse(true) &&
otelEnabled) {
// activate OpenTelemetry JDBC instrumentation by wrapping AgroalDatasource
// use an optional CDI bean as we can't reference optional OpenTelemetry classes here
dataSource = agroalOpenTelemetryWrapper.get().apply(dataSource);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.quarkus.arc.deployment;

import java.util.Optional;

import io.quarkus.builder.item.SimpleBuildItem;
import io.quarkus.runtime.RuntimeValue;

public final class OpenTelemetrySdkBuildItem extends SimpleBuildItem {

private final RuntimeValue<Boolean> runtimeEnabled;

public OpenTelemetrySdkBuildItem(RuntimeValue<Boolean> sdkEnabled) {
this.runtimeEnabled = sdkEnabled;
}

/**
* True if the OpenTelemetry SDK is enabled at build and runtime.
*/
public RuntimeValue<Boolean> isRuntimeEnabled() {
return runtimeEnabled;
}

public static Optional<RuntimeValue<Boolean>> isOtelSdkEnabled(Optional<OpenTelemetrySdkBuildItem> buildItem) {
// optional is empty if the extension is disabled at build time
return buildItem.isPresent() ? Optional.of(buildItem.get().isRuntimeEnabled()) : Optional.empty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@
import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSamplerProvider;
import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider;
import io.quarkus.agroal.spi.JdbcDataSourceBuildItem;
import io.quarkus.agroal.spi.OpenTelemetryInitBuildItem;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.AnnotationsTransformerBuildItem;
import io.quarkus.arc.deployment.BeanContainerBuildItem;
import io.quarkus.arc.deployment.InterceptorBindingRegistrarBuildItem;
import io.quarkus.arc.deployment.OpenTelemetrySdkBuildItem;
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
import io.quarkus.arc.deployment.ValidationPhaseBuildItem.ValidationErrorBuildItem;
import io.quarkus.arc.processor.InterceptorBindingRegistrar;
Expand All @@ -52,7 +52,6 @@
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.BuildSteps;
import io.quarkus.deployment.annotations.ExecutionTime;
import io.quarkus.deployment.annotations.Produce;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
import io.quarkus.deployment.builditem.RemovedResourceBuildItem;
Expand Down Expand Up @@ -107,8 +106,11 @@ AdditionalBeanBuildItem ensureProducerIsRetained() {

@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
SyntheticBeanBuildItem openTelemetryBean(OpenTelemetryRecorder recorder, OTelRuntimeConfig oTelRuntimeConfig) {
return SyntheticBeanBuildItem.configure(OpenTelemetry.class)
void openTelemetryBean(OpenTelemetryRecorder recorder,
OTelRuntimeConfig oTelRuntimeConfig,
BuildProducer<SyntheticBeanBuildItem> syntheticProducer,
BuildProducer<OpenTelemetrySdkBuildItem> openTelemetrySdkBuildItemBuildProducer) {
syntheticProducer.produce(SyntheticBeanBuildItem.configure(OpenTelemetry.class)
.defaultBean()
.setRuntimeInit()
.unremovable()
Expand All @@ -122,7 +124,10 @@ SyntheticBeanBuildItem openTelemetryBean(OpenTelemetryRecorder recorder, OTelRun
null))
.createWith(recorder.opentelemetryBean(oTelRuntimeConfig))
.destroyer(OpenTelemetryDestroyer.class)
.done();
.done());

openTelemetrySdkBuildItemBuildProducer.produce(
new OpenTelemetrySdkBuildItem(recorder.isOtelSdkEnabled(oTelRuntimeConfig)));
}

@BuildStep
Expand Down Expand Up @@ -258,7 +263,6 @@ void transformWithSpan(BuildProducer<AnnotationsTransformerBuildItem> annotation

@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
@Produce(OpenTelemetryInitBuildItem.class)
void createOpenTelemetry(
OpenTelemetryRecorder recorder,
CoreVertxBuildItem vertx,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
import io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider;
import io.opentelemetry.sdk.logs.LogRecordProcessor;
import io.opentelemetry.sdk.logs.export.LogRecordExporter;
import io.quarkus.agroal.spi.OpenTelemetryInitBuildItem;
import io.quarkus.arc.deployment.BeanContainerBuildItem;
import io.quarkus.arc.deployment.OpenTelemetrySdkBuildItem;
import io.quarkus.arc.deployment.UnremovableBeanBuildItem;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
Expand Down Expand Up @@ -45,7 +45,7 @@ void nativeSupport(BuildProducer<ServiceProviderBuildItem> servicesProducer) {

@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
@Consume(OpenTelemetryInitBuildItem.class)
@Consume(OpenTelemetrySdkBuildItem.class)
LogHandlerBuildItem build(OpenTelemetryLogRecorder recorder,
OTelRuntimeConfig config,
BeanContainerBuildItem beanContainerBuildItem) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import io.quarkus.arc.SyntheticCreationalContext;
import io.quarkus.opentelemetry.runtime.config.runtime.OTelRuntimeConfig;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.annotations.Recorder;
import io.quarkus.runtime.annotations.RuntimeInit;
import io.quarkus.runtime.annotations.StaticInit;
Expand All @@ -38,6 +39,11 @@ public void resetGlobalOpenTelemetryForDevMode() {
GlobalEventLoggerProvider.resetForTest();
}

@RuntimeInit
public RuntimeValue<Boolean> isOtelSdkEnabled(OTelRuntimeConfig oTelRuntimeConfig) {
return new RuntimeValue<>(!oTelRuntimeConfig.sdkDisabled());
}

@RuntimeInit
public void eagerlyCreateContextStorage() {
ContextStorage.get();
Expand Down
17 changes: 17 additions & 0 deletions integration-tests/opentelemetry-jdbc-instrumentation/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm-panache</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2</artifactId>
</dependency>

<!-- Test Dependencies -->
<dependency>
Expand Down Expand Up @@ -215,6 +219,19 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>

</dependencies>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import io.quarkus.it.opentelemetry.model.Hit;
import io.quarkus.it.opentelemetry.model.db2.Db2Hit;
import io.quarkus.it.opentelemetry.model.h2.H2Hit;
import io.quarkus.it.opentelemetry.model.mariadb.MariaDbHit;
import io.quarkus.it.opentelemetry.model.oracle.OracleHit;
import io.quarkus.it.opentelemetry.model.pg.PgHit;
Expand All @@ -39,6 +40,9 @@ public Hit createHit(@QueryParam("id") Long id, @PathParam("tenant") String tena
case "db2":
persist(Db2Hit::new, id);
return Db2Hit.findById(id);
case "h2":
persist(H2Hit::new, id);
return H2Hit.findById(id);
default:
throw new IllegalArgumentException();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.quarkus.it.opentelemetry.model.h2;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;

import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
import io.quarkus.it.opentelemetry.model.Hit;

@Entity
public class H2Hit extends PanacheEntityBase implements Hit {

@Id
public Long id;

public String message;

@Override
public Long getId() {
return id;
}

@Override
public String getMessage() {
return message;
}

@Override
public void setId(Long id) {
this.id = id;
}

@Override
public void setMessage(String message) {
this.message = message;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ quarkus.datasource.db2.db-kind=db2
quarkus.datasource.db2.jdbc.max-size=1
quarkus.datasource.db2.jdbc.telemetry=true

# H2 data source
quarkus.hibernate-orm.h2.datasource=h2
quarkus.hibernate-orm.h2.packages=${model-base-dir}h2
quarkus.hibernate-orm.h2.database.generation=none
quarkus.datasource.h2.db-kind=h2
quarkus.datasource.h2.jdbc.max-size=1
quarkus.datasource.h2.jdbc.telemetry=true

# speed up build
quarkus.otel.bsp.schedule.delay=100
quarkus.otel.bsp.export.timeout=5s
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public Map<String, String> start() {
properties.put("quarkus.hibernate-orm.oracle.active", "false");
properties.put("quarkus.hibernate-orm.postgresql.active", "false");
properties.put("quarkus.hibernate-orm.mariadb.active", "false");
properties.put("quarkus.hibernate-orm.h2.active", "false");

return properties;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package io.quarkus.it.opentelemetry;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import org.h2.tools.Server;

import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;

public class H2DatabaseTestResource implements QuarkusTestResourceLifecycleManager {

public static final String QUARKUS_OTEL_SDK_DISABLED = "quarkus.otel.sdk.disabled";
private Server tcpServer;
private Map<String, String> initProperties;

@Override
public void init(Map<String, String> initArgs) {
initProperties = initArgs;
}

@Override
public Map<String, String> start() {

try {
tcpServer = Server.createTcpServer("-ifNotExists");
tcpServer.start();
System.out.println("[INFO] H2 database started in TCP server mode; server status: " + tcpServer.getStatus());
} catch (SQLException e) {
throw new RuntimeException(e);
}

Map<String, String> properties = new HashMap<>(initProperties);
properties.put("quarkus.datasource.h2.jdbc.url", "jdbc:h2:tcp://localhost/mem:test");
properties.put("quarkus.hibernate-orm.h2.database.generation", "drop-and-create");
properties.put("quarkus.hibernate-orm.postgresql.active", "false");
properties.put("quarkus.hibernate-orm.oracle.active", "false");
properties.put("quarkus.hibernate-orm.mariadb.active", "false");
properties.put("quarkus.hibernate-orm.db2.active", "false");

return properties;
}

@Override
public synchronized void stop() {
if (tcpServer != null) {
tcpServer.stop();
System.out.println("[INFO] H2 database was shut down; server status: " + tcpServer.getStatus());
tcpServer = null;
}
}
}
Loading

0 comments on commit e38b5d9

Please sign in to comment.