Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Morgan (node.js): Coloring status code (as in 'dev') while using custom format

I am using morgan for logging in node.js.

I like the status code coloring provided in the predefined format mode 'dev', but I am using a custom format.

How can I get the same coloring as in 'dev' mode?

Per morgan documentation, dev format is the following :

 :method :url :status :response-time ms - :res[content-length]

When I use that it does not color :

// does not color
app.use(morgan(':method :url :status :response-time ms - :res[content-length]')); 

But when I use predefined 'dev' it does color!

app.use(morgan('dev'));
like image 286
Binu Avatar asked Mar 29 '16 12:03

Binu


People also ask

What does Morgan do in node JS?

morgan is a Node. js and Express middleware to log HTTP requests and errors, and simplifies the process. In Node. js and Express, middleware is a function that has access to the request and response lifecycle methods, and the next() method to continue logic in your Express server.

How do you use Morgan in Express?

This means even if your application is using some custom HTTP headers, you can still use morgan to log them. All you need to do is first define your own token and use it for your log format. To create a custom token, you need to invoke morgan. token() and pass the name and a callback function to it.

What is logger Express?

Morgan — HTTP logging middleware for express. It provides the ability to log incoming requests by specifying the formatting of log instance based on different request related information. For example: :method :url :status :response-time ms - :res[content-length]


3 Answers

You can use chalkJS for coloring very easily.

import morgan from 'morgan';
import chalk from 'chalk'; // or you can use the require('chalk') syntax too

export const morganMiddleware = morgan(function (tokens, req, res) {
    return [
        '\n\n\n',
        chalk.hex('#ff4757').bold('🍄  Morgan --> '),
        chalk.hex('#34ace0').bold(tokens.method(req, res)),
        chalk.hex('#ffb142').bold(tokens.status(req, res)),
        chalk.hex('#ff5252').bold(tokens.url(req, res)),
        chalk.hex('#2ed573').bold(tokens['response-time'](req, res) + ' ms'),
        chalk.hex('#f78fb3').bold('@ ' + tokens.date(req, res)),
        chalk.yellow(tokens['remote-addr'](req, res)),
        chalk.hex('#fffa65').bold('from ' + tokens.referrer(req, res)),
        chalk.hex('#1e90ff')(tokens['user-agent'](req, res)),
        '\n\n\n',
    ].join(' ');
});

app.use(morganMiddleware);
like image 195
Param Singh Avatar answered Oct 20 '22 11:10

Param Singh


Yes it cannot colourise your output to console by default.

You can either refer to this article which takes help of the 'chalk' module in order to colourise the output to console.

Or else what I did was I used the default 'dev' configuration and I added an extra config for my custom tokens which left the default dev output as it is. Something like this:

app.use(morgan('dev'));
app.use(morgan('auth_id - :userid user_email - :email'));

This will do what you are trying to do but, the second output of morgan will be in a newline.

like image 32
techpool Avatar answered Oct 20 '22 12:10

techpool


@Adam Reis pointed in the really nice direction. I came up with this solution:

morgan.token('splitter', (req) => {
    return "\x1b[36m--------------------------------------------\x1b[0m\n";
});
morgan.token('statusColor', (req, res, args) => {
    // get the status code if response written
    var status = (typeof res.headersSent !== 'boolean' ? Boolean(res.header) : res.headersSent)
        ? res.statusCode
        : undefined

    // get status color
    var color = status >= 500 ? 31 // red
        : status >= 400 ? 33 // yellow
            : status >= 300 ? 36 // cyan
                : status >= 200 ? 32 // green
                    : 0; // no color

    return '\x1b[' + color + 'm' + status + '\x1b[0m';
});
server.use(morgan(`:splitter\x1b[33m:method\x1b[0m \x1b[36m:url\x1b[0m :statusColor :response-time ms - length|:res[content-length]`));

Here is the result:

enter image description here

like image 5
mkb Avatar answered Oct 20 '22 12:10

mkb