Docs Menu
Docs Home
/ / /
Node.js Driver
/

Monitor Application Events

On this page

  • Overview
  • Monitor Events
  • Command Events
  • Example
  • Event Descriptions
  • Server Discovery and Monitoring Events
  • Event Subscription Example
  • Event Descriptions
  • Example Event Documents
  • Connection Pool Events
  • Event Subscription Examples
  • Event Descriptions
  • Example Event Documents
  • API Documentation

In this guide, you can learn how to set up and configure monitoring in the MongoDB Node.js driver.

Monitoring involves collecting information about the activities of a running program, which you can use with an application performance management library.

Monitoring the Node.js 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 these tasks:

  • Monitor Command Events

  • Monitor Server Discovery and Monitoring (SDAM) Events

  • Monitor Connection Pool Events

This guide shows how to use information about the activity of the driver in code. To learn how to record events in the driver, see the Node.js driver's Logging guide.

You can monitor events using the Node.js driver by subscribing to them in your application.

An event is any action that occurs within the driver during its operation. The Node.js driver includes functionality for listening to a subset of these events.

The Node.js driver organizes the events it defines into the following categories:

  • Command Events

  • Server Discovery and Monitoring (SDAM) Events

  • Connection Pool Events

The following sections show how to monitor each event category.

A command event is an event related to a MongoDB database command. You can access one or more command monitoring events using the driver by subscribing to them in your application.

To learn more about MongoDB database commands, see the Database Commands guide in the Server Manual.

Note

Command monitoring is disabled by default. To enable command monitoring, pass the monitorCommands option as true to your MongoClient constructor.

The following example demonstrates connecting to a replica set and subscribing to one of the command monitoring events created by the MongoDB deployment:

/* Subscribe to an event */
const { MongoClient } = require("mongodb");
// Replace the following with your MongoDB deployment's connection string
const uri = "mongodb+srv://<clusterUrl>/?replicaSet=rs&writeConcern=majority";
const client = new MongoClient(uri, { monitorCommands:true });
// Replace <event name> with the name of the event you are subscribing to
const eventName = "<event name>";
// Subscribes to a specified event and print a message when the event is received
client.on(eventName, event => console.log(event));
async function run() {
try {
// Establishes and verifies connection to the "admin" database
await client.db("admin").command({ ping: 1 });
console.log("Connected successfully");
} finally {
// Closes the database connection on completion or error
await client.close();
}
}
run().catch(console.dir);

You can subscribe to any of the following command monitoring events:

Event Name
Description

commandStarted

Created when a command is started.

commandSucceeded

Created when a command succeeded.

commandFailed

Created when a command failed.

CommandStartedEvent {
requestId: 1534,
databaseName: "app",
commandName: "find",
address: 'localhost:27017',
connectionId: 812613,
command: {
find: { firstName: "Jane", lastName: "Doe" }
}
}
CommandSucceededEvent {
requestId: 1534,
commandName: "find",
address: 'localhost:27017',
connectionId: 812613,
duration: 15,
reply: {
cursor: {
firstBatch: [
{
_id: ObjectId("5e8e2ca217b5324fa9847435"),
firstName: "Jane",
lastName: "Doe"
}
],
_id: 0,
ns: "app.users"
},
ok: 1,
operationTime: 1586380205
}
}
CommandFailedEvent {
requestId: 1534,
commandName: "find",
address: 'localhost:27017',
connectionId: 812613,
failure: Error("something failed"),
duration: 11
}

The Node.js driver creates topology events, also known as SDAM events, when there is a change in the state of the instance or cluster that you connected to. For example, the driver creates an event when you establish a new connection or if the cluster elects a new primary node.

To learn more about topology events, see the Replication guide in the Server Manual.

The following sections demonstrate how to record topology changes in your application and explore the information provided in these events.

You can access one or more SDAM events by subscribing to them in your application. The following example demonstrates connecting to a replica set and subscribing to one of the SDAM events created by the MongoDB deployment:

/* Subscribe to SDAM event */
const { MongoClient } = require("mongodb");
// Replace the following with your MongoDB deployment's connection string
const uri = "mongodb+srv://<clusterUrl>/?replicaSet=rs&writeConcern=majority";
const client = new MongoClient(uri);
// Replace <event name> with the name of the event you are subscribing to
const eventName = "<event name>";
// Subscribes to a specified event and prints a message when the event is received
client.on(eventName, event => {
console.log(`received ${eventName}: ${JSON.stringify(event, null, 2)}`);
});
async function run() {
try {
// Establishes and verifies connection to the database
await client.db("admin").command({ ping: 1 });
console.log("Connected successfully");
} finally {
// Closes the database connection on completion or error
await client.close();
}
}
run().catch(console.dir);

You can subscribe to any of the following SDAM events:

Event Name
Description

serverOpening

Created when a connection to an instance opens.

serverClosed

Created when a connection to an instance closes.

serverDescriptionChanged

Created when an instance state changes (such as from secondary to primary).

topologyOpening

Created before attempting a connection to an instance.

topologyClosed

Created after all instance connections in the topology close.

topologyDescriptionChanged

Created when the topology changes, such as an election of a new primary or a mongos proxy disconnecting.

serverHeartbeatStarted

Created before issuing a hello command to a MongoDB instance.

serverHeartbeatSucceeded

Created when the hello command returns successfully from a MongoDB instance.

serverHeartbeatFailed

Created when a hello command issued to a specific MongoDB instance fails to return a successful response.

The following sections show sample output for each type of SDAM event.

ServerDescriptionChangedEvent {
topologyId: 0,
address: 'localhost:27017',
previousDescription: ServerDescription {
address: 'localhost:27017',
error: null,
roundTripTime: 0,
lastUpdateTime: 1571251089030,
lastWriteDate: null,
opTime: null,
type: 'Unknown',
minWireVersion: 0,
maxWireVersion: 0,
hosts: [],
passives: [],
arbiters: [],
tags: []
},
newDescription: ServerDescription {
address: 'localhost:27017',
error: null,
roundTripTime: 0,
lastUpdateTime: 1571251089051,
lastWriteDate: 2019-10-16T18:38:07.000Z,
opTime: { ts: Timestamp, t: 18 },
type: 'RSPrimary',
minWireVersion: 0,
maxWireVersion: 7,
maxBsonObjectSize: 16777216,
maxMessageSizeBytes: 48000000,
maxWriteBatchSize: 100000,
me: 'localhost:27017',
hosts: [ 'localhost:27017' ],
passives: [],
arbiters: [],
tags: [],
setName: 'rs',
setVersion: 1,
electionId: ObjectID,
primary: 'localhost:27017',
logicalSessionTimeoutMinutes: 30,
'$clusterTime': ClusterTime
}
}

The type field of the ServerDescription object in this event contains one of the following possible values:

Type
Description

Unknown

Unknown instance

Standalone

Standalone instance

Mongos

Mongos proxy instance

PossiblePrimary

At least one server recognizes this as the primary, but is not yet verified by all instances.

RSPrimary

Primary instance

RSSecondary

Secondary instance

RSArbiter

Arbiter instance

RSOther

RSGhost

See the RSGhost and RSOther specification for more details

ServerHeartbeatStartedEvent {
connectionId: 'localhost:27017'
}
ServerHeartbeatSucceededEvent {
duration: 1.939997,
reply:{
hosts: [ 'localhost:27017' ],
setName: 'rs',
setVersion: 1,
isWritablePrimary: true,
secondary: false,
primary: 'localhost:27017',
me: 'localhost:27017',
electionId: ObjectID,
lastWrite: {
opTime: { ts: [Timestamp], t: 18 },
lastWriteDate: 2019-10-16T18:38:17.000Z,
majorityOpTime: { ts: [Timestamp], t: 18 },
majorityWriteDate: 2019-10-16T18:38:17.000Z
},
maxBsonObjectSize: 16777216,
maxMessageSizeBytes: 48000000,
maxWriteBatchSize: 100000,
localTime: 2019-10-16T18:38:19.589Z,
logicalSessionTimeoutMinutes: 30,
minWireVersion: 0,
maxWireVersion: 7,
readOnly: false,
ok: 1,
operationTime: Timestamp,
'$clusterTime': ClusterTime
},
connectionId: 'localhost:27017'
}
ServerHeartbeatFailed {
duration: 20,
failure: MongoError('some error'),
connectionId: 'localhost:27017'
}
ServerOpeningEvent {
topologyId: 0,
address: 'localhost:27017'
}
ServerClosedEvent {
topologyId: 0,
address: 'localhost:27017'
}
TopologyOpeningEvent {
topologyId: 0
}
TopologyClosedEvent {
topologyId: 0
}
TopologyDescriptionChangedEvent {
topologyId: 0,
previousDescription: TopologyDescription {
type: 'ReplicaSetNoPrimary',
setName: null,
maxSetVersion: null,
maxElectionId: null,
servers: Map {
'localhost:27017' => ServerDescription
},
stale: false,
compatible: true,
compatibilityError: null,
logicalSessionTimeoutMinutes: null,
heartbeatFrequencyMS: 10000,
localThresholdMS: 15,
options: Object,
error: undefined,
commonWireVersion: null
},
newDescription: TopologyDescription {
type: 'ReplicaSetWithPrimary',
setName: 'rs',
maxSetVersion: 1,
maxElectionId: null,
servers: Map {
'localhost:27017' => ServerDescription
},
stale: false,
compatible: true,
compatibilityError: null,
logicalSessionTimeoutMinutes: 30,
heartbeatFrequencyMS: 10000,
localThresholdMS: 15,
options: Object,
error: undefined,
commonWireVersion: 7
}
}

The type field of the TopologyDescription object in this event contains one of the following possible values:

Type
Description

Single

Standalone instance

ReplicaSetWithPrimary

Replica set with a primary

ReplicaSetNoPrimary

Replica set with no primary

Sharded

Sharded cluster

Unknown

Unknown topology

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

The following sections demonstrate how to record connection pool events in your application and explore the information provided in these events.

You can access one or more connection pool events using the driver by subscribing to them in your application. The following example demonstrates connecting to a replica set and subscribing to one of the connection pool monitoring events created by the MongoDB deployment:

const { MongoClient } = require("mongodb");
// Replace the following with your MongoDB deployment's connection string
const uri =
"mongodb+srv://<clusterUrl>/?replicaSet=rs&writeConcern=majority";
const client = new MongoClient(uri);
// Replace <event name> with the name of the event you are subscribing to
const eventName = "<event name>";
// Subscribes to the event
client.on(eventName, (event) =>
console.log("\nreceived event:\n", event)
);
async function run() {
try {
// Establishes and verifies connection
await client.db("admin").command({ ping: 1 });
console.log("\nConnected successfully!\n");
} finally {
// Ensures that the client will close when you finish/error
await client.close();
}
}
run().catch(console.dir);

Connection pool monitoring events can aid you in debugging and understanding the behavior of your application's connection pool. The following example uses connection pool monitoring events to return a count of checked-out connections in the pool:

function connectionPoolStatus(client) {
let checkedOut = 0;
function onCheckout() {
checkedOut++;
}
function onCheckin() {
checkedOut--;
}
function onClose() {
client.removeListener('connectionCheckedOut', onCheckout);
client.removeListener('connectionCheckedIn', onCheckin);
checkedOut = NaN;
}
// Decreases count of connections checked out of the pool when connectionCheckedIn event is triggered
client.on('connectionCheckedIn', onCheckin);
// Increases count of connections checked out of the pool when connectionCheckedOut event is triggered
client.on('connectionCheckedOut', onCheckout);
// Cleans up event listeners when client is closed
client.on('close', onClose);
return {
count: () => checkedOut,
cleanUp: onClose
};
}

You can subscribe to any of the following connection pool monitoring events:

Event Name
Description

connectionPoolCreated

Created when a connection pool is created.

connectionPoolReady

Created when a connection pool is ready.

connectionPoolClosed

Created when a connection pool is closed before server instance destruction.

connectionCreated

Created when a connection is created, but not necessarily when it is used for an operation.

connectionReady

Created after a connection has successfully completed a handshake and is ready to be used for operations.

connectionClosed

Created when a connection is closed.

connectionCheckOutStarted

Created when an operation attempts to acquire a connection for execution.

connectionCheckOutFailed

Created when an operation fails to acquire a connection for execution.

connectionCheckedOut

Created when an operation successfully acquires a connection for execution.

connectionCheckedIn

Created when a connection is checked back into the pool after an operation is executed.

connectionPoolCleared

Created when all connections are closed and the connection pool is cleared.

The following sections show sample output for each type of connection pool monitoring event.

ConnectionPoolCreatedEvent {
time: 2023-02-13T15:54:06.944Z,
address: '...',
options: {...}
}
ConnectionPoolReadyEvent {
time: 2023-02-13T15:56:38.440Z,
address: '...'
}
ConnectionPoolClosedEvent {
time: 2023-02-13T15:56:38.440Z,
address: '...'
}
ConnectionCreatedEvent {
time: 2023-02-13T15:56:38.291Z,
address: '...',
connectionId: 1
}
ConnectionReadyEvent {
time: 2023-02-13T15:56:38.291Z,
address: '...',
connectionId: 1,
durationMS: 60
}
ConnectionClosedEvent {
time: 2023-02-13T15:56:38.439Z,
address: '...',
connectionId: 1,
reason: 'poolClosed',
serviceId: undefined
}
ConnectionCheckOutStartedEvent {
time: 2023-02-13T15:56:38.291Z,
address: '...',
}
ConnectionCheckOutFailedEvent {
time: 2023-02-13T15:56:38.291Z,
address: '...',
reason: ...,
durationMS: 60
}
ConnectionCheckedOutEvent {
time: 2023-02-13T15:54:07.188Z,
address: '...',
connectionId: 1,
durationMS: 60
}
ConnectionCheckedInEvent {
time: 2023-02-13T15:54:07.189Z,
address: '...',
connectionId: 1
}
ConnectionPoolClearedEvent {
time: 2023-02-13T15:56:38.439Z,
address: '...',
serviceId: undefined,
interruptInUseConnections: true,
}

To learn more about any of the options or types discussed in this guide, see the following API documentation:

Back

Monitoring and Logging