'Using log4j.xml, log specific file or package at debug everything else at error

I'd like to setup my log4j.xml file to log specific classes/packages at DEBUG level and the rest at ERROR level.

As you can see below I updated the logging level to info for gov.xxxx.app.batch.thread and gov.xxxx.app.batch.sms.DoWork to info.

However it looks like the threshold takes precedence (which makes sense). Is there a way to make it so that the class/package level config takes precedence over the threshold? Or another approach that would yield the desired result?

log4j.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>

        <appender name="console" class="org.apache.log4j.ConsoleAppender">
                <param name="threshold" value="all"/>
                <layout class="org.apache.log4j.PatternLayout">
                        <param name="conversionPattern" value="%d  %p  %c %L - %m%n"/>
                </layout>
        </appender>

        <appender name="logFile" class="org.apache.log4j.DailyRollingFileAppender">
                <param name="file" value="${app.batchdriver.home}/logs/${app.batchdriver.log.name}"/>
                <param name="maxFileSize" value="5MB"/>
                <param name="maxBackupIndex" value="20"/>
                <param name="threshold" value="error"/>

                <layout class="org.apache.log4j.PatternLayout">
                        <param name="conversionPattern" value="%d  %p  %c %L - %m%n"/>
                </layout>
        </appender>

        <!-- Logger for Batch classes -->
        <logger name="gov.xxxx.app">
                <level value="error"/>
        </logger>

        <!-- Logger for Spring classes -->
        <logger name="org.springframework">
                <level value="error"/>
        </logger>

        <!-- Logger for Hibernate classes -->
        <logger name="org.hibernate">
                <level value="error"/>
        </logger>

        <!-- Logger for Apache classes -->
        <logger name="org.apache">
                <level value="error"/>
        </logger>

        <!-- Logger for Apache classes -->
        <logger name="net.sf">
                <level value="error"/>
        </logger>

        <!-- Logger for testing Performance -->
        <logger name="gov.xxxx.app.batch.thread">
                <level value="info"/>
        </logger>
        <logger name="gov.xxxx.app.batch.sms.DoWork">
                <level value="info"/>
        </logger>
        <root>
                <priority value ="all" />
                <appender-ref ref="console"/>
                <appender-ref ref="logFile"/>
        </root>

</log4j:configuration>


Solution 1:[1]

If I understand your requirements correctly you want to log:

  1. everything to console
  2. errors to logFile + INFO logs from specific packages

If that is the case you need to do following:

  1. remove threshold (or make it INFO) on logFile appender
  2. remove <appender-ref ref="logFile"/> from root logger because root logger specifies "all" and you do not want that
  3. add to all loggers which you want to see in logFile

Sources

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

Source: Stack Overflow

Solution Source
Solution 1 hoaz