Search code examples
node.jsmongodbloggingwinston

Winston logger with MongoDB, if there is an error it saves on both collections (errorLog and infoLog), It should only save on "errorLog" collection


This is my code. If the level: "info" it's insert only one on (infoLog) collection, but if the level: "error" it's insert on both collection (errorLog & infoLog) collection. How I can fix this issue?

const { createLogger, format, transports } = require("winston");
const { combine, timestamp, prettyPrint } = format;
require("dotenv").config();
require("winston-mongodb");
const logger = createLogger({
  format: format.combine(
    format.timestamp({
      format: "DD-MM-YYYY  HH:mm:ss Z ",
    }),
    format.json(),
    format.metadata()
  ),
  transports: [
    new transports.Console(),
    new transports.MongoDB({
      level: "info",
      db: "mongodb://localhost:27017/oos",
      options: {
        useUnifiedTopology: true,
      },
      collection: "infoLog",
    }),
    new transports.MongoDB({
      level: "error",
      db: "mongodb://localhost:27017/oos",
      options: {
        useUnifiedTopology: true,
      },
      collection: "errorLog",
    }),
  ],
});

module.exports = logger;

This is what showing on console log enter image description here

{"level":"error","message":"([email protected]) Invalid Credential & User Not Found!!! ","timestamp":"30-09-2022  11:30:01 +08:00 "}

There are the collection data saved errorLog Collection infoLog Collection

{
"_id" : ObjectId("633662b98435813e681353e7"),
"timestamp" : ISODate("2022-09-30T11:30:01.056+08:00"),
"level" : "error",
"message" : "([email protected]) Invalid Credential & User Not Found!!! ",
"meta" : {
    "timestamp" : "30-09-2022  11:30:01 +08:00 "
}

}

This is the logger:

 logger.error(`(${email}) Invalid Credential & User Not Found!!! `);

Solution

  • I found a solution at https://betterstack.com/community/guides/logging/how-to-install-setup-and-use-winston-and-morgan-to-log-node-js-applications/#configuring-transports-in-winston

    Could be this one:

    const errorFilter = winston.format((info, opts) => {
      return info.level === 'error' ? info : false;
    });
    
    const infoFilter = winston.format((info, opts) => {
      return info.level === 'info' ? info : false;
    });
    
    const logger = winston.createLogger({
      level: 'info',
      transports: [
        new transports.MongoDB({
          level: "error",
          db: "mongodb://localhost:27017/oos",
          options: { useUnifiedTopology: true },
          collection: "errorLog",
          format: combine(errorFilter(), ...),
        }),
        new transports.MongoDB({
          level: "info",
          db: "mongodb://localhost:27017/oos",
          options: { useUnifiedTopology: true },
          collection: "infoLog",
          format: combine(infoFilter(), ...),
        }),
      ],
    });
    

    Maybe you can try also this:

    const collectionName = winston.collection((info, opts) => {
      return `${info.level}Log`;
    });
    
    new transports.MongoDB({
      level: "info",
      db: "mongodb://localhost:27017/oos",
      options: {
        useUnifiedTopology: true,
      },
      collection: collectionName(),
    }),