logo

The next-generation blog, news, and article for you to start sharing your stories today!

Express js log rotate middleware with request and response

 

In Express js sometime we have to log request and response data in api lifecycle.

Logging of request data is pretty simple but , deal with response data is very complecated. Well i went though many stackoverflow tutorials and blogs but unable to find proper solution.

Finally i made a solution with help of stackoverflow, blogs and various articles, and implemented in my live code.

Here is code snippet of the source code.

I am assuming that you have little bit knowledge of middleware in express js.


const moment = require('moment');
const rfs = require("rotating-file-stream");
const geoip = require('geoip-lite');
const { PassThrough } = require('stream')
let path = require('path');

const accessLogStream = rfs.createStream('access.log', {
    interval: '1M', // rotate monthly
    compress: true,
    path: path.join(__dirname, '../../log')
});

module.exports = function (req, res, next) {
    try {
        let geo = geoip.lookup(req.ip);
        let country = geo ? geo.country : "Unknown";
        let region = geo ? geo.region : "Unknown";
        let log = {
            "time": moment().format('YYYY/MM/DD HH:mm:ss'),
            "host": req.hostname,
            "ip": req.ip,
            "originalUrl": req.originalUrl,
            "geo": {
                "browser": req.headers["user-agent"],
                "Language": req.headers["accept-language"],
                "Country": country,
                "Region": region,
            },
            "method": req.method,
            "path": req.path,
            "url": req.url,
            "body": req.body,
            "params": req.params,
            "query": req.query,
            "response": {
                "body": res.body
            }
        };
        const defaultWrite = res.write.bind(res);
        const defaultEnd = res.end.bind(res);
        const ps = new PassThrough();
        const chunks = [];

        ps.on('data', data => chunks.push(data));

        res.write = (...args) => {
            ps.write(...args);
            defaultWrite(...args);
        }

        res.end = (...args) => {
            ps.end(...args);
            defaultEnd(...args);
        }
        res.on('finish', () => {
            log.response.body = Buffer.concat(chunks).toString()
            accessLogStream.write(JSON.stringify(log) + "\n");
        })
    } catch (error) {
        console.log(error)
        next(error)
    }
    next();
}

Hello friends i am vikram parihar. 

Please let me know if you have any issue and doubt about this code snippt. Thank you.

avatar

Vikram Parihar

An editor at Keyscript

Vikram Parihar is an senior software engineer. He is working since 2013 in web development technologies. He works in NodeJS, Angular, Vue, PHP, Laravel, Express JS and various popular technologies.