Mongoose Debug messages with a custom logging library or style
Tags: node, logging, mongodb, mongoose
Published: 2020-11-05 17:39:09

# Mongoose Custom Logger

When Using Mongoose as MongoDb object modeling for NodeJs, one interesting feature is the possibility to log to standard output what Mongoose is actually doing while interfacing with MongoDB. This can be easily achieved by configuring Mongoose library itself:

```javascript
mongoose.set('debug', true)
```

Which will print any action that Mongoose is performing (e.g. insert, update, remove, find) in a colored and very readable fashion.

![Log Sample](https://sergio-cloud.s3-eu-west-1.amazonaws.com/blog_images/log_sample.png)

This is basically an inner call of the library to `console.log`.

However when employing a custom logger library, or a custom logging style, the Mongoose log style becomes soon non-compliant.
Imagine adding a logging library to your project or a logger that logs to file instead of stdout, or even a custom log format for logging to standard output.
In all the former cases Mongoose logs would be lost or not conformant.

Luckily Mongoose is providing an additional parameter to the previous method. From the official [doc](https://mongoosejs.com/docs/api/mongoose.html#mongoose_Mongoose-set), the parameter can be either a writable stream or a callback for logging a message using a custom format.

```javascript
mongoose.set('debug', function(collectionName, methodName, ...methodArgs) {}); // use custom function to log collection methods + arguments
```

> If a writable stream is passed, it will log to that stream, without colorization. If a callback function is passed, it will receive the collection name, the method name, then all arguments passed to the method. For example, if you wanted to replicate the default logging, you could output from the callback Mongoose: ${collectionName}.${methodName}(${methodArgs.join(', ')}).

As stated above the custom callback can be something like this:

```javascript
function(collectionName, methodName, ...methodArgs) {
  customLogger.log(`${collectionName}.${methodName}(${methodArgs.join(', ')})`)
}
```

where `customLogger` is a custom logging library or imported dependency. The result is something like that:

![Log No Color](https://sergio-cloud.s3-eu-west-1.amazonaws.com/blog_images/log_uncolor.png)

While this is a step forward, this will just print a plain string, throwing away the nice colorization of the original Mongoose method, which is not cool!
Whereas for the `Mongoose` string, it is just a matter of pure console coloring optimization, in the form of:

```javascript
customLogger.log(`\x1B[0;36mMongoose:\x1B[0m:`);
```

The format of the nice part of the collection and operation performed is not straightforward to be printed.
But after digging a while in the lib, I found out that it uses a standard method of the native Node.js library `util`, in particular [util.inspect](https://nodejs.org/api/util.html#util_util_inspect_object_options), which:

> returns a string representation of object that is intended for debugging. The output of util.inspect may change at any time and should not be depended upon programmatically. Additional options may be passed that alter the result. util.inspect() will use the constructor's name and/or @@toStringTag to make an identifiable tag for an inspected value.

In the case of the `Mongoose` lib, the object is slightly manipulated to remove new lines and extra white spaces.
The result is similar to:

```javascript
util.inspect(m, false, 10, true).replace(/\n/g, '').replace(/\s{2,}/g, ' ');
```

So putting altogether, the final configuration of the Mongoose logging is something like that:

```javascript
mongoose.set('debug', (collectionName, methodName, ...methodArgs) => {
  const msgMapper = (m) => {
    return util.inspect(m, false, 10, true)
      .replace(/\n/g, '').replace(/\s{2,}/g, ' ');
  };
  customLogger.log(`\x1B[0;36mMongoose:\x1B[0m: ${collectionName}.${methodName}` + `(${methodArgs.map(msgMapper).join(', ')})`)
});
```

which outputs:
![Log Color](https://sergio-cloud.s3-eu-west-1.amazonaws.com/blog_images/log_color2.png)

I am happy that I can finally achieve the same log output created by the Mongoose library with any custom logging library I may employ.