Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Log4j 2 root logger overrides everything?

I am relatively new to Log4j 2. Currently, I have this configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <File name="DebugFile" fileName="../../logs/debug.log">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </File>
    <File name="BenchmarkFile" fileName="../../logs/benchmark.log">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </File>
  </Appenders>
  <Loggers> 
    <Logger name="com.messaging.main.ConsoleMain" level="debug">
      <AppenderRef ref="DebugFile"/>
    </Logger>
    <Logger name="com.messaging.main.ClientMain" level="debug">
      <AppenderRef ref="BenchmarkFile"/>
    </Logger>   
    <Root level="error">
      <AppenderRef ref="DebugFile"/>
    </Root>
  </Loggers>
</Configuration>

If I log something in these two classes ConsoleMain and ClientMain via a static Logger

    static Logger _logger = LogManager.getLogger(ClientMain.class.getName());

and

    static Logger _logger = LogManager.getLogger(ConsoleMain.class.getName());

they ALWAYS use the appender and level of the root logger. If the level of the root logger is "error" as above, it never shows any debug level logging output, even if the level of the individual loggers is debug. Also, it always appends to the log file specified in the root logger and not the one specified in the logger of the classes.

So, it seems that the root logger somehow overrides everything. How do I get log4j to actually use the appender and the level of the loggers of the classes?

I tried removing the appender of the root, but then it does not log anything.

Thank you!

like image 875
Danny Schweizer Avatar asked Oct 06 '13 15:10

Danny Schweizer


1 Answers

I tried your setup but I cannot reproduce the issue. Here is the code I used:

package com.messaging.main;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ClientMain {
    public static void main(String[] args) throws Exception {
        Logger logger = LogManager.getLogger(ClientMain.class);
        logger.debug("debug from ClientMain");
    }
}

package com.messaging.main;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ConsoleMain {
    public static void main(String[] args) throws Exception {
        Logger logger = LogManager.getLogger(ConsoleMain.class);
        logger.debug("debug from ConsoleMain");
    }
}

when I run these with your exact config file I get the following output:

benchmark.log:

07:59:51.070 [main] DEBUG com.messaging.main.ClientMain - debug from ClientMain

debug.log:

07:59:51.070 [main] DEBUG com.messaging.main.ClientMain - debug from ClientMain
07:59:58.306 [main] DEBUG com.messaging.main.ConsoleMain - debug from ConsoleMain
07:59:58.306 [main] DEBUG com.messaging.main.ConsoleMain - debug from ConsoleMain

This is expected behaviour. The duplicate entries are normal as by default additivity is true in log4j, so both the Root logger and the named Loggers will log the same message (see http://logging.apache.org/log4j/2.x/manual/configuration.html#Additivity). I'm not seeing the issue you are reporting that debug-level messages never appear in the log file when the Root level is "error".

Perhaps something else is going on. What version of log4j2 are you using (most recent is now beta9)? Can you also try to reproduce the issue with the bare minimum sample code above and see if the issue still occurs?

like image 61
Remko Popma Avatar answered Oct 05 '22 01:10

Remko Popma