Search code examples
javalogginglog4j

Lost control of log4j levels


We recently upgraded from log4j 1.* to 2.17.1 in response to the vulnerability. After making what I thought were the requisite changes to our pom.xml, etc, I found I seem to have no control over debugging levels - i.e., it seems to be stuck displaying everything from info on up, but not debug - not matter what level changes I make to my log4j.xml. Hopefully the info I include here will be enough to identify the issue(s). Thanks in advance.

log4j.xml

    <appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">
        <param name="Target" value="System.out"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%-5p] [%c{1}] [%M:%L] - %m%n"/>
        <param name="Threshold" value="DEBUG"/>
        </layout>
    </appender>

    <logger name="edu.mydomain.directory">
        <level value="debug"/>
    </logger>

    <logger name="org.apache">
        <level value="warn"/>
    </logger>

    <logger name="org.springframework">
        <level value="warn"/>
    </logger>

    <logger name="org.hibernate">
        <level value="warn"/>
    </logger>

    <root>
        <priority value="warn"/>
        <appender-ref ref="consoleAppender"/>
    </root>
</log4j:configuration>

Pom.xml

<dependency> 
                <groupId>org.apache.logging.log4j</groupId> 
                <artifactId>log4j-to-slf4j</artifactId>
                <version>2.17.1</version> 
  </dependency>
  <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>${slf4j.version}</version> 
   </dependency>

Implementation:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
…
private static Logger log = LoggerFactory.getLogger(PersonController.class);

log.info(“this appears”);
log.debug(“this doesn’t appear”);

Solution

  • To understand the issue we have to understand the logging hierarchy.

    enter image description here

    As we can see any Log level defined as Warn will not be able to see the Error or Fatal level logs but can see Info and above.

    Now coming back to your configuration. I can see you have defined log level to your packages but missed the appender-ref to it. So here log is only printed by <root> logger which is set to level warn.

    Sample logger

      <Loggers>
        <Logger name="edu.mydomain.directory" level="debug" additivity="false">
          <AppenderRef ref="consoleAppender"/>
        </Logger>
        <Root level="error">
          <AppenderRef ref="consoleAppender"/>
        </Root>
      </Loggers>
    

    It is always good to have the root logger defined to level error. Additivity is also very important, if not set then log would be printed multiple times for each level.
    Once an event reaches a logger with its additivity set to false the event will not be passed to any of its parent loggers, regardless of their additivity setting.

    For more information, you can refer the link below:

    1. Hierarchy and Architecture
    2. Configuration