Ashok
Ashok

Reputation: 3611

Multiple patterns not working while writing the logs to console

my requirement is to write the different logs to the console which needs to have a different pattern.

I've used multiple appenders and used a separate logger but it's not taking the pattern which I've given for the appender instead it's taking another pattern.

Below is the log4j2.properties

name = PropertiesConfig

appenders = console, console1

appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss,SSS} %t %-5p %c{6}:%L - %m%n

appender.console1.type = Console
appender.console1.name = STDOUT1
appender.console1.layout.type = PatternLayout
appender.console1.layout.pattern = %m%n

loggers = rolling
logger.rolling.name = org.apache.logging.log4j.core.appender.rolling

#Configure module specific
logger.org.apache.kafka.common.network.Selector = info
logger.com.test.test1 = fine
logger.com.test.test1.service.impl.RSStd=info

#configure rootLogger and attach all the appenders to it
rootLogger.level = info
rootLogger.appenderRef.console.ref = STDOUT

logger.performancelog.name = PERFORMANCE_LOG
logger.performancelog.additivity = false
logger.performancelog.level = info
logger.performancelog.appenderRef.console1.ref = STDOUT1

Every time it's picking this pattern

appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss,SSS} %t %-5p %c{6}:%L - %m%n

instead of

appender.console1.layout.pattern = %m%n

Below is my java code GlobalLogger

import java.util.Objects;

import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.owasp.esapi.ESAPI;
import org.apache.logging.log4j.core.config.Configuration;
import com.test.sample.common.constants.CommonConstants;
import com.test.sample.obj.ProcessRuntime;

public class GlobalLogger {
    private static final String Ref = ", Ref=";
    private final Logger logger;
    private final Logger testLogger;

    public static GlobalLogger getLogger(Class<?> cls) {
        return getLogger (cls.getName());
    }

    public static GlobalLogger getLogger(String pkgName) {
        return new GlobalLogger(LogManager.getLogger(pkgName));
    }

    private GlobalLogger(Logger logger) {
        this.testLogger=LogManager.getLogger("PERFORMANCE_LOG");
        this.logger = logger;
    }
    
    public static GlobalLogger getTESTLogger(String loggerName) { //1.1
        return new GlobalLogger(LogManager.getLogger(loggerName));
    }

    public void logIbgm(Object message){ //1.1
        testLogger.info("(PERFORMANCE_LOG) " + validateInput(message));
    }
    public boolean isTrace() {
        return logger.isTraceEnabled();
    }

    public void trace(Object message){
        if (isTrace()) {
            logger.trace(lineNumber() + Ref +  (Objects.equals(null, ProcessRuntime.getRequestId())?"":ProcessRuntime.getRequestId())+ ", " +validateInput( message));
        }
    }
    
    public void trace(Object message, Throwable t){
        if(isTrace()){
            logger.trace(lineNumber() + Ref +  (Objects.equals(null, ProcessRuntime.getRequestId())?"":ProcessRuntime.getRequestId()) + ", " + validateInput(message), t);
        }
    }

    public boolean isDebug() {
        return logger.isDebugEnabled();
    }
    
    public void debug(Object message){
        if(isDebug()){
            logger.debug(lineNumber() + Ref +  (Objects.equals(null, ProcessRuntime.getRequestId())?"":ProcessRuntime.getRequestId())+ ", " + validateInput(message));
        }
    }
    
    public void debug(Object message, Throwable t){
        if(isDebug()){
            logger.debug(lineNumber() + Ref + (Objects.equals(null, ProcessRuntime.getRequestId())?"":ProcessRuntime.getRequestId())+ ", " +validateInput( message), t);
        }
    }

    public boolean isInfo() {
         return logger.isInfoEnabled();
    }
    
    public void info(Object message){
        if(isInfo()){
            logger.info(lineNumber() + Ref + (Objects.equals(null, ProcessRuntime.getRequestId())?"":ProcessRuntime.getRequestId()) + ", " +validateInput(message));
        }
    }
    
    public void info(Object message, Throwable t){
        if(isInfo()){
            logger.info(lineNumber() + Ref + (Objects.equals(null, ProcessRuntime.getRequestId())?"":ProcessRuntime.getRequestId())+ ", " + validateInput(message), t);
        }
    }

    public boolean isWarn() {
        return logger.isWarnEnabled();
    }
    
    public void warn(Object message){
        if(isWarn()){
            logger.warn(lineNumber() + Ref +  (Objects.equals(null, ProcessRuntime.getRequestId())?"":ProcessRuntime.getRequestId())+ ", " + validateInput(message));
        }
    }
    
    public void warn(Object message, Throwable t){
        if(isWarn()){
            logger.warn(lineNumber() + Ref + (Objects.equals(null, ProcessRuntime.getRequestId())?"":ProcessRuntime.getRequestId())+ ", " + validateInput(message), t);
        }
    }
    
    public void error(Object message){
        logger.error(lineNumber() + Ref +  (Objects.equals(null, ProcessRuntime.getRequestId())?"":ProcessRuntime.getRequestId())+ ", " + validateInput(message));
    }
    
    public void error(Object message, Throwable t){
        logger.error(lineNumber() + Ref + (Objects.equals(null, ProcessRuntime.getRequestId())?"":ProcessRuntime.getRequestId()) + ", " + validateInput(message), t);
    }

    /*
     * Get the Actual Line Number
     */
    private String lineNumber() {
        StackTraceElement[] threadTrackArray = Thread.currentThread().getStackTrace();
        if (threadTrackArray.length > 3) {
            return ":" + Integer.toString(threadTrackArray[3].getLineNumber()) + "-";
        }
        return "";
    }

    public static void consoleLoggerInit () {
        consoleLoggerInit (null);
    }
    public static void consoleLoggerInit (Level logLevel) {
        final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
        final Configuration config = ctx.getConfiguration();
        if (config != null) {
            config.getRootLogger().getAppenders().clear();
            if (logLevel != null) {
                config.getRootLogger().setLevel(logLevel);
            } else {
                config.getRootLogger().setLevel(Level.INFO);
            }
            config.addAppender(ConsoleAppender.createDefaultAppenderForLayout(PatternLayout.newBuilder().withPattern("%5p [%t] (%c{1}) %m%n")
                    .withConfiguration(config).build()));
        }
    }

    public static String validateInput(Object msg) {
        try {
            String aString="";
            if(msg!=null)
                aString=msg.toString();
            return ESAPI.validator().getValidInput(CommonConstants.ESAPI_CONSTANTS.CONTEXT_INPUT_VALIDATION, aString, 
                    CommonConstants.ESAPI_CONSTANTS.VAL_TYPE_SOMETHING_ELSE, aString.length()+1,false);
        } catch (Exception e) {
            return "";
        }
    }
}

I'm using the this.testLogger=LogManager.getLogger("PERFORMANCE_LOG"); and the method

public void logIbgm(Object message){ //1.1
        testLogger.info("(PERFORMANCE_LOG) " + validateInput(message));
    }

PERFORMANCE_LOG is the name that is the same used for the logger name in log4j2.properties

pom.xml

<dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.17.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.17.1</version>
        </dependency>

Upvotes: 1

Views: 384

Answers (1)

Piotr P. Karwasz
Piotr P. Karwasz

Reputation: 16045

You are using the appenders and loggers properties to specify the list of appender and logger identifiers. While these properties are still supported, they are not required since version 2.6 (cf. LOG4J2-1308). To enable your "PERFORMANCE_LOG" logger either:

  • remove the loggers property (by default all the logger ids are enabled),

  • or set it to a list of all enabled loggers, e.g.:

    loggers = rolling, performancelog
    

Remark: while having multiple appenders on the same output stream is allowed, it is certainly not the recommended configuration. The PatternLayout in Log4j2 supports "pattern selectors" (cf. documentation), which can be used in your scenario.

A possible solution using MarkerPatternSelector would require:

  • obviously a marker, e.g.:

    private static final Marker PERF_MARKER = MarkerManager.getMarker("PERFORMANCE_LOG");
    
  • a pattern layout configured with a marker pattern selector:

    appender.c.l.type = PatternLayout
    appender.c.l.mps.type = MarkerPatternSelector
    appender.c.l.mps.defaultPattern = %d{yyyy-MM-dd HH:mm:ss,SSS} %t %-5p %c{6}:%L - %m%n
    appender.c.l.mps.0.type = PatternMatch
    appender.c.l.mps.0.key = PERFORMANCE_LOG
    appender.c.l.mps.0.pattern = (%marker) %m%n
    
  • to log using the PERFORMANCE marker you can use any logger, just use a Logger method with a marker parameter or LogBuilder:

    logger.info(PERF_MARKER, () -> validateInput(message));
    logger.atInfo()
          .withMarker(PERF_MARKER)
          .log("{}", () -> validateInput(message));
    

Upvotes: 1

Related Questions