DEV Community

loading...

Mongoose Debug messages with a custom logging library or style

Sergio Matone
Cloud infrastracture architect
・3 min read

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:

mongoose.set('debug', true)
Enter fullscreen mode Exit fullscreen mode

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

Log Sample

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, the parameter can be either a writable stream or a callback for logging a message using a custom format.

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

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:

function(collectionName, methodName, ...methodArgs) {
  customLogger.log(`${collectionName}.${methodName}(${methodArgs.join(', ')})`)
}
Enter fullscreen mode Exit fullscreen mode

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

Log No Color

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:

customLogger.log(`\x1B[0;36mMongoose:\x1B[0m:`);
Enter fullscreen mode Exit fullscreen mode

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, 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:

util.inspect(m, false, 10, true).replace(/\n/g, '').replace(/\s{2,}/g, ' ');
Enter fullscreen mode Exit fullscreen mode

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

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(', ')})`)
});
Enter fullscreen mode Exit fullscreen mode

which outputs:
Log Color

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.

Discussion (0)