Newer
Older
express-blog / src / utils / logging / winston.js
// src/utils/logging/index.js
const util = require("util");
const { createLogger, format, transports } = require("winston");
const { SPLAT, LEVEL, MESSAGE } = require("triple-beam");

const { customLevels, LOG_LEVEL } = require("../../config/logging");

const { buildTransport } = require("./streams");

const { sessionTransport, sqliteTransport } = require("./config.js");
const config = require("../../config");

const formatMessage = (info) => {
  const { timestamp, level, message } = info;
  const splat = info[SPLAT] || [];
  const settings = config.logging.prettyPrint;

  // util.formatWithOptions applies splat arguments using config values
  const formattedMessage = util.formatWithOptions(
    {
      colors: settings.colors,
      depth: settings.depth,
      breakLength: settings.breakLength,
      compact: settings.compact,
    },
    message,
    ...splat,
  );

  // Isolate Error for stack trace
  const error =
    splat.find((arg) => arg instanceof Error) ||
    (message instanceof Error ? message : null);

  const stack = error ? `\n${error.stack}` : "";

  return `[${timestamp}] [${level}] ${formattedMessage}${stack}`;
};

const winstonLogger = createLogger({
  levels: customLevels.levels,
  format: format.combine(
    format.timestamp(),
    format.printf(
      ({ timestamp, level, message }) => `[${timestamp}] [${level}] ${message}`,
    ),
  ),
  transports: [
    buildTransport("info", "info"),
    buildTransport("event", "event"),
    buildTransport("error", "error"),
    buildTransport("warn", "warn"),
    buildTransport("debug", "debug"),
    buildTransport("notice", "notice"),
    buildTransport("security", "security"),
    sessionTransport,
    new transports.Console({
      level: LOG_LEVEL,
      format: format.combine(
        format.splat(),
        format.colorize(),
        format.timestamp(),
        format.printf(formatMessage),
      ),
      transports: [new transports.Console()],
    }),
    sqliteTransport,
  ],
});

module.exports = {
  winstonLogger,
};