For AI agents: a documentation index is available at https://www.mongodb.com/docs/llms.txt — markdown versions of all pages are available by appending .md to any URL path.
Docs Menu

Monitor Application Events

In this guide, you can learn how to use the Scala driver to monitor events that occur during driver operation. Monitoring involves collecting information about the activities of a running program, which you can use with an application or an application performance management library.

You can monitor application events to understand the driver's resource usage and performance, which helps you make informed decisions when designing and debugging your application.

The Scala driver organizes the events you can monitor into the following categories:

  • Command events: Events related to MongoDB database commands

  • Server Discovery and Monitoring (SDAM) events: Events related to changes in the state of the MongoDB instance or cluster you are connected to

  • Connection pool events: Events related to the connection pool the driver maintains with a MongoDB instance

The following sections describe each event category and show how to monitor events. To learn how to record driver events to a log, see the Logging guide.

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

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

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

Important

Redacted Output

As a security measure, the driver redacts the contents of some command events to protect sensitive information. For a full list of redacted command events, see the Security section of the MongoDB Command Logging and Monitoring specification.

To learn more about MongoDB database commands, see Database Commands.

The following example defines the CommandCounter class, which implements the CommandListener interface. The class tracks the number of times the driver successfully executes each database command and prints this information each time a command finishes.

case class CommandCounter() extends CommandListener {
private val commands =
scala.collection.mutable.Map[String, Int]()
override def commandStarted(event: CommandStartedEvent): Unit = {}
override def commandSucceeded(
event: CommandSucceededEvent
): Unit = {
val commandName = event.getCommandName
commands(commandName) =
commands.getOrElse(commandName, 0) + 1
println(commands.toMap)
}
override def commandFailed(event: CommandFailedEvent): Unit = {}
}

The following code adds an instance of the CommandCounter class to a MongoClientSettings object and configures a MongoClient instance by using the settings:

val settings: MongoClientSettings = MongoClientSettings
.builder()
.addCommandListener(CommandCounter())
.applyConnectionString(ConnectionString("<connection string>"))
.build()
val mongoClient: MongoClient = MongoClient(settings)

When you run the application, the output resembles the following:

Map(find -> 1)
Map(find -> 2)
Map(find -> 2, endSessions -> 1)

The following table describes the command events that the Scala driver publishes and the listener interface that handles them:

Event Type
Listener Interface
Description

Published when a database command starts.

Published when a database command succeeds.

Published when a database command fails.

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

The Scala driver defines nine SDAM events and provides the following listener interfaces, which each listen for three SDAM events:

  • ClusterListener: Listens for events related to topology changes, or changes in the state and structure of the cluster

  • ServerListener: Listens for events related to individual server changes

  • ServerMonitorListener: Listens for heartbeat events, which report on the status of communication between replica set members

You can use information from SDAM events to understand cluster changes, assess cluster health, or plan capacity.

The following example defines the TestClusterListener class, which implements the ClusterListener interface. The class contains methods that print messages in response to the following topology-related events:

  • clusterOpening(): Prints a message when the driver first connects to a cluster

  • clusterClosed(): Prints a message when the driver disconnects from a cluster

  • clusterDescriptionChanged(): Prints a message about changes to the read and write availability of the cluster

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 ID ${event.getClusterId} opening")
override def clusterClosed(event: ClusterClosedEvent): Unit =
println(s"Cluster with ID ${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 code adds an instance of the TestClusterListener class to a MongoClientSettings object and configures a MongoClient instance by using the settings:

val uri: ConnectionString = ConnectionString("<connection string>")
val settings: MongoClientSettings = MongoClientSettings
.builder()
.applyToClusterSettings((builder: ClusterSettings.Builder) =>
builder.addClusterListener(TestClusterListener(ReadPreference.secondary())))
.applyConnectionString(uri)
.build()
val client: MongoClient = MongoClient(settings)

When you run the application, the output resembles the following:

Cluster with ID ClusterId{value='...', description='...'} opening
Writable server available
Readable server available
Cluster with ID ClusterId{value='...', description='...'} closed

The following table describes each SDAM event, the listener interface that handles it, and when the driver publishes it:

Event Type
Listener Interface
Description

Published when the topology description changes, such as when there is an election of a new primary.

Published when the driver first connects to the cluster.

Published when the driver disconnects from the cluster.

Published when the server description changes.

Published when a new server is added to the topology.

Published when an existing server is removed from the topology.

Published when the server monitor sends a hello command to the server. This action is called a heartbeat.

Published when the heartbeat succeeds.

Published when the heartbeat fails.

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

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

Tip

Connection Pools

To learn more about connection pools, see the Connection Pools guide.

The following example defines the ConnectionPoolLibrarian class, which implements the ConnectionPoolListener interface. The class prints a message each time the driver checks out a connection from the connection pool.

case class ConnectionPoolLibrarian()
extends ConnectionPoolListener {
override def connectionCheckedOut(
event: ConnectionCheckedOutEvent
): Unit =
println(
s"Let me get you the connection with id " +
s"${event.getConnectionId.getLocalValue}..."
)
override def connectionCheckOutFailed(
event: ConnectionCheckOutFailedEvent
): Unit = {}
}

The following code adds an instance of the ConnectionPoolLibrarian class to a MongoClientSettings object and configures a MongoClient instance by using the settings:

val settings: MongoClientSettings = MongoClientSettings
.builder()
.applyToConnectionPoolSettings(
(builder: ConnectionPoolSettings.Builder) =>
builder.addConnectionPoolListener(
ConnectionPoolLibrarian()
)
)
.applyConnectionString(ConnectionString("<connection string>"))
.build()
val mongoClient: MongoClient = MongoClient(settings)

When you run the application, the output resembles the following:

Let me get you the connection with id 1...

The following table describes the connection pool events that the Scala driver publishes and the listener interface that handles them:

Event Type
Listener Interface
Description

Published when the connection pool is created.

Published when the connection pool is ready for use.

Published when the connection pool is closed.

Published when a connection is created in the pool.

Published when a connection completes its handshake and is ready for use.

Published when a connection is closed.

Published when the driver starts to check out a connection.

Published when the driver successfully checks out a connection.

Published when the driver fails to check out a connection.

Published when the driver checks a connection back into the pool.

Published when the connection pool is cleared.

To learn more about the methods and types discussed in this guide, see the following API documentation: