0

I want to add a dynamic attribute to a pattern I am using with log4js. I am using some custom pattern, something like this: "%d{} %-6p[%thread] %c [%x{context}]: %m%n%r"

Context is the dynamic value that I want to set with some unique id generated for each user on the server side. There is a way to add dynamic value when creation log4js configuration by using "tokens" and "context" attributes. But in this case values should be set during the log creation.

Is there a way to add some dynamic attribute that is set when the actual message is written to the log and not during the config phase?

Right now I am doing something like this:

        log4js.configure(
        {
          appenders: { "file": { "type": "file", "filename": "service.log", "maxLogSize": 102400, "backups": 5,  "category": "com.nextinsurance",  "layout": { "type": "pattern", "pattern": "%d{} %-6p[%thread] %c [%x{context}]: %m%n%r",  "tokens" : {context: function(logEvent){ return getContextFromData(logEvent) } } } }, "console" : {"type": "console"} },
          categories: { "default": { "appenders": ["file", "console"], "level": "info" } }
        }
       );

But want to inject this value when writing to log, something like

logger.info(Message, {context: context_value})
Boltosaurus
  • 2,138
  • 3
  • 21
  • 33

1 Answers1

0

You can use logEvent data property to fetch context. logEvent data property contains the array of args passed in log event. Here is the sample code:

var log4js = require("log4js");

log4js.configure({
  appenders: {
    out: {
      type: 'stdout',
      layout: {
        type: 'pattern',
        pattern: '[%d] [%p] [%c] [%x{context}] - %m%n',
        tokens: {
          context: function(logEvent) {
            let returnVal = logEvent.data[1] ? logEvent.data[1].context : undefined;
            if (returnVal) {
              logEvent.data.pop();
            } else {
              returnVal = 'null'; // set any default value if context is not passed.
            }
            return returnVal;
          }
        }
      }
    }
  },
  categories: {
    default: {
      appenders: ['out'],
      level: 'INFO'
    }
  }
});

log4js.level = 'info';
let logger = log4js.getLogger();

logger.info('Hello', { context: 'context_value'}); // prints [2019-09-13T16:50:48.818] [INFO] [default] [context_value] - Hello
logger.info('Hello'); // prints [2019-09-13T16:50:48.820] [INFO] [default] [null] - Hello
  • This would not work if you have multiple appenders. The first pop() would empty the context in the subsequent logs. – alain Jan 13 '22 at 12:42