MongoDB Metrics Instrumentation

MongoDB is a modern database that supports transactional, search, analytics, and mobile use cases with a flexible document data model and a unified query interface.

Below you can find an example of how to instrument MongoDb with Micrometer.

To add more capabilities such as distributed tracing, please consider using Spring Data MongoDb which uses Micrometer Observation under the hood.

Below you can find an example of metrics for command execution.

// Setting up instrumentation
registry = new SimpleMeterRegistry();
MongoClientSettings settings = MongoClientSettings.builder()
    .addCommandListener(new MongoMetricsCommandListener(registry))
    .applyToClusterSettings(builder -> builder.hosts(singletonList(new ServerAddress(host, port)))
        .addClusterListener(new ClusterListener() {
            @Override
            public void clusterOpening(ClusterOpeningEvent event) {
                clusterId.set(event.getClusterId().getValue());
            }
        }))
    .build();
mongo = MongoClients.create(settings);

// Usage example
mongo.getDatabase("test").getCollection("testCol").insertOne(new Document("testDoc", new Date()));

Tags tags = Tags.of("cluster.id", clusterId.get(), "server.address", String.format("%s:%s", host, port),
        "command", "insert", "collection", "testCol", "status", "SUCCESS");
assertThat(registry.get("mongodb.driver.commands").tags(tags).timer().count()).isEqualTo(1);

Below you can find an example of metrics of the connection pool.

// Setting up instrumentation
MeterRegistry registry = new SimpleMeterRegistry();
MongoMetricsConnectionPoolListener connectionPoolListener = new MongoMetricsConnectionPoolListener(registry,
        e -> Tags.of("cluster.id", e.getServerId().getClusterId().getValue(), "server.address",
                e.getServerId().getAddress().toString(), "my.custom.connection.pool.identifier", "custom"));
MongoClientSettings settings = MongoClientSettings.builder()
    .applyToConnectionPoolSettings(
            builder -> builder.minSize(2).addConnectionPoolListener(connectionPoolListener))
    .applyToClusterSettings(builder -> builder.hosts(singletonList(new ServerAddress(host, port)))
        .addClusterListener(new ClusterListener() {
            @Override
            public void clusterOpening(ClusterOpeningEvent event) {
                clusterId.set(event.getClusterId().getValue());
            }
        }))
    .build();
MongoClient mongo = MongoClients.create(settings);

// Usage example
mongo.getDatabase("test").createCollection("testCol");

Tags tags = Tags.of("cluster.id", clusterId.get(), "server.address", String.format("%s:%s", host, port),
        "my.custom.connection.pool.identifier", "custom");

assertThat(registry.get("mongodb.driver.pool.size").tags(tags).gauge().value()).isEqualTo(2);
assertThat(registry.get("mongodb.driver.pool.checkedout").gauge().value()).isZero();
assertThat(registry.get("mongodb.driver.pool.waitqueuesize").gauge().value()).isZero();

mongo.close();