Monitoring
The driver uses JMX to create MXBeans that allow you to monitor various aspects of the driver.
The driver creates MXBean
instances of a single
type, ConnectionPoolStatisticsMBean
. The driver registers one
ConnectionPoolStatisticsMBean
instance for each server it connects
to. For example, when connected to a replica set, the driver creates an
instance for each non-hidden member of the replica set.
Each MXBean
instance is required to be registered with a unique object
name, which consists of a domain and a set of named properties. All
MXBean
instances created by the driver are under the domain
org.mongodb.driver
. Instances of ConnectionPoolStatisticsMBean
have the following properties:
clusterId
: a client-generated unique identifier, required to ensure object name uniqueness in situations where an application has multipleMongoClient
instances connected to the same MongoDB server deploymenthost
: the hostname of the serverport
: the port on which the server is listeningminSize
: the minimum allowed size of the pool, including idle and in-use membersmaxSize
: the maximum allowed size of the pool, including idle and in-use memberssize
: the current size of the pool, including idle and in-use memberscheckedOutCount
: the current count of connections that are currently in use
JMX connection pool monitoring is disabled by default. To enable it
add a com.mongodb.management.JMXConnectionPoolListener
instance
when creating a MongoClientSettings
instance:
val settings: MongoClientSettings = MongoClientSettings.builder() .applyToConnectionPoolSettings((builder: ConnectionPoolSettings.Builder) => builder.addConnectionPoolListener(new JMXConnectionPoolListener())) .build()
Command Monitoring
The driver implements the command monitoring specification, allowing an application to be notified when a command starts and when it either succeeds or fails.
An application registers command listeners with a MongoClient
by
configuring a MongoClientSettings
instance with instances of classes
that implement the CommandListener
interface. The following example
is a simple implementation of the CommandListener
interface:
case class TestCommandListener() extends CommandListener { override def commandStarted(event: CommandStartedEvent): Unit = { println(s"""Sent command '${event.getCommandName}:${event.getCommand.get(event.getCommandName)}' | with id ${event.getRequestId} to database '${event.getDatabaseName}' | on connection '${event.getConnectionDescription.getConnectionId}' to server | '${event.getConnectionDescription.getServerAddress}'""".stripMargin) } override def commandSucceeded(event: CommandSucceededEvent): Unit = { println(s"""Successfully executed command '${event.getCommandName}}' | with id ${event.getRequestId} | on connection '${event.getConnectionDescription.getConnectionId}' to server | '${event.getConnectionDescription.getServerAddress}'""".stripMargin) } override def commandFailed(event: CommandFailedEvent): Unit = { println(s"""Failed execution of command '${event.getCommandName}}' | with id ${event.getRequestId} | on connection '${event.getConnectionDescription.getConnectionId}' to server | '${event.getConnectionDescription.getServerAddress} | with exception '${event.getThrowable}'""".stripMargin) } }
The following example creates an instance of MongoClientSettings
configured with an instance of TestCommandListener
:
val settings: MongoClientSettings = MongoClientSettings.builder() .addCommandListener(TestCommandListener()) .build() val client: MongoClient = MongoClient(settings)
A MongoClient
configured with these options prints a message to
System.out
before sending each command to a MongoDB server, and
prints another message upon either successful completion or failure of each
command.
Cluster Monitoring
The driver implements the SDAM Monitoring specification, allowing an application to be notified when the driver detects changes to the topology of the MongoDB cluster to which it is connected.
An application registers listeners with a MongoClient
by configuring
MongoClientSettings
with instances of classes that implement any of
the ClusterListener
, ServerListener
, or
ServerMonitorListener
interfaces.
The following code demonstrates how to create a cluster listener:
case class TestClusterListener(readPreference: ReadPreference) extends ClusterListener { var isWritable: Boolean = false var isReadable: Boolean = false override def clusterOpening(event: ClusterOpeningEvent): Unit = println(s"Cluster with unique client identifier ${event.getClusterId} opening") override def clusterClosed(event: ClusterClosedEvent): Unit = println(s"Cluster with unique client identifier ${event.getClusterId} closed") override def clusterDescriptionChanged(event: ClusterDescriptionChangedEvent): Unit = { if (!isWritable) { if (event.getNewDescription.hasWritableServer) { isWritable = true println("Writable server available!") } } else { if (!event.getNewDescription.hasWritableServer) { isWritable = false println("No writable server available!") } } if (!isReadable) { if (event.getNewDescription.hasReadableServer(readPreference)) { isReadable = true println("Readable server available!") } } else { if (!event.getNewDescription.hasReadableServer(readPreference)) { isReadable = false println("No readable server available!") } } } }
The following example creates an instance of MongoClientSettings
configured with an instance of TestClusterListener
:
val settings: MongoClientSettings = MongoClientSettings.builder() .applyToClusterSettings((builder: ClusterSettings.Builder) => builder.addClusterListener(TestClusterListener(ReadPreference.secondary()))) .build() val client: MongoClient = MongoClient(settings)
A MongoClient
configured with these options prints a message to
System.out
when the MongoClient
is created with these options, and
when that MongoClient
is closed. In addition, it prints a message
when the client enters any of the following states:
Has an available server that will accept writes
Is without an available server that will accept writes
Has an available server that will accept reads by using the configured
ReadPreference
Is without an available server that will accept reads by using the configured
ReadPreference
Connection Pool Monitoring
The driver supports monitoring of connection pool-related events.
An application registers listeners with a MongoClient
by configuring
MongoClientSettings
with instances of classes that implement the
ConnectionPoolListener
interface.
The following code demonstrates how to create a connection pool listener:
case class TestConnectionPoolListener() extends ConnectionPoolListener { override def connectionPoolOpened(event: ConnectionPoolOpenedEvent): Unit = println(event) override def connectionPoolClosed(event: ConnectionPoolClosedEvent): Unit = println(event) override def connectionCheckedOut(event: ConnectionCheckedOutEvent): Unit = println(event) override def connectionCheckedIn(event: ConnectionCheckedInEvent): Unit = println(event) override def waitQueueEntered(event: ConnectionPoolWaitQueueEnteredEvent): Unit = println(event) override def waitQueueExited(event: ConnectionPoolWaitQueueExitedEvent): Unit = println(event) override def connectionAdded(event: ConnectionAddedEvent): Unit = println(event) override def connectionRemoved(event: ConnectionRemovedEvent): Unit = println(event) }
The following example creates an instance of MongoClientSettings
configured with an instance of TestConnectionPoolListener
:
val settings: MongoClientSettings = MongoClientSettings.builder() .applyToConnectionPoolSettings((builder: ConnectionPoolSettings.Builder) => builder.addConnectionPoolListener(TestConnectionPoolListener())) .build() val client: MongoClient = MongoClient(settings)
A MongoClient
configured with these options prints a message to
System.out
for each connection pool-related event for each MongoDB
server to which the MongoClient is connected.