1

My simple question is : If I have two statements like logger.info() and logger.error() in Java (using log4j), I want the results of these two lines to be printed in two separate files. That is, logger.info(...) should print to a file say myLog.info and logger.error(...) should print to myLog.error file. I am using rolling file appender for this task. Also I want just one logger object to do the task. Someone might suggest two or more different loggers one for each file, but that's not the case.

I tried searching a solution for the problem. One of the links Creating multiple log files of different content with log4j says about "threshold" and I even tried to add threshold in my xml configuration file. But what it actually is doing that : info log is being printed in myLog.info file but error log gets printed in both the files. Can it be done through xml configuration file alone or a separate properties file is needed? If xml file is sufficient, then what needs to be done?

I am preferring xml file over properties file. If there is a working solution using only xml configuration file, that would be sufficient. Thanks in advance.

Community
  • 1
  • 1
Dhruv Singhal
  • 145
  • 2
  • 17

1 Answers1

2

You could use filters to deny any messages except those of the level you want. Here is an example of how to do this:

First a class to test our efforts:

package test;
import org.apache.log4j.Logger;

public class Main {

    private static final Logger logger = Logger.getLogger(Main.class);
    public static void main(String[] args) {
        logger.debug("here's some debug");
        logger.info("here's some info");
        logger.warn("here's some warn");
        logger.error("here's some error");
        logger.fatal("here's some fatal");
    }

}

Next a log4j.xml config file to set up the appenders and loggers:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
    <appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %-5p  [%c{1}] %m %n" />
        </layout>
    </appender>

    <appender name="debugLog" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="logs/debug.log" />
        <param name="Append" value="true" />
        <param name="MaxFileSize" value="5000KB" />
        <param name="maxBackupIndex" value="5" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p - %m%n" />
        </layout>

        <filter class="org.apache.log4j.varia.LevelMatchFilter">
            <param name="LevelToMatch" value="DEBUG" />
            <param name="AcceptOnMatch" value="true" />
        </filter>

        <filter class="org.apache.log4j.varia.DenyAllFilter" />
    </appender>

    <appender name="infoLog" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="logs/info.log" />
        <param name="Append" value="true" />
        <param name="MaxFileSize" value="5000KB" />
        <param name="maxBackupIndex" value="5" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p - %m%n" />
        </layout>

        <filter class="org.apache.log4j.varia.LevelMatchFilter">
            <param name="LevelToMatch" value="INFO" />
            <param name="AcceptOnMatch" value="true" />
        </filter>

        <filter class="org.apache.log4j.varia.DenyAllFilter" />
    </appender>

    <logger name="test" additivity="false">
        <level value="DEBUG" />
        <appender-ref ref="consoleAppender" />
        <appender-ref ref="debugLog" />
        <appender-ref ref="infoLog" />
    </logger>
</log4j:configuration>

This pattern will allow you to generate a separate log for each log level, just repeat the configuration that I have provided for either debug or info logging. Note that the console appender will accept all levels.

I was able to gain some insight from this post so I thought I should give credit.

Community
  • 1
  • 1
D.B.
  • 4,523
  • 2
  • 19
  • 39
  • I searched for the solutions but none mentioned the way using level matching filter. This one worked very well. Thanks. :) – Dhruv Singhal Oct 10 '16 at 08:18