How to log express HTTP requests using morgan with style?

Customizing node morgan logger with tokens.

In this cookbook, I am gonna help you setup morgan with express to log HTTP requests like this,


at the end of this post, you will be able to log the following details

  • date and time of the request ( formatted as hh:mm a ddd, MMMM Do YYYY )
  • HTTP Method (ex: GET, POST, PUT, DELETE)
  • endpoint path (ex: /, /users, /payments)
  • response time ( The time between the request coming into morgan and when the response headers are written, in milliseconds. )
  • remote-address ( The remote address of the request. This will use req.ip, otherwise the standard req.connection.remoteAddress value.)
  • remote-user ( The user authenticated as part of Basic auth for the request. )
  • user-agent ( The User-Agent request header is a characteristic string that lets servers and network peers identify the application, operating system, vendor, and/or version of the requesting user agent. )

Install Dependencies

npm i morgan moment-timezone

# or if you are using yarn
yarn add morgan moment-timezone

Setting up morgan tokens

morgan logger allows you to customize with the .token() method. The .token() method takes in name of the token as the first argument, following a callback function. morgan will run the callback function each time a log occurs using the token.

morgan.token('date', (req, res, tz: string) => {
  return moment()
    .format('hh:mm a ddd, MMMM Do YYYY');
morgan.token('splitter', () => {
  return '\x1b[36m--------------------------------------------\x1b[0m\n';
morgan.token('statusColor', (req, res) => {
  const status = (typeof res.headersSent !== 'boolean'
  ? Boolean(res.header)
  : res.headersSent)
    ? res.statusCode
    : undefined;
  const color =
    status >= 500
      ? 31
      : status >= 400
      ? 33
      : status >= 300
      ? 36
      : status >= 200
      ? 32
      : 0;

  return '\x1b[' + color + 'm' + status + '\x1b[0m';

Morgan in express middleware

      `:splitter :date[Asia/Kolkata]   \x1b[33m:method\x1b[0m \x1b[36m:url\x1b[0m :statusColor \x1b[35m:response-time ms\x1b[0m | \x1b[35m:remote-addr\x1b[0m | :remote-user | \x1b[30m:user-agent\x1b[0m`,

here I have used my local timezone, you can change Asia/Kolkata to your local timezone.

Skipping logs

if you want to skip logging a specific request that's called frequently but you don't need to have the log you can use the below code and replace startsWith argument with the request URL of yours

      `:splitter :date[Asia/Kolkata]    \x1b[33m:method\x1b[0m \x1b[36m:url\x1b[0m :statusColor \x1b[35m:response-time ms\x1b[0m | \x1b[35m:remote-addr\x1b[0m | :remote-user | \x1b[30m:user-agent\x1b[0m`,
        skip: (req, res) => {
          return req.originalUrl.startsWith('/metrics');

No Comments Yet