Monitor your Deployment
On this page
Overview
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 Events
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.
Command Events
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.
Example
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:
Make a class with counter functionality that implements the
CommandListener
interface.Add an instance of the new class that implements
CommandListener
to aMongoClientSettings
object.Configure a
MongoClient
instance with theMongoClientSettings
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>(); 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); } 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}
Server Discovery and Monitoring Events
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 eventsServerListener
: events related tomongod
ormongos
processesServerMonitorListener
: 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.
Example
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; 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
Connection Pool Events
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.
Example
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 { public void connectionCheckedOut(final ConnectionCheckedOutEvent event) { System.out.printf("Fetching the connection with id %s...%n", event.getConnectionId().getLocalValue()); } 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...
Monitor Connection Pool Events with JMX
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.
JMX Support
To enable JMX connection pool monitoring, add an instance of the
JMXConnectionPoolListener
class to your MongoClient
object.
The JMXConnectionPoolListener
class performs the following actions:
Creates MXBean instances for each
mongod
ormongos
process the driver maintains a connection pool withRegisters 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:
JMX and JConsole Example
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:
Select the Java process running the preceding example code.
Click Insecure Connection in the warning dialog box.
Click on the MBeans tab.
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:
Exit JConsole by closing the JConsole window.
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.
Include the Driver in Your Distributed Tracing System
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.
API Documentation
For more information about the classes and methods mentioned in this document, see the following API Documentation: