Skip to content

Commit 956f31a

Browse files
gsmetmichalvavrik
authored andcommitted
Use a bean for telemetry wrapping to avoid making DataSources mutable
We had a hard time making it immutable so let's not break this contract. We had a lot of race conditions before doing so.
1 parent e81ba26 commit 956f31a

File tree

7 files changed

+31
-65
lines changed

7 files changed

+31
-65
lines changed

docs/src/main/asciidoc/opentelemetry.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ The https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/ma
243243
implementation("io.opentelemetry.instrumentation:opentelemetry-jdbc")
244244
----
245245

246-
As it uses a dedicated JDBC datasource wrapper, you must enable JDBC tracing for your datasource:
246+
As it uses a dedicated JDBC datasource wrapper, you must enable telemetry for your datasource:
247247

248248
[source, properties]
249249
----

extensions/agroal/deployment/src/main/java/io/quarkus/agroal/deployment/AgroalProcessor.java

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import io.agroal.api.AgroalDataSource;
2323
import io.agroal.api.AgroalPoolInterceptor;
2424
import io.quarkus.agroal.DataSource;
25-
import io.quarkus.agroal.runtime.AgroalOpenTelemetryRecorder;
2625
import io.quarkus.agroal.runtime.AgroalRecorder;
2726
import io.quarkus.agroal.runtime.DataSourceJdbcBuildTimeConfig;
2827
import io.quarkus.agroal.runtime.DataSourceSupport;
@@ -83,7 +82,7 @@ void build(
8382
Capabilities capabilities,
8483
BuildProducer<ExtensionSslNativeSupportBuildItem> sslNativeSupport,
8584
BuildProducer<AggregatedDataSourceBuildTimeConfigBuildItem> aggregatedConfig,
86-
BuildProducer<OpenTelemetryJDBCInstrumentationBuildItem> otelInstrumentationActiveProducer,
85+
BuildProducer<AdditionalBeanBuildItem> additionalBeans,
8786
CurateOutcomeBuildItem curateOutcomeBuildItem) throws Exception {
8887
if (dataSourcesBuildTimeConfig.driver.isPresent() || dataSourcesBuildTimeConfig.url.isPresent()) {
8988
throw new ConfigurationException(
@@ -111,7 +110,7 @@ void build(
111110
DataSources.TRACING_DRIVER_CLASSNAME));
112111
}
113112

114-
if (aggregatedDataSourceBuildTimeConfig.getJdbcConfig().telemetry && !otelJdbcInstrumentationActive) {
113+
if (aggregatedDataSourceBuildTimeConfig.getJdbcConfig().telemetry) {
115114
otelJdbcInstrumentationActive = true;
116115
}
117116

@@ -124,8 +123,10 @@ void build(
124123

125124
if (otelJdbcInstrumentationActive && capabilities.isPresent(OPENTELEMETRY_TRACER)) {
126125
// at least one datasource is using OpenTelemetry JDBC instrumentation,
127-
// therefore we need to prepare OpenTelemetry data source wrapper
128-
otelInstrumentationActiveProducer.produce(new OpenTelemetryJDBCInstrumentationBuildItem());
126+
// therefore we register the OpenTelemetry data source wrapper bean
127+
additionalBeans.produce(new AdditionalBeanBuildItem.Builder()
128+
.addBeanClass("io.quarkus.agroal.runtime.AgroalOpenTelemetryWrapper")
129+
.setDefaultScope(DotNames.SINGLETON).build());
129130
}
130131

131132
// For now, we can't push the security providers to Agroal so we need to include
@@ -216,8 +217,6 @@ void generateDataSourceSupportBean(AgroalRecorder recorder,
216217
List<AggregatedDataSourceBuildTimeConfigBuildItem> aggregatedBuildTimeConfigBuildItems,
217218
SslNativeConfigBuildItem sslNativeConfig,
218219
Capabilities capabilities,
219-
Optional<OpenTelemetryJDBCInstrumentationBuildItem> otelInstrumentationActive,
220-
AgroalOpenTelemetryRecorder agroalOpenTelemetryRecorder,
221220
BuildProducer<AdditionalBeanBuildItem> additionalBeans,
222221
BuildProducer<SyntheticBeanBuildItem> syntheticBeanBuildItemBuildProducer,
223222
BuildProducer<UnremovableBeanBuildItem> unremovableBeans) {
@@ -228,13 +227,6 @@ void generateDataSourceSupportBean(AgroalRecorder recorder,
228227
return;
229228
}
230229

231-
if (otelInstrumentationActive.isPresent()) {
232-
// prepare OpenTelemetry datasource wrapper
233-
// this code must only run when the OpenTelemetry is active
234-
// to avoid native failures
235-
agroalOpenTelemetryRecorder.prepareOpenTelemetryAgroalDatasource();
236-
}
237-
238230
// make a DataSourceProducer bean
239231
additionalBeans.produce(AdditionalBeanBuildItem.builder().addBeanClasses(DataSources.class).setUnremovable()
240232
.setDefaultScope(DotNames.SINGLETON).build());

extensions/agroal/deployment/src/main/java/io/quarkus/agroal/deployment/OpenTelemetryJDBCInstrumentationBuildItem.java

Lines changed: 0 additions & 9 deletions
This file was deleted.

extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/AgroalOpenTelemetryRecorder.java

Lines changed: 0 additions & 24 deletions
This file was deleted.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package io.quarkus.agroal.runtime;
2+
3+
import java.util.function.Function;
4+
5+
import io.agroal.api.AgroalDataSource;
6+
7+
public class AgroalOpenTelemetryWrapper implements Function<AgroalDataSource, AgroalDataSource> {
8+
9+
@Override
10+
public AgroalDataSource apply(AgroalDataSource originalDataSource) {
11+
return new OpenTelemetryAgroalDataSource(originalDataSource);
12+
}
13+
}

extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/DataSources.java

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import java.util.Collection;
88
import java.util.Iterator;
99
import java.util.Map;
10-
import java.util.Objects;
1110
import java.util.ServiceLoader;
1211
import java.util.concurrent.ConcurrentHashMap;
1312
import java.util.concurrent.ConcurrentMap;
@@ -69,7 +68,6 @@ public class DataSources {
6968
public static final String TRACING_DRIVER_CLASSNAME = "io.opentracing.contrib.jdbc.TracingDriver";
7069
private static final String JDBC_URL_PREFIX = "jdbc:";
7170
private static final String JDBC_TRACING_URL_PREFIX = "jdbc:tracing:";
72-
private static volatile Function<AgroalDataSource, AgroalDataSource> OTEL_DATASOURCE_TRANSFORMER = null;
7371

7472
private final DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig;
7573
private final DataSourcesRuntimeConfig dataSourcesRuntimeConfig;
@@ -81,6 +79,7 @@ public class DataSources {
8179
private final TransactionSynchronizationRegistry transactionSynchronizationRegistry;
8280
private final DataSourceSupport dataSourceSupport;
8381
private final Instance<AgroalPoolInterceptor> agroalPoolInterceptors;
82+
private final Instance<AgroalOpenTelemetryWrapper> agroalOpenTelemetryWrapper;
8483

8584
private final ConcurrentMap<String, AgroalDataSource> dataSources = new ConcurrentHashMap<>();
8685

@@ -90,8 +89,10 @@ public DataSources(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
9089
TransactionManagerConfiguration transactionRuntimeConfig,
9190
TransactionManager transactionManager,
9291
XAResourceRecoveryRegistry xaResourceRecoveryRegistry,
93-
TransactionSynchronizationRegistry transactionSynchronizationRegistry, DataSourceSupport dataSourceSupport,
94-
@Any Instance<AgroalPoolInterceptor> agroalPoolInterceptors) {
92+
TransactionSynchronizationRegistry transactionSynchronizationRegistry,
93+
DataSourceSupport dataSourceSupport,
94+
@Any Instance<AgroalPoolInterceptor> agroalPoolInterceptors,
95+
Instance<AgroalOpenTelemetryWrapper> agroalOpenTelemetryWrapper) {
9596
this.dataSourcesBuildTimeConfig = dataSourcesBuildTimeConfig;
9697
this.dataSourcesRuntimeConfig = dataSourcesRuntimeConfig;
9798
this.dataSourcesJdbcBuildTimeConfig = dataSourcesJdbcBuildTimeConfig;
@@ -102,6 +103,7 @@ public DataSources(DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
102103
this.transactionSynchronizationRegistry = transactionSynchronizationRegistry;
103104
this.dataSourceSupport = dataSourceSupport;
104105
this.agroalPoolInterceptors = agroalPoolInterceptors;
106+
this.agroalOpenTelemetryWrapper = agroalOpenTelemetryWrapper;
105107
}
106108

107109
/**
@@ -129,6 +131,7 @@ public AgroalDataSource apply(String s) {
129131
});
130132
}
131133

134+
@SuppressWarnings("resource")
132135
public AgroalDataSource doCreateDataSource(String dataSourceName) {
133136
if (!dataSourceSupport.entries.containsKey(dataSourceName)) {
134137
throw new IllegalArgumentException("No datasource named '" + dataSourceName + "' exists");
@@ -255,9 +258,9 @@ public AgroalDataSource doCreateDataSource(String dataSourceName) {
255258
}
256259

257260
if (dataSourceJdbcBuildTimeConfig.telemetry && dataSourceJdbcRuntimeConfig.telemetry.orElse(true)) {
258-
// active OpenTelemetry JDBC instrumentation by wrapping AgroalDatasource
259-
// use the transformer as we can't reference optional OpenTelemetry classes here
260-
dataSource = OTEL_DATASOURCE_TRANSFORMER.apply(dataSource);
261+
// activate OpenTelemetry JDBC instrumentation by wrapping AgroalDatasource
262+
// use an optional CDI bean as we can't reference optional OpenTelemetry classes here
263+
dataSource = agroalOpenTelemetryWrapper.get().apply(dataSource);
261264
}
262265

263266
return dataSource;
@@ -452,13 +455,4 @@ public void stop() {
452455
}
453456
}
454457
}
455-
456-
/**
457-
* Set a function that will wrap {@link AgroalDataSource} with the OpenTelemetry datasource.
458-
*/
459-
static void setOpenTelemetryDatasourceTransformer(Function<AgroalDataSource, AgroalDataSource> otelDatasourceTransformer) {
460-
Objects.requireNonNull(otelDatasourceTransformer);
461-
OTEL_DATASOURCE_TRANSFORMER = otelDatasourceTransformer;
462-
}
463-
464458
}

extensions/agroal/runtime/src/main/java/io/quarkus/agroal/runtime/OpenTelemetryAgroalDataSource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import io.opentelemetry.instrumentation.jdbc.datasource.OpenTelemetryDataSource;
1414

1515
/**
16-
* The {@link AgroalDataSource} wrapper that actives OpenTelemetry JDBC instrumentation.
16+
* The {@link AgroalDataSource} wrapper that activates OpenTelemetry JDBC instrumentation.
1717
*/
1818
public class OpenTelemetryAgroalDataSource extends OpenTelemetryDataSource implements AgroalDataSource {
1919

0 commit comments

Comments
 (0)