'How can I setup Log4JS with JSON output logs in Nodejs?

I am using Log4js to log my events with node-js. I am creating .log files correctly, but want to create JSON files instead. The log.js file is currently setup like this:

const appSettings = {
        log4js: {
            traceLogConfig: {
                appenders: {
                    fileAppender: { type: 'multiFile', base: `src/logs/log`, property: 'DATE', extension: '.log',
                    maxLogSize: 10485760, backups: 3, compress: true},
                    consoleAppender: { type: 'console' }
            },
            categories: {
                default: { appenders: ['fileAppender', 'consoleAppender'], level: 'trace'}
            }
        }
    }
};

export default appSettings;

And in the index.js code:

import log4js from "log4js";
import appSettings from "./logs.js";
log4js.configure(appSettings.log4js.traceLogConfig);
const logger = log4js.getLogger("fileAppender");

logger.addContext(
  "DATE",
  `${new Date(Date.now()).toISOString().split("T")[0]
  }-${new Date().getHours()}-${new Date().getMinutes()}`
);

logger.info(`Code started running at ${new Date(Date.now())}.`);

With the following result:

[2022-01-26T13:19:27.067] [INFO] fileAppender - Code started running at at Wed Jan 26 2022 13:19:27 GMT (Greenwich Mean Time).

I have tried to apply solutions I found here and here, but could not make the code work. I tried to change the code to the following: log.js:

const appSettings = {
        log4js: {
            traceLogConfig: {
                appenders: {
                    out:{ type: 'stdout', layout: { type: 'json', separator: ',' } }
            },
            categories: {
                default: { appenders: ['out'], level: 'info' }
            }
        }
    }
};

export default appSettings;

index.js:

import log4js from "log4js";
import appSettings from "./logs.js";

log4js.configure(appSettings.log4js.traceLogConfig);
log4js.addLayout('json', function(config) {
  return function(logEvent) { return JSON.stringify(logEvent) + config.separator; }
});
const logger = log4js.getLogger("fileAppender");

logger.addContext(
  "DATE",
  `${new Date(Date.now()).toISOString().split("T")[0]
  }-${new Date().getHours()}-${new Date().getMinutes()}`
);

logger.info(`Code started running at ${new Date(Date.now())}.`);

However, I am getting an error message:

 process.stdout.write(`${layout(loggingEvent, timezoneOffset)}\n`);
                            ^

TypeError: layout is not a function

The logs are very detailed and work great, I just need them to be in JSON, something like:

{ log:[
{
type: 'INFO',
message: 'Code started running at at Wed Jan 26 2022 13:19:27 GMT (Greenwich Mean Time).'
},
{
type: 'ERROR',
message: 'Update could not complete at line 14...'
}
]}

How can I do this with log4js? I tried using log4js-json-layout in the following way: log.js file:

let custID = `${process.argv[2]}`;
const appSettings = {
        log4js: {
            traceLogConfig: {
                appenders: {
                    type: 'console',
                    layout: {
                        type: 'json',
                    }
            }
        }
    }
};

index.js:

import log4js from "log4js";
import appSettings from "./logs.js";
import jsonLayout from "log4js-json-layout";

log4js.configure(appSettings.log4js.traceLogConfig);
log4js.addLayout('json', jsonLayout);

const logger = log4js.getLogger("fileAppender");

logger.addContext(
  "DATE",
  `${new Date(Date.now()).toISOString().split("T")[0]
  }-${new Date().getHours()}-${new Date().getMinutes()}`
);

logger.info(`Code started running at ${new Date(Date.now())}.`);

export default appSettings;

But I am getting an error message:

throw new Error(`Problem with log4js configuration: (${util.inspect(config, { depth: 5 })})`
            ^

Error: Problem with log4js configuration: ({
  appenders: [ { type: 'console', layout: { type: 'json' } } ]
}) - must have a property "appenders" of type object.

Any idea how I can set this up correctly?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source