Search code examples
node.jsexpressloggingwinston

NodeJS Express - Global Unique Request Id


Is it possible to define a unique request Id that is included in each log statement without handing the logger to each method/function call?

Technologies in use: NodeJS, Express, Winston


Solution

  • Edited

    Finally, I have created a library that makes all the work. https://github.com/davicente/express-logger-unique-req-id

    It is a wrapper of Winston library, so you can use it the same way.

    Let me know if it helps you


    We had this same problem in several projects, and I couldn't finde any complete solution for this question. We are using same technologies (Node.js, Express.js and Winston for logs) I found a solution to this using a couple of libraries and wrapping Winston library: - node-uuid for creating unique identificators for each request - continuation-local-storage for sharing this IDs among different modules without sending req object in all the calls.

    First I need to create and set the unique identificator with each request. I do it in the middleware:

    var uuid = require('node-uuid');
    var createNamespace = require('continuation-local-storage').createNamespace;
    var myRequest = createNamespace('my request');
    
    // Run the context for each request. Assign a unique identifier to each request
    app.use(function(req, res, next) {
        myRequest.run(function() {
            myRequest.set('reqId', uuid.v1());
            next();
        });
    });
    

    After that I had to wrap Winston library, recovering the id from the context and adding to the message of the log:

    var winston = require('winston');
    var getNamespace = require('continuation-local-storage').getNamespace;
    
    // Wrap Winston logger to print reqId in each log
    var formatMessage = function(message) {
        var myRequest = getNamespace('my request');
        message = myRequest && myRequest.get('reqId') ? message + " reqId: " + myRequest.get('reqId') : message;
        return message;
    };
    
    var logger = {
        log: function(level, message) {
            winstonLogger.log(level, formatMessage(message));
        },
        error: function(message) {
            winstonLogger.error(formatMessage(message));
        },
        warn: function(message) {
            winstonLogger.warn(formatMessage(message));
        },
        verbose: function(message) {
            winstonLogger.verbose(formatMessage(message));
        },
        info: function(message) {
            winstonLogger.info(formatMessage(message));
        },
        debug: function(message) {
            winstonLogger.debug(formatMessage(message));
        },
        silly: function(message) {
            winstonLogger.silly(formatMessage(message));
        }
    };
    module.exports = logger;
    

    I think it was a little bit complex, so I decided to write it down in a post. You can get more information from there: Express.js: Logging info with global unique request ID – Node.js

    I hope this helps with your problem.