How to log express HTTP requests using morgan with style?

Customizing node morgan logger with tokens.

·

4 min read

How to log express HTTP requests using morgan with style?

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

image.png

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()
    .tz(tz)
    .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

  app.use(
    morgan(
      `: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

app.use(
    morgan(
      `: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');
        },
      },
    ),
  );