Docs Menu
Docs Home
/ / /
Java Reactive Streams Driver

Monitor your Deployment

On this page

  • Overview
  • Monitor Events
  • Command Events
  • Server Discovery and Monitoring Events
  • Connection Pool Events
  • Monitor Connection Pool Events with JMX
  • JMX Support
  • JMX and JConsole Example
  • Include the Driver in Your Distributed Tracing System
  • API Documentation

In this guide, you can learn how to set up and configure monitoring in the Java Reactive Streams driver.

Monitoring is the process of gathering information about the activities a running program performs for use in an application or an application performance management library.

Monitoring the MongoDB Java driver lets you understand the driver's resource usage and performance, and can help you make informed decisions when designing and debugging your application.

In this guide you will learn how to perform the following tasks:

  • Monitor different types of events in the MongoDB Java Driver

  • Monitor connection pool events with Java Management Extensions (JMX) and JConsole

To monitor an event, you must register a listener on your MongoClient instance.

An event is any action that happens in a running program. The driver includes functionality for listening to a subset of the events that occur when the driver is running.

A listener is a class that performs some action when certain events occur. A listener's API defines the events it can respond to.

Each method of a listener class represents a response to a certain event. Each method receives one argument: an object representing the event the method responds to.

The MongoDB Java driver organizes the events it defines into three categories:

  • Command events

  • Server discovery and monitoring events

  • Connection pool events

The following sections show how to monitor each event category.

For a full list of the events you can monitor, see the event package of the MongoDB Java Driver.

A command event is an event related to a MongoDB database command. Some examples of database commands that produce command events are find, insert, delete, and count.

To monitor command events, create a class that implements the CommandListener interface and register an instance of that class with your MongoClient instance.

For more information about MongoDB database commands, see Database Commands in the MongoDB Server manual.

Note

Internal Commands

The driver does not publish events for commands it calls internally. This includes database commands the driver uses to monitor your cluster and commands related to connection establishment (such as the initial hello command).

Important

Redacted Output

As a security measure, the driver redacts the contents of some command events. This protects the sensitive information contained in these command events. For a full list of redacted command events, see the MongoDB command logging and monitoring specification.

The following example shows how to make a counter for database commands. The counter keeps track of the number of times the driver successfully executes each database command, and prints this information every time a database command finishes.

To implement the counter, perform the following steps:

  1. Make a class with counter functionality that implements the CommandListener interface.

  2. Add an instance of the new class that implements CommandListener to a MongoClientSettings object.

  3. Configure a MongoClient instance with the MongoClientSettings object.

The following code defines the CommandCounter class which implements the CommandListener interface:

class CommandCounter implements CommandListener {
private final Map<String, Integer> commands = new HashMap<String, Integer>();
@Override
public synchronized void commandSucceeded(final CommandSucceededEvent event) {
String commandName = event.getCommandName();
int count = commands.getOrDefault(commandName, 0);
commands.put(commandName, count + 1);
System.out.println(commands);
}
@Override
public void commandFailed(final CommandFailedEvent event) {
System.out.printf("Failed execution of command '%s' with id %s%n",
event.getCommandName(),
event.getRequestId());
}
}

The following code adds an instance of the CommandCounter class to a MongoClientSettings object, and configures a MongoClient instance with the MongoClientSettings object. The code then runs some database commands to test the counter.

MongoClientSettings settings = MongoClientSettings.builder()
.applyConnectionString(URI)
.addCommandListener(new CommandCounter())
.build();
try (MongoClient mongoClient = MongoClients.create(settings)) {
MongoDatabase database = mongoClient.getDatabase(DATABASE);
MongoCollection<Document> collection = database.getCollection(COLLECTION);
// Run some commands to test the counter
FindPublisher<Document> findPublisher1 = collection.find();
FindPublisher<Document> findPublisher2 = collection.find();
Flux.from(findPublisher1).blockLast();
Flux.from(findPublisher2).blockLast();
}
{find=1}
{find=2}
{find=2, endSessions=1}

A server discovery and monitoring (SDAM) event is an event related to a change in the state of the MongoDB instance or cluster you have connected the driver to.

The driver defines nine SDAM events. The driver divides these nine events between three separate listener interfaces which each listen for three of the nine events. Here are the three interfaces and the events they listen for:

  • ClusterListener: topology-related events

  • ServerListener: events related to mongod or mongos processes

  • ServerMonitorListener: heartbeat-related events

To monitor a type of SDAM event, write a class that implements one of the three preceding interfaces and register an instance of that class with your MongoClient instance.

For a detailed description of each SDAM event in the driver, see the MongoDB SDAM Logging and Monitoring Specification.

Note

Load Balanced Mode

The driver doesn't emit heartbeat related events when in load balanced mode. For more details about SDAM events with load balancing, see MongoDB Load Balancer Support Specification.

The following example shows how to make a listener class that prints a message that lets you know if the driver can write to your MongoDB instance.

The following code defines the IsWritable class which implements the ClusterListener interface:

class IsWritable implements ClusterListener {
private boolean isWritable;
@Override
public synchronized void clusterDescriptionChanged(final ClusterDescriptionChangedEvent event) {
if (!isWritable) {
if (event.getNewDescription().hasWritableServer()) {
isWritable = true;
System.out.println("Able to write to server");
}
} else if (!event.getNewDescription().hasWritableServer()) {
isWritable = false;
System.out.println("Unable to write to server");
}
}
}

The following code adds an instance of the IsWritable class to a MongoClient object. The code then runs a find operation to test the IsWritable class.

MongoClientSettings settings = MongoClientSettings.builder()
.applyConnectionString(URI)
.applyToClusterSettings(builder ->
builder.addClusterListener(new IsWritable()))
.build();
try (MongoClient mongoClient = MongoClients.create(settings)) {
MongoDatabase database = mongoClient.getDatabase(DATABASE);
MongoCollection<Document> collection = database.getCollection(COLLECTION);
// Run a command to trigger a ClusterDescriptionChangedEvent
FindPublisher<Document> findPublisher = collection.find();
Flux.from(findPublisher).blockLast();
}
Able to write to server

A connection pool event is an event related to a connection pool held by the driver. A connection pool is a set of open TCP connections your driver maintains with a MongoDB deployment. Connection pools help reduce the number of network handshakes your application needs to perform with a MongoDB deployment, and can help your application run faster.

To monitor connection pool events, write a class that implements the ConnectionPoolListener interface and register an instance of that class with your MongoClient instance.

The following example shows how to make a listener class that prints a message each time you check out a connection from your connection pool.

The following code defines the ConnectionPoolLibrarian class which implements the ConnectionPoolListener interface:

class ConnectionPoolLibrarian implements ConnectionPoolListener {
@Override
public void connectionCheckedOut(final ConnectionCheckedOutEvent event) {
System.out.printf("Fetching the connection with id %s...%n",
event.getConnectionId().getLocalValue());
}
@Override
public void connectionCheckOutFailed(final ConnectionCheckOutFailedEvent event) {
System.out.println("Something went wrong! Failed to checkout connection.");
}
}

The following code adds an instance of the ConnectionPoolLibrarian class to a MongoClient object. The code then runs a database command to test the librarian.

MongoClientSettings settings = MongoClientSettings.builder()
.applyConnectionString(URI)
.applyToClusterSettings(builder ->
builder.addClusterListener(new IsWritable()))
.build();
try (MongoClient mongoClient = MongoClients.create(settings)) {
MongoDatabase database = mongoClient.getDatabase(DATABASE);
MongoCollection<Document> collection = database.getCollection(COLLECTION);
// Run a command to trigger a ClusterDescriptionChangedEvent
FindPublisher<Document> findPublisher = collection.find();
Flux.from(findPublisher).blockLast();
}
Let me get you the connection with id 21...

You can monitor connection pool events using Java Management Extensions (JMX). JMX provides tools to monitor applications and devices.

For more information about JMX, see the official Oracle JMX documentation.

To enable JMX connection pool monitoring, add an instance of the JMXConnectionPoolListener class to your MongoClient object.

The JMXConnectionPoolListener class performs the following actions:

  1. Creates MXBean instances for each mongod or mongos process the driver maintains a connection pool with

  2. Registers these MXBean instances with the platform MBean server

MXBeans registered on the platform MBean server have the following properties:

Property
Description
clusterId
A client-generated unique identifier. This identifier ensures that each MXBean the driver makes has a unique name when an application has multiple MongoClient instances connected to the same MongoDB deployment.
host
The hostname of the machine running the mongod or mongos process.
port
The port on which the mongod or mongos process is listening.
minSize
The minimum size of the connection pool, including idle and in-use connections.
maxSize
The maximum size of the connection pool, including idle and in-use connections.
size
The current size of the connection pool, including idle and in-use connections.
checkedOutCount
The current count of connections that are in use.

All MXBean instances created by the driver are under the domain "org.mongodb.driver".

For more information about the topics discussed in this subsection, see the following resources from Oracle:

The following example shows how you can monitor the driver's connection pools using JMX and JConsole. JConsole is a JMX-compliant GUI monitoring tool that comes with the Java Platform.

Tip

Consult the Official JMX and JConsole Documentation

The descriptions of JMX and JConsole in this example are illustrative rather than a source of truth. For guaranteed up-to-date information, consult the following official Oracle resources:

The following code snippet adds a JMXConnectionPoolListener to a MongoClient instance. The code then pauses execution so you can navigate to JConsole and inspect your connection pools.

JMXConnectionPoolListener connectionPoolListener = new JMXConnectionPoolListener();
try (MongoClient mongoClient = MongoClients.create(URI)) {
System.out.println("Navigate to JConsole to see your connection pools...");
// Pauses the code execution so you can navigate to JConsole and inspect your connection pools
Thread.sleep(Long.MAX_VALUE);
}
Navigate to JConsole to see your connection pools...

Once you have started your server, open JConsole by running the following command in your terminal:

jconsole

Once JConsole is open, perform the following actions in the GUI:

  1. Select the Java process running the preceding example code.

  2. Click Insecure Connection in the warning dialog box.

  3. Click on the MBeans tab.

  4. Inspect your connection pool events under the "org.mongodb.driver" domain.

When you no longer want to inspect your connection pools in JConsole, perform the following tasks:

  1. Exit JConsole by closing the JConsole window.

  2. Stop the Java program running the preceding code snippet.

For more information about JMX and JConsole, see the following resources from Oracle:

For more information about the JMXConnectionPoolListener class, see the API Documentation for JMXConnectionPoolListener.

If you use a distributed tracing system, you can include event data from the driver. A distributed tracing system is an application that tracks requests as they propagate throughout different services in a service-oriented architecture.

If you use the driver in a Spring Cloud application, use Spring Cloud Sleuth to include MongoDB event data in the Zipkin distributed tracing system.

If you do not use Spring Cloud or must include driver event data in a distributed tracing system other than Zipkin, you must write a command event listener that manages spans for your desired distributed tracing system. To see an implementation of such a listener, see the TraceMongoCommandListener class in the Spring Cloud Sleuth source code.

To learn more about Spring Cloud Sleuth, see Getting Started in the Spring Cloud Sleuth documentation.

To view a detailed description of a distributed tracing system, see Dapper from Google Research.

For more information about the classes and methods mentioned in this document, see the following API Documentation:

Back

Logging