0
votes

I have a log4j.properties file on the classpath. I have 2 appenders. One is the base root appender. The other is a file appender and only a single associated logger. As soon as the number of loggers defined in the log4j.properties file gets above 5, log4j fails to associate the file appender with the appropriate logger.

For example:

log4j.rootLogger=DEBUG, console

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p %-60c %x - %m%n

log4j.logger.logger.1=WARN
log4j.logger.logger.2=FATAL
log4j.logger.logger.3=INFO
log4j.logger.logger.4=INFO
log4j.logger.logger.5=TRACE
log4j.logger.logger.6=FATAL

log4j.appender.audit=org.apache.log4j.RollingFileAppender
log4j.appender.audit.File=/tmp/audit/audit.log
log4j.appender.audit.MaxBackupIndex=99999
log4j.appender.audit.layout=org.apache.log4j.PatternLayout
log4j.appender.audit.layout.ConversionPattern=%d :: %m%n

log4j.category.face.audit=TRACE, audit
log4j.additivity.face.audit=false
log4j.logger.face.audit=TRACE

For a simple test that uses this configuration via slf4j:

public class TestMe {
    public static final Logger LOGGER = LoggerFactory.getLogger(TestMe.class);
    public static final Logger AUDIT = LoggerFactory.getLogger("face.audit");
    static {
        AUDIT.trace("AUDIT!");
    }

    @Test
    public void testConfig() throws Exception {}
}

This results in:

log4j:WARN No appenders could be found for logger (face.audit).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

If I comment out a ANY SINGLE logger (or more), it works. As soon as the number of loggers (not counting the one assigned to the face.audit category) gets above 5, this fails.

Any suggestions would be appreciated.

1

1 Answers

0
votes

It turns out the problem is defining BOTH a category as well as a logger for the same name.

log4j.category.face.audit=TRACE, audit
...
log4j.logger.face.audit=TRACE

It seems that how this works depends on the order that the properties are parsed. Changing the entries in the properties changes the order in which they end up being parsed since they're just stored on a Properties object (HashMap) so the order they end up traversed in is arbitrary but deterministic depending on the key hash values.

EDIT: category is deprecated (and has been for a long time). The right answer here is to only have:

log4j.logger.face.audit=TRACE, audit

... and no category entry.