본문 바로가기

Language/JavaScript

Monitoring MongoDB connection status

If you need to know what your MongoDB connection status is or when a database’s connection has dropped, timed out or some other error has occurred – this post will be useful to you. I don’t use any ODM packages like MongooseJS hence all examples cover the native MongoDB driver for node.js.

Main aspects:

  • checking MongoDB connection status using the .isConnected() method
  • listening to MongoDB events like: closedreconnecttimeout and others
  • Setting appname and checking what applications are connected to a database

Checking if the MongoDB database is connected?

Let’s say that we have a DbClient class where we have a .connect() method which looks like that:

public async connect() {
    if (this.db === undefined ||
        (this.db.serverConfig).isConnected() === false) {

        console.log("Connecting to database");
        this.db = await MongoClient.connect("mongodb://localhost:27017/test");
    } else {
        console.log(`Already connected to database: ${this.db.databaseName}`);
    }

    return this.db;
}

That code preventing us from connecting to the same database many times. But what if we need to detect and react somehow when the application loses the connection? For applications working online, it would be a tough situation. Thankfully MongoDB driver allows us to detect that kind of situations.

Monitoring MongoDB events

By default the Db object allows listening to a few basics events like: closereconnecttimeouterror,authenticated. That could be used as follow:

this.db.on("close", () => console.log(`CLOSE event on db: ${this.db.databaseName}`));
this.db.on("reconnect", () => console.log(`RECONNECT event on db: ${this.db.databaseName}`));
this.db.on("timeout", () => console.log(`TIMEOUT event on db: ${this.db.databaseName}`));
this.db.on("error", () => console.log(`ERROR event on db: ${this.db.databaseName}`));
this.db.on("timeout", () => console.log(`TIMEOUT event on db: ${this.db.databaseName}`));

Listening to a particular event is very simple. You can log a relevant message with the correct log status (usage of console.log() is a just an example). If you wish you can also do other actions like sending an email or a push notification to your DevOps team. It’s up to you.
You might also create a dedicated endpoint which will return 200 status when a database is connected, and then use that endpoint in some monitoring tool.

How to automatically reconnect to the database?

While your application loses the connection to the database it would be nice if it could reconnect automatically as soon as it’s possible. To do that we need to set the reconnectTries option. By default, MongoDB’s driver will try to reconnect 30 times every 1000 ms (1 sec). That time interval can be adjusted by setting the desired value for reconnectInterval option.

this.db = await MongoClient.connect("mongodb://localhost:27017/test", {
    reconnectTries: Number.MAX_VALUE, // try reconnect as long as it's possible  (default: 30),
    reconnectInterval: 500, // retry every 0.5 second (default value is 1000 ms - 1 sec)
 });

To test the above solution we will:

  1. start MongoDb server
  2. start our application which:
    • connects to MongoDB server
    • try to connect again (just to check if we can connect twice to the same database)
    • try to save some document
  3. restart the MongoDb server and observe what happens

Results:

MongoDB close and reconnect events

The full source code is available here

How to monitor connections on MongoDB side?

When a few applications connect to the same database sometimes you might need to check what apps are connected to a given database. MongoDB contains a  db.currentOp() method for checking in-progress operations. To return idle connections you need to call it with an argument: db.currentOp($all).

Checking connected apps to MongoDB database

You can see that some connections have a clientMetadata property where you can check what driver and OS was used to establish the connection. There is also an appName property which contains the application name. We can set value for the appName in our node application.

const options = {
    appname: appName,
    reconnectTries: Number.MAX_VALUE,
    reconnectInterval: 500,
};

this.db = await MongoClient.connect("mongodb://localhost:27017/test", options);
  • Please note that the property name used in MongoDB’s node.js driver is appname (all lowercase) not appName.
  • You might also see an error that property appname is not recognized as a valid field of MongoClientOptions. Unfortunately, it’s missing in Typescript definitions for MongoDB. The temporary solution for that is casting the options object to any type (Yes, I know…).

The final results:

Setting appname property while connecting to MongoDB

The full source code is available here

That’s all I hope that it would be useful for you. If you have any questions please let me know.