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

1.8k Views Asked by At

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.

2

There are 2 best solutions below

0
On BEST ANSWER

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');
0
On

This can be done.

Let your log4js config file be as it is:

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

You can overwrite the file name while loading the configuration as below:

const { traceLogConfig } = require('./log4js-config').log4js;
traceLogConfig.appenders.fileAppender.filename = 'your file name';
log4js.configure(traceLogConfig);