[ https://issues.apache.org/jira/browse/LOG4J2-441?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14031319#comment-14031319 ]
Anthony Baldocchi commented on LOG4J2-441: ------------------------------------------ This is definitely a significant deviation from Log4j 1.2 behavior as I understand it with regard to log level behavior. In Log4j 1.2, the logger levels didn't act as filters from parent logger to child logger but instead determination of logger level was determined by checking the leaf logger for level and iterating up parents until a level value or the root logger was reached. So, for example, if level 1 logger configuration specified INFO level, level 2 specified DEBUG level, and level 3 specified TRACE level, then with additivity disabled, logging to level 3 would allow messages from TRACE->FATAL, to level 2 would allow DEBUG->FATAL, and level 1 would allow INFO->FATAL. The way it works currently, if level 1 logger configuration specifies INFO level, then level 2 and level 3 loggers will both only allow INFO->FATAL level log messages even though their configurations specify DEBUG and TRACE respectively. Was this behavior different by design? I don't recall seeing any documentation that called this behavior out. With regard to the level on AppenderRef new functionality, my understanding of how this is supposed to work is that once a decision is made to log to a particular logger, the level on the AppenderRef could further filter log events to allow different appenders to handle different subsets of log messages; whether a parent's AppenderRef level will apply to a child logger only matters if the child either has additivity enabled (in which case the level should only apply when the log event is processed by the parent logger) or does not specify an AppenderRef (in which case the parent's AppenderRefs apply). I think from the chart given above that the AppenderRef behavior matches expectations, although it would take further testing with much more targeted scenarios to validate. > logger level configuration does not work correct > ------------------------------------------------ > > Key: LOG4J2-441 > URL: https://issues.apache.org/jira/browse/LOG4J2-441 > Project: Log4j 2 > Issue Type: Bug > Components: Core > Reporter: Andreas Rytina > Assignee: Ralph Goers > Attachments: log4j2.xml.row1, log4j2.xml.row10, log4j2.xml.row11, > log4j2.xml.row12, log4j2.xml.row13, log4j2.xml.row2, log4j2.xml.row3, > log4j2.xml.row4, log4j2.xml.row5, log4j2.xml.row6, log4j2.xml.row7, > log4j2.xml.row8, log4j2.xml.row9 > > > Configuring the loglevel in the logger does not work in combination with > configuring the loglevel at the appender-refs. I analyzed this with the > beta9. See the table which lists various loglevel configurations for the 3 > loggers. The column format for the table is: > Column 1-6 are the logger with their level config (level@logger1, > level@appender-ref)(level@logger2, level@appender-ref)(level@logger3, > level@appender-ref) > Column 7 is the actual output > Column 8 is the expected Output > For instance the first row of the table shows a logging result which I not > expected in that way. You can take log4j2.xml.row1 to reproduce the first > row. The first logger is named "com". The second logger is named > "com.log4jtest" and the third logger is named "com.log4jtest.test". This > looks like a bug in log4j 2.0: > Logger1 considers the levels {info, debug, warning} but not the level trace. > {color:red}What is the default level, if there is no level defined at the > logger header and also not at the appender-ref?{color} Here it seems that the > Logger1 has the level debug as default which is not clear for me. For me it > would make sense if the default level is either OFF or ALL when there is no > explicit level set. But either way there should be a clear rule for this. The > other rows are showing similar inconsistent logging behaviour. > |1|2|3|4|5|6|7|8| > ||level 1 logger||level 1 appender-ref||level 2 logger||level 2 > appender-ref||level 3 logger ||level 3 appender-ref||actual output||expected > output|| > |-|-|-|info|debug|debug|Logger3: info logger > Logger2: info logger > Logger1: info logger > Logger3: debug logger > Logger1: debug logger > Logger3: warning logger > Logger2: warning logger > Logger1: warning logger|Logger3: info logger > Logger2: info logger > Logger3: debug logger > Logger3: warning logger > Logger2: warning logger| > |-|-|-|info|-|debug|no output|Logger3: info logger > Logger2: info logger > Logger3: debug logger > Logger3: warning logger > Logger2: warning logger| > |-|-|info|info|-|debug|no output|Logger3: info logger > Logger2: info logger > Logger3: debug logger > Logger3: warning logger > Logger2: warning logger| > |fatal|fatal|info|info|-|debug|no output|Logger3: info logger > Logger2: info logger > Logger3: debug logger > Logger3: warning logger > Logger2: warning logger| > |info|info|info|info|-|debug|no output|Logger3: info logger > Logger2: info logger > Logger1: info logger > Logger3: debug logger > Logger3: warning logger > Logger2: warning logger > Logger1: warning logger| > |debug|debug|info|info| |debug|no output|Logger3: info logger > Logger2: info logger > Logger1: info logger > Logger3: debug logger > Logger3: warning logger > Logger2: warning logger > Logger1: warning logger| > |info|debug|info|info|-|debug|no output|Logger3: info logger > Logger2: info logger > Logger1: info logger > Logger3: debug logger > Logger3: warning logger > Logger2: warning logger > Logger1: warning logger| > |debug|info|info|info|-|debug|no output|Logger3: info logger > Logger2: info logger > Logger1: info logger > Logger3: debug logger > Logger3: warning logger > Logger2: warning logger > Logger1: warning logger| > |debug|trace|info|info|-|debug|no output|Logger3: info logger > Logger2: info logger > Logger1: info logger > Logger3: debug logger > Logger3: warning logger > Logger2: warning logger > Logger1: warning logger| > |-|-|info|info|fatal|debug|no output|Logger2: info logger > Logger2: warning logger| > |-|-|info|info|trace|debug|Logger3: info logger > Logger2: info logger > Logger1: info logger > Logger3: debug logger > Logger1: debug logger > Logger3: warning logger > Logger2: warning logger > Logger1: warning logger > Logger1: trace logger|Logger3: info logger > Logger2: info logger > Logger3: debug logger > Logger2: warning logger| > |-|-|-|info|trace|debug|Logger3: info logger > Logger2: info logger > Logger1: info logger > Logger3: debug logger > Logger1: debug logger > Logger3: warning logger > Logger2: warning logger > Logger1: warning logger > Logger1: trace logger|Logger3: info logger > Logger2: info logger > Logger3: debug logger > Logger2: warning logger| > |-|-|info|-|trace|debug|Logger3: info logger > Logger2: info logger > Logger1: info logger > Logger3: debug logger > Logger1: debug logger > Logger3: warning logger > Logger2: warning logger > Logger1: warning logger > Logger1: trace logger|Logger3: info logger > Logger2: info logger > Logger3: debug logger > Logger2: warning logger| > Here is the log4j2.xml: > {code:xml} > <?xml version="1.0" encoding="UTF-8" ?> > <configuration> > <appenders> > <console name="TestConsole0"> > <PatternLayout pattern="RootLogger: %msg%n"/> > </console> > <console name="TestConsole1"> > <PatternLayout pattern="Logger1: %msg%n"/> > </console> > <console name="TestConsole2"> > <PatternLayout pattern="Logger2: %msg%n"/> > </console> > <console name="TestConsole3"> > <PatternLayout pattern="Logger3: %msg%n"/> > </console> > </appenders> > > <loggers> > <logger name="com" > > <appender-ref ref="TestConsole1" /> > </logger> > > <logger name ="com.log4jtest" level="info"> > <appender-ref ref="TestConsole2" level="info"/> > </logger> > > <logger name ="com.log4jtest.test" level="fatal"> > <appender-ref ref="TestConsole3" level="debug"/> > </logger> > > <root level="error"> > <appender-ref ref="TestConsole0" level="error"/> > </root> > </loggers> > </configuration> > {code} > And here are the logging calls: > {code:title=Log4j2LogLevelTest.java|borderStyle=solid} > package com.log4jtest.test; > import static org.junit.Assert.*; > import org.apache.logging.log4j.LogManager; > import org.apache.logging.log4j.Logger; > import org.junit.Test; > public class Log4j2LogLevelTest { > private static final Logger logger = > LogManager.getLogger(Log4j2LogLevelTest.class); > > @Test > public void testLogLevel() { > logger.info("info logger"); > logger.debug("debug logger"); > logger.warn("warning logger"); > logger.trace("trace logger"); > } > } > {code} -- This message was sent by Atlassian JIRA (v6.2#6252) --------------------------------------------------------------------- To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org