Log4j 2
  1. Log4j 2
  2. LOG4J2-219

Named logger without root logger ends up with empty Appenders map - does not log anything

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0-beta5
    • Fix Version/s: 2.0-beta6
    • Component/s: Core
    • Labels:
      None

      Description

      On the log4j-user mailing list, Peter DePasquale gave this test case that demonstrates the problem:

      Note that the configuration has no root logger, but only contains a named logger.

      In a debugger I found that the LoggerConfig for "logtest.LogTest" ended up with an empty "appenders" Map<String, AppenderControl<?>>. The appenderRefs list did contain an AppenderRef object but in #callAppenders there are no AppenderControl objects to call...

      (Sorry, I have been unable to find out the underlying cause yet.)

      <?xml version="1.0" encoding="UTF-8"?>
      <configuration status="warn">
      <appenders>
      <File name="tracelog" fileName="trace-log.txt"
      immediateFlush="true" append="false">
      <PatternLayout pattern="%d

      {HH:mm:ss.SSS}

      [%t] %-5level %logger

      {36}

      - %msg%n"/>
      </File>
      </appenders>

      <loggers>
      <logger name="logtest.LogTest" level="trace">
      <appender-ref ref="tracelog"/>
      </logger>
      </loggers>
      </configuration>

      package logtest;
      import org.apache.logging.log4j.LogManager;
      import org.apache.logging.log4j.Logger;
      import org.apache.logging.log4j.core.config.XMLConfigurationFactory;

      public class LogTest {
      public static void main(String[] args)

      { System.setProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY, "log4j2-roottest.xml"); Logger logger = LogManager.getLogger(LogTest.class); logger.trace("This is a trace message"); logger.info("This is an info message"); logger.warn("This is a warning message"); }

      }

        Activity

        Hide
        Remko Popma added a comment -

        Underlying cause: BaseConfiguration will not connect appenders to Loggers if no root element is present.

        Instead, if no root element is present, it will create a default root element and connect it to a default Console appender.
        A status logger warning is emitted: "No Root logger was configured, using default".
        Further processing is skipped and other configured logger elements are not considered.

        Logger elements will only be connected to their appenders if a root element exists.
        (see o.a.l.l.c.c.BaseConfiguration.doConfigure() from line 199)

        I'm not sure what to do with this.
        The code essentially says that a root element is mandatory.
        The documentation does not say that anywhere (or did I miss something?).
        True, all examples have a root element, but those are just examples...

        Should we change the code or change the docs?

        Show
        Remko Popma added a comment - Underlying cause: BaseConfiguration will not connect appenders to Loggers if no root element is present. Instead, if no root element is present, it will create a default root element and connect it to a default Console appender. A status logger warning is emitted: "No Root logger was configured, using default". Further processing is skipped and other configured logger elements are not considered. Logger elements will only be connected to their appenders if a root element exists. (see o.a.l.l.c.c.BaseConfiguration.doConfigure() from line 199) I'm not sure what to do with this. The code essentially says that a root element is mandatory. The documentation does not say that anywhere (or did I miss something?). True, all examples have a root element, but those are just examples... Should we change the code or change the docs?
        Hide
        Ralph Goers added a comment -

        That is a good question.

        1. Obviously the warning isn't noisy enough.
        2. The concern I have on changing the code is that you would need to add a root logger that either a) does nothing, which seems odd or b) writes to the console, which may confuse users even more since they won't know why that is happening.

        I guess I'm inclined to lean towards creating a root appender that writes to the console (essentially what is happening now) and then including the user's configuration, while emitting a warning and making sure the documentation is clear on this. At the same time it would be good to know what Log4j 1.x and Logback do in this case.

        Ralph

        Show
        Ralph Goers added a comment - That is a good question. 1. Obviously the warning isn't noisy enough. 2. The concern I have on changing the code is that you would need to add a root logger that either a) does nothing, which seems odd or b) writes to the console, which may confuse users even more since they won't know why that is happening. I guess I'm inclined to lean towards creating a root appender that writes to the console (essentially what is happening now) and then including the user's configuration, while emitting a warning and making sure the documentation is clear on this. At the same time it would be good to know what Log4j 1.x and Logback do in this case. Ralph
        Hide
        Remko Popma added a comment -

        From the dev mailing list:
        ..., then to summarize my understanding for LOG4J2-219 the solution would be to:

        • internally create a root logger if one isn't explicitly configured (like in beta5)
        • this default root logger would have level ERROR (like in beta5)
        • this default root logger would not have any appenders configured (different from beta5)
        • named loggers in the config are picked up correctly and not ignored (different from beta5)
        Show
        Remko Popma added a comment - From the dev mailing list: ..., then to summarize my understanding for LOG4J2-219 the solution would be to: internally create a root logger if one isn't explicitly configured (like in beta5) this default root logger would have level ERROR (like in beta5) this default root logger would not have any appenders configured (different from beta5) named loggers in the config are picked up correctly and not ignored (different from beta5)
        Hide
        Remko Popma added a comment -

        I ended up creating a root appender that writes to the console (like in beta5) as Ralph suggested.
        The only code change was to pick up and no longer ignore the named loggers in the config.

        Added JUnit test that demonstrates the issue and passes after the change.

        Doc changes were also fairly minor: in the configuration I emphasized that a root logger must exist,
        and in the side menu I added more links to subsections in the configuration page, including a link to the Configuring Loggers section.

        Show
        Remko Popma added a comment - I ended up creating a root appender that writes to the console (like in beta5) as Ralph suggested. The only code change was to pick up and no longer ignore the named loggers in the config. Added JUnit test that demonstrates the issue and passes after the change. Doc changes were also fairly minor: in the configuration I emphasized that a root logger must exist, and in the side menu I added more links to subsections in the configuration page, including a link to the Configuring Loggers section.
        Hide
        Remko Popma added a comment -

        Fixed in revision 1479072.

        Show
        Remko Popma added a comment - Fixed in revision 1479072.

          People

          • Assignee:
            Remko Popma
            Reporter:
            Remko Popma
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development