HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //home/arjun/projects/good-life-be/helper/logRequest.js
import morgan from 'morgan';
import dayjs from 'dayjs';
import chalk from 'chalk';

const MethodColors = {
  GET: chalk.green,
  POST: chalk.blue,
  PUT: chalk.yellow,
  DELETE: chalk.red,
  PATCH: chalk.magenta,
  OPTIONS: chalk.cyan,
  default: chalk.white,
};

const StatusColors = [
  { condition: (status) => status >= 500, color: chalk.red },
  { condition: (status) => status >= 400, color: chalk.yellow },
  { condition: (status) => status >= 300, color: chalk.cyan },
  { condition: (status) => status >= 200, color: chalk.green },
  { condition: (status) => status >= 100, color: chalk.white },
  { condition: (status) => status >= 0, color: chalk.gray },
];

const ResponseTimeColors = [
  { condition: (responseTime) => responseTime >= 1000, color: chalk.red },
  { condition: (responseTime) => responseTime >= 500, color: chalk.yellow },
  { condition: (responseTime) => responseTime >= 250, color: chalk.cyan },
  { condition: (responseTime) => responseTime >= 0, color: chalk.green },
];

const ResponseSizeColors = [
  { condition: (responseSize) => responseSize >= 100000, color: chalk.red },
  { condition: (responseSize) => responseSize >= 50000, color: chalk.yellow },
  { condition: (responseSize) => responseSize >= 25000, color: chalk.cyan },
  { condition: (responseSize) => responseSize >= 0, color: chalk.green },
];

const ResponseTimeFormatter = (responseTime) => {
  if (responseTime >= 60000) {
    const minutes = Math.floor(responseTime / 60000);
    const seconds = Math.floor((responseTime % 60000) / 1000);
    return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
  }

  if (responseTime >= 1000) {
    return `${(responseTime / 1000).toFixed(3)}s`;
  }

  return `${responseTime}ms`;
};

const ResponseSizeFormatter = (responseSize) => {
  if (responseSize >= 1000000) {
    return `${(responseSize / 1000000).toFixed(3)}mb`;
  }

  if (responseSize >= 1000) {
    return `${(responseSize / 1000).toFixed(3)}kb`;
  }

  return `${responseSize}b`;
};

const defaultColor = chalk.grey;

const logRequest = async (app) => {
  const onRequest = morgan(
    (tokens, req, res) => {
      const methodColor = MethodColors[req.method] || MethodColors.default;

      return defaultColor(
        [
          chalk.yellow('🡶'),
          `[${dayjs().format('hh:mm:ss a')}]`,
          methodColor(tokens.method(req, res)),
          tokens.url(req, res),
        ].join(' ')
      );
    },
    { immediate: true }
  );

  const onResponse = morgan((tokens, req, res) => {
    const methodColor = MethodColors[req.method] || MethodColors.default;
    const statusColor =
      StatusColors.find((c) => c.condition(res.statusCode))?.color ||
      defaultColor;
    const responseTimeColor =
      ResponseTimeColors.find((c) =>
        c.condition(Number(tokens['response-time'](req, res)))
      )?.color || defaultColor;
    const responseSizeColor =
      ResponseSizeColors.find((c) =>
        c.condition(Number(tokens.res(req, res, 'content-length')))
      )?.color || defaultColor;

    return [
      chalk.blue('🡴'),
      defaultColor(`[${dayjs().format('hh:mm:ss a')}]`),
      methodColor(tokens.method(req, res)),
      defaultColor(tokens.url(req, res)),
      statusColor(tokens.status(req, res)),
      responseSizeColor(
        ResponseSizeFormatter(
          Number(tokens.res(req, res, 'content-length') ?? 0)
        )
      ),
      '-',
      responseTimeColor(
        ResponseTimeFormatter(Number(tokens['response-time'](req, res)))
      ),
    ].join(' ');
  });

  app.use(onRequest);
  app.use(onResponse);
};

export default logRequest;