log4jfileappenderlog-level

log4j isolating certain level from a class


I want to ask something on log4j. I have this config file for log4j on activemq. My problem is that I want to log all INFO level messages from every class I have, but I want to log all DEBUG level messages from "TransportConnection" class to a different file and, at the same time, log all only messages that are greater or equal to WARN level, to the rootLogger.

The problem with this configuration is that I log INFO level messages from "TransportConnection" class in the rootLogger. I want to pass only the WARN and above level to the rootLogger.

I dont want to set a Threshold to the "out" appender, because I want INFO level messages from other classes.

log4j.rootLogger=INFO,out

# Log these warnings
log4j.logger.org.apache.activemq.broker.BrokerRegistry=INFO
log4j.logger.org.apache.activemq.broker.TransportConnection=DEBUG,tc

# Standard logging
log4j.appender.out=org.apache.log4j.RollingFileAppender
log4j.appender.out.file=/var/lib/activemq/log/activemq.log
log4j.appender.out.maxFileSize=10240KB
log4j.appender.out.maxBackupIndex=100
log4j.appender.out.append=true
log4j.appender.out.layout=org.apache.log4j.PatternLayout
log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n

# Transport Connections logging
log4j.appender.tc=org.apache.log4j.RollingFileAppender
log4j.appender.tc.file=/var/lib/activemq/log/tc.log
log4j.appender.tc.maxFileSize=10240KB
log4j.appender.tc.maxBackupIndex=100
log4j.appender.tc.append=true
log4j.appender.tc.layout=org.apache.log4j.PatternLayout
log4j.appender.tc.layout.ConversionPattern=%d [%t] %-5p %-30.30c{1} - %m%n

Solution

  • You could write your own custom filter. I suggest that implementation could be something like that:

    public class MinLevelForParticularClassFilter extends Filter {
    
        private boolean acceptOnMatch = false;
        private Level level;
        private String className;
    
        @Override
        public int decide(LoggingEvent event) {
            if (this.className != null && this.level != null) {
                if (event.getLocationInformation().getClassName().startsWith(className)) {
                    // this is event for specified class
                    if (!event.getLevel().isGreaterOrEqual(this.level)) {
                        // level of event is less than specified level
                        return Filter.DENY;
                    }
                }
            }
    
            if (acceptOnMatch) {
                return Filter.ACCEPT;
            } else {
                return Filter.NEUTRAL;
            }
        }
    
        public boolean isAcceptOnMatch() { return acceptOnMatch; }
        public void setAcceptOnMatch(boolean acceptOnMatch) { this.acceptOnMatch = acceptOnMatch; }
    
        public Level getLevel() { return level; }
        public void setLevel(Level level) { this.level = level; }
    
        public String getClassName() { return className; }
        public void setClassName(String className) { this.className = className; }
    }
    

    Note that if you change "className" variable to "packageName" variable, the implementation will be the same for filter by particular package.

    The log4j configuration in XML (since filters are unsupported by configuration in property files):

    <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
        <appender name="out" class="org.apache.log4j.RollingFileAppender">
            <param name="File" value="activemq.log" /> 
            <param name="MaxFileSize" value="10240KB" />
            <param name="MaxBackupIndex" value="100" />
            <param name="Append" value="true" />
            <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern" value="%d [%-15.15t] %-5p %-30.30c{1} - %m%n"/> 
            </layout>
    
            <!-- Apply filter to appender that's destined for root logger -->
            <filter class="com.foo.log4j.filters.MinLevelForParticularClassFilter">
                <param name="Level" value="WARN" />
                <param name="ClassName" value="org.apache.activemq.broker.TransportConnection" />
                <param name="AcceptOnMatch" value="true" />
            </filter>
    
        </appender>
    
        <appender name="tc" class="org.apache.log4j.RollingFileAppender">
            <param name="File" value="tc.log" /> 
            <param name="MaxFileSize" value="10240KB" />
            <param name="MaxBackupIndex" value="100" />
            <param name="Append" value="true" />
            <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern" value="%d [%t] %-5p %-30.30c{1} - %m%n"/> 
            </layout>
        </appender>
    
        <logger name="org.apache.activemq.broker.BrokerRegistry">
            <level value="INFO" />
        </logger>
        <logger name="org.apache.activemq.broker.TransportConnection">
            <level value="DEBUG" />
            <appender-ref ref="tc" />
        </logger>
        <root> 
            <priority value ="INFO" /> 
            <appender-ref ref="out" /> 
        </root> 
    </log4j:configuration>