6
votes

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!

1
At first I thought the problem was with the log4j concept of "Additivity", but after re-reading your problem statement I'm less sure. (Just in case, here is the link: logging.apache.org/log4j/2.x/manual/… ) You mention that both logs appear in the same file. Root and ConsoleLogger both point to the same file in your config, so the only issue left is ClientLogger. Still strange...Remko Popma
Thanks for the comment. It just always takes the file from the Root, so if I change it to BenchmarkFile, it will also log to BenchmarkFile in the Console Logger, so the issue is not (only) the Client Logger.Danny Schweizer

1 Answers

1
votes

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?