Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you preserve request context in a Node JS App using express?

My request object contains a unique id which every log in my app must have.This id must also be propagated to any APIs I'm calling from my back-end Right now, I'm passing the request object everywhere. This is obviously not an ideal solution.Are there any suggestions?

CODE FLOW

Client------->Server(generate request id, use this for all logs)----->pass request id to any api call

Code:

app.use(function(req,res,next) {    
  logger.info("My message",req);
});
like image 966
Anurag Ojha Avatar asked Sep 18 '15 15:09

Anurag Ojha


2 Answers

You can use the continuation-local-storage module. There is also the request-local module that is just a small layer on top of continuation-local-storage. Don't expect continuation-local-storage to always be perfect though...you will run into edge cases where the cls context will be invalid.

like image 104
Patrick Steele-Idem Avatar answered Oct 05 '22 03:10

Patrick Steele-Idem


Here is a revised solution using the continuation-local-storage module.

Here is my context module. So far it only stores path, request time and correlation ID that it generates if it doesn’t receive one in the request.

'use strict';

const continuation = require('continuation-local-storage');
const cuid = require('cuid');

const appName = require('config').get('app_name');

class Context {

    static setup(req, res, next) {
        const session = continuation.createNamespace(appName);
        session.run(() => {
            session.set('context', new Context(req));
            next();
        });
    }

    constructor(req) {
        this.path = req.path;
        this.corrId = req.headers['x-correlation-id'] || cuid();
        this.requestTime = Date.now();
    }

    static current() {
        return continuation.getNamespace(appName).get('context');
    }
}

module.exports = Context;

My app.js includes:

const Context = require('./context');

app.use(Context.setup);

After that, any code can call Context.current() to get the current context of the Express request. I will use that for consistent logging.

like image 33
pharsicle Avatar answered Oct 05 '22 03:10

pharsicle