Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible for using different pattern layout for different log level and output to SYSTEM_OUT?

For log4j2, is it possible for using different pattern layout for different log level and output to SYSTEM_OUT?

Here is my log4j2.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration>
        <Appenders>
            <Console name="debugMsg" target="SYSTEM_OUT">
                <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %l - %msg%n"/>
            </Console>
            <Console name="infoMsg" target="SYSTEM_OUT">
                <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %msg%n"/>
            </Console>
        </Appenders>
        <Loggers>
            <Root level="trace"  additivity="false">
                <AppenderRef ref="infoMsg" level="info"/>
                <AppenderRef ref="debugMsg" level="debug"/>
            </Root>
        </Loggers>
    </Configuration>

However, the INFO level message are shown in both "infoMsg" and "debugMsg" pattern.

2015-12-24 10:51:56.176 Log4j is ready.
[INFO ] 2015-12-24 10:51:56.176 com.myftpserver.MyFtpServer.<init>(MyFtpServer.java:65) - Log4j is ready.
2015-12-24 10:51:56.176 Configuration file is loaded
[INFO ] 2015-12-24 10:51:56.176 com.myftpserver.Configuration.load(Configuration.java:74) - Configuration file is loaded
[DEBUG] 2015-12-24 10:51:56.176 com.myftpserver.Configuration.load(Configuration.java:82) - supportPassiveMode=true
2015-12-24 10:51:56.301 User Manager class is loaded.
[INFO ] 2015-12-24 10:51:56.301 com.myftpserver.Configuration.load(Configuration.java:119) - User Manager class is loaded.
2015-12-24 10:51:56.301 File Manager class is loaded.
[INFO ] 2015-12-24 10:51:56.301 com.myftpserver.Configuration.load(Configuration.java:121) - File Manager class is loaded.
2015-12-24 10:51:56.301 Server Initialization completed.
[INFO ] 2015-12-24 10:51:56.301 com.myftpserver.MyFtpServer.<init>(MyFtpServer.java:69) - Server Initialization completed.
2015-12-24 10:51:56.301 Available passive port:[1232, 1233, 1234]
[INFO ] 2015-12-24 10:51:56.301 com.myftpserver.MyFtpServer.<init>(MyFtpServer.java:75) - Available passive port:[1232, 1233, 1234]

So, is it possible to remove duplicate item?

thank you very much and Merry X'mas

like image 779
The KNVB Avatar asked Dec 24 '15 03:12

The KNVB


People also ask

What is pattern layout in log4j2?

Layout class and overrides the format() method to structure the logging information according to a supplied pattern. PatternLayout is also a simple Layout object that provides the following-Bean Property which can be set using the configuration file: Sr.No.

How do you change the log level in log4j2?

You can set a logger's level with the class Configurator from Log4j Core. BUT be aware that the Configurator class is not part of the public API. If you wish to change the root logger level, do something like this : LoggerContext ctx = (LoggerContext) LogManager.

How do you get all Appenders in log4j2?

Enumeration appenders = logger. getAllAppenders(); . . . fileBackupIndex = rollingFileAppender. getMaxBackupIndex();

Which of the following are format characters used in log4j?

The format characters used in log4j are, L- it is used to output the line number from where the logging request was processed or issued. m- It is used to output the application supplied message related to the logging event. p- It is used to output the priority of the logging event.


2 Answers

The latest versions of Log4j2 allow a pattern selector instead of just a single pattern. Log4j provides a selector based on markers but not one based on levels. Create a Jira issue and I will add it. However, Log4j does allow you to used a script to select the pattern. It would be simple to write one that selects based on the level.

In the configuration above the debug appender is also going to output info level events, which is why you see the duplicates.

I haven't tested it but I believe the configuration below should do what you want:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout>
                <ScriptPatternSelector defaultPattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %l - %msg%n">
                    <Script name="LevelSelector" language="bsh"><![CDATA[
                        if (logEvent.getLevel() == org.apache.logging.log4j.Level.INFO) {
                            return "INFO";
                        } 
                        return null;
                        ]]>
                    </Script>
                    <PatternMatch key="INFO" pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %msg%n"/>
                </ScriptPatternSelector>
            </PatternLayout>
        </Console> 
    </Appenders>
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>
like image 84
rgoers Avatar answered Nov 14 '22 23:11

rgoers


Yes. Since log4j 2.13 there is the LevelPatternSelector. You can use it like that.

I use the error/fatal case as default pattern. You can also specify it explicite.

      <Console name="stdout" target="SYSTEM_OUT">
         <PatternLayout>
            <LevelPatternSelector defaultPattern="%highlight{[%p] %d{HH:mm:ss} %c:%L %m}{bright,red}%n">
               <PatternMatch key="WARN" pattern="%highlight{[%p] %d{HH:mm:ss} %c:%L %m}{bright,yellow}%n" />
               <PatternMatch key="INFO" pattern="[%style{%p}{blue}] %d{HH:mm:ss} %c:%L %m%n" />
               <PatternMatch key="DEBUG" pattern="[%p] %d{HH:mm:ss} %c:%L %m%n" />
               <PatternMatch key="TRACE" pattern="[%p] %d{HH:mm:ss} %c:%L %m%n" />
            </LevelPatternSelector>
         </PatternLayout>
      </Console>
like image 36
keiki Avatar answered Nov 14 '22 22:11

keiki