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

Enable more MongoDB Micrometer metrics #44999

Merged
merged 3 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,21 @@ AdditionalIndexedClassesBuildItem includeMongoCommandListener(MongoClientBuildTi
return new AdditionalIndexedClassesBuildItem();
}

@BuildStep
AdditionalIndexedClassesBuildItem includeMongoCommandMetricListener(
MongoClientBuildTimeConfig buildTimeConfig,
Optional<MetricsCapabilityBuildItem> metricsCapability) {
if (!buildTimeConfig.metricsEnabled) {
return new AdditionalIndexedClassesBuildItem();
Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I wouldn't do that. Even if it doesn't complain right now, that's certainly something that could break later.

What you need to do is change the method to return void and inject a BuildProducer<AdditionalIndexedClassesBuildItem> additionalIndexedClasses and call the produce() method when it makes sense (and return; if you want to exit early).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@gsmet I've adjusted the code as you requested. Thanks!

}
boolean withMicrometer = metricsCapability.map(cap -> cap.metricsSupported(MetricsFactory.MICROMETER))
.orElse(false);
if (withMicrometer) {
return new AdditionalIndexedClassesBuildItem(MongoClientRecorder.getMicrometerCommandListenerClassName());
}
return new AdditionalIndexedClassesBuildItem();
}

@BuildStep
public void registerDnsProvider(BuildProducer<NativeImageResourceBuildItem> nativeProducer) {
nativeProducer.produce(new NativeImageResourceBuildItem("META-INF/services/" + DnsClientProvider.class.getName()));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.quarkus.mongodb.metrics;

import jakarta.inject.Inject;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.mongodb.MongoMetricsCommandListener;

public class MicrometerCommandListener extends MongoMetricsCommandListener {
@Inject
public MicrometerCommandListener(MeterRegistry registry) {
super(registry);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.mongodb.event.ConnectionPoolListener;

import io.quarkus.arc.Arc;
import io.quarkus.mongodb.metrics.MicrometerCommandListener;
import io.quarkus.mongodb.metrics.MicrometerConnectionPoolListener;
import io.quarkus.mongodb.metrics.MongoMetricsConnectionPoolListener;
import io.quarkus.mongodb.reactive.ReactiveMongoClient;
Expand Down Expand Up @@ -99,6 +100,10 @@ public ConnectionPoolListener get() {
};
}

public static String getMicrometerCommandListenerClassName() {
return MicrometerCommandListener.class.getName();
}

Copy link
Contributor

Choose a reason for hiding this comment

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

As this is used in a single place you can directly add the class name at the use site.
This would also avoid loading the class at runtime if not used wich would be better.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As this is used in a single place you can directly add the class name at the use site. This would also avoid loading the class at runtime if not used wich would be better.

micrometer wasn't on class path in deployment module, that's why I've put it there. I'll add optional dependency and move the code to the deployment

public Supplier<ConnectionPoolListener> createMPMetricsConnectionPoolListener() {
return new Supplier<ConnectionPoolListener>() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ private void callPersonEndpoint(String endpoint) {
.when().get("/q/metrics")
.then()
.statusCode(200)
.body(CoreMatchers.containsString("mongodb_driver_commands_seconds_max"))
.body(CoreMatchers.containsString("mongodb_driver_pool_checkedout"))
.body(CoreMatchers.containsString("mongodb_driver_pool_size"))
.body(CoreMatchers.containsString("mongodb_driver_pool_waitqueuesize"));
Expand Down