Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Mongodb otel refactor #40472

Closed
wants to merge 14 commits into from
12 changes: 12 additions & 0 deletions docs/src/main/asciidoc/mongodb.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,18 @@ This behavior must first be enabled by setting the `quarkus.mongodb.metrics.enab
So when you access the `/q/metrics` endpoint of your application you will have information about the connection pool status.
When using xref:smallrye-metrics.adoc[SmallRye Metrics], connection pool metrics will be available under the `vendor` scope.


== Tracing

To use tracing with mongo, you need to add the xref:opentelemetry.adoc[`quarkus-opentelemetry`] extension to your project.

Even with all the tracing infrastructure in place the mongodb tracing is not enabled by default, and you need to enable it by setting this property:
[source, properties]
----
# enable tracing
quarkus.mongodb.tracing.enabled=true
----

== Testing helpers

xref:#dev-services[Dev Services for MongoDB] is your best option to start a MongoDB database for your unit tests.
Expand Down
1 change: 1 addition & 0 deletions docs/src/main/asciidoc/opentelemetry.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,7 @@ Additional exporters will be available in the Quarkiverse https://docs.quarkiver
* https://quarkus.io/guides/scheduler[`quarkus-scheduler`]
* https://quarkus.io/guides/smallrye-graphql[`quarkus-smallrye-graphql`]
* https://quarkus.io/extensions/io.quarkus/quarkus-messaging[`quarkus-messaging`]
* https://quarkus.io/extensions/io.quarkus/quarkus-mongodb-client[`quarkus-mongodb-client`]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In needs to be inserted above quarkus-messaging

** AMQP 1.0
** RabbitMQ
** Kafka
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@
import io.quarkus.mongodb.runtime.MongodbConfig;
import io.quarkus.mongodb.runtime.dns.MongoDnsClient;
import io.quarkus.mongodb.runtime.dns.MongoDnsClientProvider;
import io.quarkus.mongodb.tracing.MongoTracingCommandListener;
import io.quarkus.runtime.metrics.MetricsFactory;
import io.quarkus.smallrye.health.deployment.spi.HealthBuildItem;
import io.quarkus.vertx.deployment.VertxBuildItem;
Expand Down Expand Up @@ -112,14 +111,6 @@ AdditionalIndexedClassesBuildItem includeDnsTypesToIndex() {
MongoDnsClient.class.getName());
}

@BuildStep
AdditionalIndexedClassesBuildItem includeDnsTypesToIndex(MongoClientBuildTimeConfig buildTimeConfig) {
if (buildTimeConfig.tracingEnabled) {
return new AdditionalIndexedClassesBuildItem(MongoTracingCommandListener.class.getName());
}
return new AdditionalIndexedClassesBuildItem();
}

@BuildStep
public void registerDnsProvider(BuildProducer<NativeImageResourceBuildItem> nativeProducer) {
nativeProducer.produce(new NativeImageResourceBuildItem("META-INF/services/" + DnsClientProvider.class.getName()));
Expand Down
10 changes: 5 additions & 5 deletions extensions/mongodb-client/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,6 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-mutiny-reactive-streams-operators</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-opentelemetry</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
Expand All @@ -58,6 +53,11 @@
<artifactId>quarkus-kubernetes-service-binding</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-opentelemetry</artifactId>
<optional>true</optional>
</dependency>

<!-- Add the health extension as optional as we will produce the health check only if it's included -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,15 @@ public MongoClients(MongodbConfig mongodbConfig, MongoClientSupport mongoClientS
}

public MongoClient createMongoClient(String clientName) throws MongoException {
MongoClientSettings mongoConfiguration = createMongoConfiguration(clientName, getMatchingMongoClientConfig(clientName));
MongoClientSettings mongoConfiguration = createMongoConfiguration(clientName, getMatchingMongoClientConfig(clientName), false);
MongoClient client = com.mongodb.client.MongoClients.create(mongoConfiguration);
mongoclients.put(clientName, client);
return client;
}

public ReactiveMongoClient createReactiveMongoClient(String clientName)
throws MongoException {
MongoClientSettings mongoConfiguration = createMongoConfiguration(clientName, getMatchingMongoClientConfig(clientName));
MongoClientSettings mongoConfiguration = createMongoConfiguration(clientName, getMatchingMongoClientConfig(clientName), true);
com.mongodb.reactivestreams.client.MongoClient client = com.mongodb.reactivestreams.client.MongoClients
.create(mongoConfiguration);
ReactiveMongoClientImpl reactive = new ReactiveMongoClientImpl(client);
Expand Down Expand Up @@ -254,14 +254,18 @@ public void apply(ServerSettings.Builder builder) {
}
}

private MongoClientSettings createMongoConfiguration(String name, MongoClientConfig config) {
private MongoClientSettings createMongoConfiguration(String name, MongoClientConfig config, boolean isReactive) {
if (config == null) {
throw new RuntimeException("mongo config is missing for creating mongo client.");
}
CodecRegistry defaultCodecRegistry = MongoClientSettings.getDefaultCodecRegistry();

MongoClientSettings.Builder settings = MongoClientSettings.builder();

if (isReactive) {
settings.contextProvider(new MongoReactiveContextProvider());
}

ConnectionString connectionString;
Optional<String> maybeConnectionString = config.connectionString;
if (maybeConnectionString.isPresent()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.quarkus.mongodb.runtime;

import org.reactivestreams.Subscriber;

import com.mongodb.RequestContext;
import com.mongodb.reactivestreams.client.ReactiveContextProvider;

import io.opentelemetry.context.Context;

class MongoReactiveContextProvider implements ReactiveContextProvider {

@Override
public RequestContext getContext(Subscriber<?> subscriber) {
return new MongoRequestContext(Context.current());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package io.quarkus.mongodb.runtime;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;

import com.mongodb.RequestContext;

import io.opentelemetry.context.Context;

@SuppressWarnings("unchecked")
public class MongoRequestContext implements RequestContext {
public static final String OTEL_CONTEXT_KEY = "otel.context.current";
private final Map<Object, Object> valuesMap;

MongoRequestContext(Context currentContext) {
valuesMap = new ConcurrentHashMap<>();
valuesMap.put(OTEL_CONTEXT_KEY, currentContext);
}

@Override
public <T> T get(Object key) {
return (T) valuesMap.get(key);
}

@Override
public boolean hasKey(Object key) {
return valuesMap.containsKey(key);
}

@Override
public boolean isEmpty() {
return valuesMap.isEmpty();
}

@Override
public void put(Object key, Object value) {
valuesMap.put(key, value);
}

@Override
public void delete(Object key) {
valuesMap.remove(key);
}

@Override
public int size() {
return valuesMap.size();
}

@Override
public Stream<Map.Entry<Object, Object>> stream() {
return valuesMap.entrySet().stream();
}
}
5 changes: 5 additions & 0 deletions extensions/opentelemetry/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-mongodb-client-deployment</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-http-deployment-spi</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import static io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem.SPI_ROOT;
import static io.quarkus.opentelemetry.runtime.OpenTelemetryRecorder.OPEN_TELEMETRY_DRIVER;
import static io.quarkus.opentelemetry.runtime.OpenTelemetryUtil.*;
import static java.util.stream.Collectors.toList;

import java.io.IOException;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.quarkus.opentelemetry.deployment.tracing;

import java.util.function.BooleanSupplier;

import io.quarkus.bootstrap.classloading.QuarkusClassLoader;

public class MongoTracingEnabled implements BooleanSupplier {

private static final String MONGO_TRACER_CONFIG = "io.quarkus.mongodb.runtime.MongodbConfig";

public boolean getAsBoolean() {
return QuarkusClassLoader.isClassPresentAtRuntime(MONGO_TRACER_CONFIG);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import jakarta.enterprise.inject.spi.EventContext;

import org.eclipse.microprofile.config.ConfigProvider;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.DotName;
Expand Down Expand Up @@ -41,6 +42,7 @@
import io.quarkus.deployment.annotations.BuildSteps;
import io.quarkus.deployment.annotations.ExecutionTime;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.AdditionalIndexedClassesBuildItem;
import io.quarkus.deployment.builditem.ApplicationInfoBuildItem;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
import io.quarkus.gizmo.MethodDescriptor;
Expand All @@ -49,6 +51,7 @@
import io.quarkus.opentelemetry.runtime.config.build.OTelBuildConfig.SecurityEvents.SecurityEventType;
import io.quarkus.opentelemetry.runtime.tracing.TracerRecorder;
import io.quarkus.opentelemetry.runtime.tracing.cdi.TracerProducer;
import io.quarkus.opentelemetry.runtime.tracing.intrumentation.mongodb.MongoTracingCommandListener;
import io.quarkus.opentelemetry.runtime.tracing.security.SecurityEventUtil;
import io.quarkus.vertx.http.deployment.spi.FrameworkEndpointsBuildItem;
import io.quarkus.vertx.http.deployment.spi.StaticResourcesBuildItem;
Expand Down Expand Up @@ -198,6 +201,17 @@ void registerSecurityEventObserver(Capabilities capabilities, OTelBuildConfig bu
}
}

@BuildStep(onlyIf = MongoTracingEnabled.class)
AdditionalIndexedClassesBuildItem includeMongoTracingListenerToIndex() {
Boolean mongoTracingEnabled = ConfigProvider.getConfig()
.getOptionalValue("quarkus.mongodb.tracing.enabled", Boolean.class)
.orElse(false);
if (mongoTracingEnabled) {
return new AdditionalIndexedClassesBuildItem(MongoTracingCommandListener.class.getName());
}
return new AdditionalIndexedClassesBuildItem();
}

private static ObserverConfiguratorBuildItem createEventObserver(
ObserverRegistrationPhaseBuildItem observerRegistrationPhase, SecurityEventType eventType, String utilMethodName) {
return new ObserverConfiguratorBuildItem(observerRegistrationPhase.getContext()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class InvalidAttributesConfigTest {
@RegisterExtension
static final QuarkusUnitTest TEST = new QuarkusUnitTest()
.overrideConfigKey("quarkus.otel.resource.attributes", "pod.id=${SOMETHING}")
.overrideConfigKey("quarkus.mongodb.devservices.enabled", "false")
.assertException(new Consumer<Throwable>() {
@Override
public void accept(final Throwable throwable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class OpenTelemetryContinuousTestingTest {
.addAsResource(new StringAsset(TestSpanExporterProvider.class.getCanonicalName()),
"META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider")
.add(new StringAsset(ContinuousTestingTestUtils.appProperties(
"quarkus.mongodb.devservices.enabled=false",
"quarkus.otel.traces.exporter=test-span-exporter")),
"application.properties"))
.setTestArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ public class OpenTelemetryDestroyerTest {
.addAsResource(new StringAsset(TestSpanExporterProvider.class.getCanonicalName()),
"META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider")
.add(new StringAsset(
"quarkus.otel.traces.exporter=test-span-exporter\n" +
"quarkus.mongodb.devservices.enabled=false\n" +
"quarkus.otel.traces.exporter=test-span-exporter\n" +
"quarkus.otel.experimental.shutdown-wait-time=PT60S\n"),
"application.properties"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class OpenTelemetryDevModeTest {
.addAsResource(new StringAsset(TestSpanExporterProvider.class.getCanonicalName()),
"META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider")
.add(new StringAsset(ContinuousTestingTestUtils.appProperties(
"quarkus.mongodb.devservices.enabled=false",
"quarkus.otel.traces.exporter=test-span-exporter")), "application.properties"));

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ public class OpenTelemetryDevServicesDatasourcesTest {
.addAsResource(new StringAsset(TestSpanExporterProvider.class.getCanonicalName()),
"META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider")
.add(new StringAsset(
"quarkus.datasource.db-kind=h2\n" +
"quarkus.mongodb.devservices.enabled=false\n" +
"quarkus.datasource.db-kind=h2\n" +
"quarkus.datasource.jdbc.telemetry=true\n" +
"quarkus.otel.traces.exporter=test-span-exporter\n" +
"quarkus.otel.bsp.export.timeout=1s\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class OpenTelemetryDisabledSdkTest {
@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withEmptyApplication()
.overrideConfigKey("quarkus.mongodb.devservices.enabled", "false")
.overrideConfigKey("quarkus.otel.sdk.disabled", "true");

@Inject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class OpenTelemetryDisabledTest {
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withEmptyApplication()
.overrideConfigKey("quarkus.otel.enabled", "false")
.overrideConfigKey("quarkus.mongodb.devservices.enabled", "false")
.assertException(t -> Assertions.assertEquals(DeploymentException.class, t.getClass()));

@Inject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
public class OpenTelemetryIdGeneratorTest {
@RegisterExtension
static final QuarkusUnitTest unitTest = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar.addClass(TestUtil.class));
.withApplicationRoot((jar) -> jar.addClass(TestUtil.class))
.overrideConfigKey("quarkus.mongodb.devservices.enabled", "false");

@Inject
OpenTelemetry openTelemetry;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ public class OpenTelemetryJdbcInstrumentationValidationTest {
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addAsResource(new StringAsset(
"quarkus.datasource.db-kind=h2\n" +
"quarkus.mongodb.devservices.enabled=false\n" +
"quarkus.datasource.db-kind=h2\n" +
"quarkus.datasource.jdbc.driver=io.opentelemetry.instrumentation.jdbc.OpenTelemetryDriver\n"),
"application.properties"))
.assertException(t -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
class OpenTelemetryLegacyConfigurationTest {
@RegisterExtension
static final QuarkusUnitTest TEST = new QuarkusUnitTest()
.overrideConfigKey("quarkus.mongodb.devservices.enabled", "false")
.overrideConfigKey("quarkus.opentelemetry.enabled", "false")
.overrideConfigKey("quarkus.opentelemetry.tracer.enabled", "false")
.overrideConfigKey("quarkus.opentelemetry.propagators", "tracecontext")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class OpenTelemetryServiceNameAppNameTest extends OpenTelemetryServiceNam
.addClass(TestSpanExporter.class)
.addClass(TestSpanExporterProvider.class)
.addAsResource(new StringAsset("" +
"quarkus.mongodb.devservices.enabled=false\n" +
"quarkus.otel.bsp.schedule.delay=50\n" +
"quarkus.application.name=" + SERVICE_NAME + "\n"), "application.properties"));
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class OpenTelemetryServiceNameCombinedResourceWinsTest extends OpenTeleme
() -> ShrinkWrap.create(JavaArchive.class)
.addClass(TestSpanExporter.class)
.addClass(TestSpanExporterProvider.class))
.overrideConfigKey("quarkus.mongodb.devservices.enabled", "false")
.overrideConfigKey("quarkus.application.name", "application-name-must-fail")
.overrideRuntimeConfigKey("quarkus.otel.bsp.schedule.delay", "50")// speed up test
.overrideRuntimeConfigKey("quarkus.otel.service.name", SERVICE_NAME)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class OpenTelemetryServiceNameCombinedServiceWinsTest extends OpenTelemet
() -> ShrinkWrap.create(JavaArchive.class)
.addClass(TestSpanExporter.class)
.addClass(TestSpanExporterProvider.class))
.overrideConfigKey("quarkus.mongodb.devservices.enabled", "false")
.overrideConfigKey("quarkus.application.name", "application-name-must-fail")
.overrideRuntimeConfigKey("quarkus.otel.bsp.schedule.delay", "50")// speed up test
.overrideRuntimeConfigKey("quarkus.otel.resource.attributes", "service.name=" + SERVICE_NAME);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class OpenTelemetryServiceNameNoResourceAttrsTest extends OpenTelemetrySe
() -> ShrinkWrap.create(JavaArchive.class)
.addClass(TestSpanExporter.class)
.addClass(TestSpanExporterProvider.class))
.overrideConfigKey("quarkus.mongodb.devservices.enabled", "false")
.overrideConfigKey("quarkus.otel.service.name", SERVICE_NAME)
.overrideRuntimeConfigKey("quarkus.otel.bsp.schedule.delay", "50");// speed up test
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class OpenTelemetryServiceNameResourceAttrTest extends OpenTelemetryServi
() -> ShrinkWrap.create(JavaArchive.class)
.addClass(TestSpanExporter.class)
.addClass(TestSpanExporterProvider.class))
.overrideConfigKey("quarkus.mongodb.devservices.enabled", "false")
.overrideRuntimeConfigKey("quarkus.otel.bsp.schedule.delay", "50")// speed up test
.overrideRuntimeConfigKey("quarkus.otel.resource.attributes", "service.name=" + SERVICE_NAME);
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class OpenTelemetrySpanSecurityEventsTest {
.addClasses(TestSpanExporter.class, TestSpanExporterProvider.class, EventsResource.class,
CustomSecurityEvent.class)
.addAsResource(new StringAsset("""
quarkus.mongodb.devservices.enabled=false
quarkus.otel.security-events.enabled=true
quarkus.otel.security-events.event-types=AUTHENTICATION_SUCCESS,AUTHORIZATION_SUCCESS,OTHER
"""), "application.properties"));
Expand Down
Loading
Loading