Search code examples
node.jsdynamiclog4js-node

How to write dynamic log file names with log4js-node?


I am trying to write a log file based on the time-stamp of the code when it runs. The log writes very well when the name is set, for example "Test.log":

const appSettings = {
        log4js: {
            traceLogConfig: {
                appenders: {
                    fileAppender: { type: 'file', filename: `./logs/Test.log`},
                    consoleAppender: { type: 'console' }
            },
            categories: {
                default: { appenders: ['fileAppender', 'consoleAppender'], level: 'trace'}
            }
        }
    }
};

A log file with the name is created correctly in the "logs" folder, and is filled with the logs from the code. However, things get more complicated when I try to make the name dynamic:

const appSettings = {
        log4js: {
            traceLogConfig: {
                appenders: {
                    fileAppender: { type: 'file', filename: `./logs/${new Date().toISOString().toString().replace(":","-")}`},
                    consoleAppender: { type: 'console' }
            },
            categories: {
                default: { appenders: ['fileAppender', 'consoleAppender'], level: 'trace'}
            }
        }
    }
};

When I run this, the file is created correctly in the folder, but then it is not filled with the log entries when the code runs. I tried creating the name separately and placing it into the code:

let name = new Date().toISOString().toString().replace(":","-");

const appSettings = {
        log4js: {
            traceLogConfig: {
                appenders: {
                    fileAppender: { type: 'file', filename: `./logs/${name}`},
                    consoleAppender: { type: 'console' }
            },
            categories: {
                default: { appenders: ['fileAppender', 'consoleAppender'], level: 'trace'}
            }
        }
    }
};

But this did not solve the issue either.


Solution

  • Apparently, it's not possible to pass a dynamic file name. You need to use a placeholder property with multiFile and then pass the property name (from the documentation):

    log4js.configure({
      appenders: {
        everything: {
          type: 'multiFile', base: 'logs/', property: 'userID', extension: '.log',
          maxLogSize: 10485760, backups: 3, compress: true
        }
      },
      categories: {
        default: { appenders: [ 'everything' ], level: 'debug'}
      }
    });
    
    const userLogger = log4js.getLogger('user');
    userLogger.addContext('userID', user.getID());
    userLogger.info('this user just logged in');