Question

I am using Tomcat 6 and trying to switch JUL to Log4j2 (2.0 beta 3). However, as it is quite a new project, the documentation is quite sparse and there are not many resources online yet.

What I want

  1. All events above debug level should go to a file on disk.
  2. Errors should go to syserr.
  3. Everything from info to warn should go to sysout.
  4. Marked audit logs should skip all this and go to a different file on disk.

What I tried

This is my first attempt log4j2.xml file:

What should I write in configuration status? Where is some documentation regarding it?

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="info">
<appenders>
    <Console name="Console-err" target="SYSTEM_ERR">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <Console name="Console-out" target="SYSTEM_OUT">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <File name="MyFile" fileName="app.log">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </File>
</appenders>
<loggers>
    <logger name="com.ecm" level="error" additivity="false">
        <appender-ref ref="Console-err" />
        <appender-ref ref="MyFile" />
    </logger>
    <root level="info">
        <appender-ref ref="Console-out" />
        <appender-ref ref="MyFile" />
    </root>
</loggers>
</configuration>

How does the logger name relate to Java classes and their loggers?

Example code:

package com.ecm.backend;

public final class Foo {
   private static final Logger LOG = LogManager.getLogger(Foo.class);

   public static void bar() {
     LOG.error("this is error");
     LOG.warn("this is warning");
   }
}

When I run this, I get this in console and the log file:

10:22:49.385 [http-8080-3] ERROR com.ecm.backend.Foo - this is error

Why is the warning ignored?

If I remove the additivity="false", I get:

10:26:51.388 [http-8080-1] ERROR com.ecm.backend.Foo - this is error
10:26:51.388 [http-8080-1] ERROR com.ecm.backend.Foo - this is error

The warning is ignored again and the error is repeated (as expected).

What am I doing wrong?


Under the fold: rest of the Tomcat can use JULI, I just want Log4j2 for my application.

Was it helpful?

Solution

If you set configuration status="debug" you will see a lot of log4j2-internal log statements about what happens during the configuration process. This may be useful to trouble-shoot configuration issues.

I usually set configuration status="warn" so I only get notifications if there is a problem.

About the relation between logger names, loggers and their java class, maybe this helps: http://logging.apache.org/log4j/2.x/manual/architecture.html

About the question why the warning is ignored, there is this logger config:

<logger name="com.ecm" level="error" additivity="false">

There also is a logger like this:

Logger LOG = LogManager.getLogger(com.ecm.backend.Foo.class);

The logger config "com.ecm" will process all calls from the LOG logger, but only the ones at "error" level or higher (fatal) will actually be logged. Log events at other levels (warn, info, debug and trace) are filtered out because their level is too low.

The way that additivity works is that first the named logger config ("com.ecm" in this case) decides whether the event should be filtered out or not. Then, if additivity="true" (the default), the event is passed on to the parent logger (in this case the root logger). Because the "warn"-level event is already filtered out by the "com.ecm" logger config it never reaches the root logger.

Not sure what you are trying to achieve, but if you want to send different event levels to different appenders, one way to do it may be to set levels on the appender-refs, not on the loggers:

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="info">
<appenders>
    <Console name="Console-err" target="SYSTEM_ERR">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <Console name="Console-out" target="SYSTEM_OUT">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <File name="MyFile" fileName="app.log">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </File>
</appenders>
<loggers>
    <logger name="com.ecm" additivity="false">
        <appender-ref ref="Console-err" level="error" />
        <appender-ref ref="MyFile" level="debug" />
    </logger>
    <root>
        <appender-ref ref="Console-out" level="info" />
        <appender-ref ref="MyFile" level="debug" />
    </root>
</loggers>
</configuration>

This will send the output of the LOG logger to MyFile and (if level is error or fatal) also to Console-err.

Output from loggers not in the "com.ecm" package will be sent to MyFile and (if level is info, warn, error or fatal) also to Console-out.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top