How to store only logs at a specific level in a particular log file?

57 Views Asked by At

I have following logger instace implementation

const fs = require("fs");
const path = require("path");
const winston = require("winston");
require("winston-daily-rotate-file");

const logLevels = {
    error: 0,
    info: 1,
    warn: 2,
    audit: 3,
    http: 4,
};

// Define log colors
const logColors = {
    error: "red",
    info: "green",
    warn: "yellow",
    audit: "blue",
    http: "cyan",
};

// Create the logs directory if it doesn't exist
const logsDir = path.join(__dirname, process.env.LOG_PATH);
if (!fs.existsSync(logsDir)) {
    fs.mkdirSync(logsDir);
}

// Configure Winston logger
const logger = winston.createLogger({
    level: "audit", // Set the minimum level to capture to "audit"
    levels: logLevels,
    format: winston.format.combine(
        winston.format.colorize({ all: true }),
        winston.format.timestamp({
            format: "YYYY-MM-DD hh:mm:ss.SSS A",
        }),
        winston.format.align(),
        winston.format.printf(
            (info) => `[${info.timestamp}] ${info.level}: ${info.message}`,
        ),
    ),
    transports: [
        // Console transport for displaying logs in the console
        new winston.transports.Console(),

        // File transport for error logs (capture only "error")
        new winston.transports.File({
            level: "error",
            format: winston.format.combine(
                winston.format.timestamp(),
                winston.format.json(),
            ),
            filename: path.join(logsDir, "error.log"),
        }),

        // File transport for info logs (capture only "info")
        new winston.transports.File({
            level: "info",
            format: winston.format.combine(
                winston.format.timestamp(),
                winston.format.json(),
            ),
            filename: path.join(logsDir, "info.log"),
        }),

        // File transport for warn logs (capture only "warn")
        new winston.transports.File({
            level: "warn",
            format: winston.format.combine(
                winston.format.timestamp(),
                winston.format.json(),
            ),
            filename: path.join(logsDir, "warn.log"),
        }),

        // File transport for audit logs (capture only "audit")
        new winston.transports.File({
            level: "audit",
            format: winston.format.combine(
                winston.format.timestamp(),
                winston.format.json(),
            ),
            filename: path.join(logsDir, "audit.log"),
        }),

        // File transport for HTTP logs (capture only "http")
        new winston.transports.File({
            level: "http",
            format: winston.format.combine(
                winston.format.timestamp(),
                winston.format.json(),
            ),
            filename: path.join(logsDir, "http.log"),
        }),

        new winston.transports.File({
            format: winston.format.combine(
                winston.format.timestamp(),
                winston.format.json(),
            ),
            filename: path.join(logsDir, "combined.log"),
        }),
    ],
});

winston.addColors(logColors);

module.exports = logger;

And I tested with the following messages to store them as logs

logger.error("ERROR: Log server is running", { value: 2 });
logger.info("INFO: Log server is running on port 5000", { value: 1 });
logger.warn("WARN: Log server is running on port 5000", { value: 3 });
logger.log({
    level: "audit",
    message: "AUDIT: Log server is running on port 5000",
    meta: { value: 4 },
});
logger.http("HTTP: Log server is running on port 5000", { value: 5 });

The problem is that only the error.log file stores error logs, while the other .log files store all the logs that have a higher severity than the current log level, along with their own logs.

The following is a sample output of the logs file.

error.log
{"level":"\u001b[31merror\u001b[39m","message":"\t\u001b[31mERROR: Log server is running\u001b[39m","timestamp":"2023-09-21 02:35:05.782 PM","value":2}
info.log
{"level":"\u001b[31merror\u001b[39m","message":"\t\u001b[31mERROR: Log server is running\u001b[39m","timestamp":"2023-09-21 02:35:05.782 PM","value":2}
{"level":"\u001b[32minfo\u001b[39m","message":"\t\u001b[32mINFO: Log server is running on port 5000\u001b[39m","timestamp":"2023-09-21 02:35:05.789 PM","value":1}
warn.log
{"level":"\u001b[31merror\u001b[39m","message":"\t\u001b[31mERROR: Log server is running\u001b[39m","timestamp":"2023-09-21 02:35:05.782 PM","value":2}
{"level":"\u001b[32minfo\u001b[39m","message":"\t\u001b[32mINFO: Log server is running on port 5000\u001b[39m","timestamp":"2023-09-21 02:35:05.789 PM","value":1}
{"level":"\u001b[33mwarn\u001b[39m","message":"\t\u001b[33mWARN: Log server is running on port 5000\u001b[39m","timestamp":"2023-09-21 02:35:05.791 PM","value":3}

And the other logs with lower severity also have the same issue as 'info' and 'warn.' From my perspective, I believe each log should store its related logs, rather than storing higher severity logs and its own log together.

Can someone give me advice on how to solve the current issue?

0

There are 0 best solutions below