2

I have a winston logger, and I want to set the filename of the file where the logger is being executed as the label object of the logger info object. e.g:
[info]:[callingFileName.js] - 19.06.2019 14:09:19: [message]:...

Here is my code:

'use strict';
const { createLogger, format, transports } = require('winston');
const winston = require('winston');
const path = require('path');
var appRoot = require('app-root-path');

const { splat, combine, timestamp, colorize, printf, label } = winston.format;

const o = {
  a: [1, 2, [[
    'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do ' +
      'eiusmod tempor incididunt ut labore et dolore magna aliqua.',
    'test',
    'foo']], 4],
  b: new Map([['za', 1], ['zb', 'test']])
};

var options = {
      debugfile: {
        level: 'debug',
        filename: `${appRoot}/logs/debug.log`,
        handleExceptions: true,
        json: true,
        maxsize: 5242880, // 5MB
        maxFiles: 5,
        colorize: false,
      },
      errorfile: {
        level: 'error',
        filename: `${appRoot}/logs/error.log`,
        handleExceptions: true,
        json: true,
        maxsize: 5242880, // 5MB
        maxFiles: 5,
        colorize: false,
      },
      console: {
        colorize: true,
        handleExceptions: true,
        prettyPrint: true,
        json: true,

      }
    };

    const customFormat = printf(info => `[${info.level}]:[${info.label}] - ${info.timestamp}: [message]: ${info.message}  ${info.meta? JSON.stringify(info.meta) : ''}`);


    const simplelogger = createLogger({
      name: "debug-console",
      format: combine(
        colorize({all:false}),
        timestamp({
          format: 'DD.MM.YYYY HH:mm:ss'
        }),
        label({ 
          label: path.basename(process.mainModule.filename) 
        }),
        splat(),
        customFormat
      ),
      transports: [
        new transports.Console(options.console),
        new transports.File( options.errorfile),
        new transports.File( options.debugfile)
      ]
    });

The label part is here:

label({ label: path.basename(process.mainModule.filename) }),

but I have the problem, that when I start my program, I run npm run index.js, so it always logs the calling file as index.js label: [info]:[index.js] - 19.06.2019 14:09:19: [message]: .... Is it somehow possible to set the label dynamically as the filename where I am running my logger.log() function? Or do I have to create a new class / instance everytime that I am in a new file other than index.js ?

EDIT: I switched to npm logat module, which solved my problems immediately with 3 lines of code. However, is there any simple solution with winston? I just saw I don't need winston anymore with logat.

MMMM
  • 3,320
  • 8
  • 43
  • 80
  • How do you handle colorized messages or maxFiles/maxsize in logat? Winston is much more advanced than logat. But of course, if logat is sufficient for your needs, then go for it. – Wernfried Domscheit Dec 17 '21 at 07:43

1 Answers1

0

The label is for static text, I don't think there is an easy way to change it. But you can define the filename in your message:

const customFormat = printf(info => 
   `[${info.level}]:[${path.basename(process.mainModule.filename)}] - ${info.timestamp}: [message]: ${info.message}  ${info.meta ? JSON.stringify(info.meta) : ''}`
);

const simplelogger = createLogger({
   name: "debug-console",
   format: combine(
      colorize({ all: false }),
      timestamp({ format: 'DD.MM.YYYY HH:mm:ss' }),
      splat(),
      customFormat
   ),
   transports: [
      new transports.Console(options.console),
      new transports.File(options.errorfile),
      new transports.File(options.debugfile)
   ]
});

You can even modify the log message, see this example:

const mutateMessage = format((info) => {
   if (info.sensitive) {
      info.message = info.message.replace(/root:.+@/, "root:[**REDACTED**]@");
   }
   if (/fail/i.test(info.message)) {
      info.level = 'error';
   }
   return info;
});


const logger = createLogger({
   level: 'info',
   format: combine(
      mutateMessage(),
      timestamp({ format: 'YYYY-MM-DD HH:mm:ss.SSS' }),
      printf(({ message, timestamp, level }) => {
         return `${timestamp} [${level}] -> ${message}`;
      })
   ),
   transports: [
      new transports.Console()
   ],
});

logger.info(`Connect to mongodb://root:secret@localhost/admin?authSource=admin`, { sensitive: true });
logger.info('Authentication failed.');


2021-12-17 08:27:53.922 [info] -> Connect to mongodb://root:[**REDACTED**]@localhost/admin?authSource=admin
2021-12-17 08:27:53.925 [error] -> Authentication failed.
Wernfried Domscheit
  • 54,457
  • 9
  • 76
  • 110
  • Your first code example doesn't address OP's concern in that the filename logged is whatever file Node used to start the app. (index.js is OP's case) – DJFriar Nov 06 '22 at 20:39