top of page
Search
  • Ralph Goers

Log4j 1 Compatibility in Log4j 2

Log4j 2 introduced many architectural changes from Log4j 1 including:

  • Components are plugins and use difference interfaces than Log4j 1.

  • Log4j logs Messages instead of Objects. Because Messages render themselves Log4j 2 does not support Renderers.

  • Log4j uses a LoggerContext instead of a LoggerRepository.

These changes meant that Log4j 1 Filters, Layouts, and Appenders could not directly be used out of the box in Log4j 2, nor could a Log4j 1 configuration be directly used by Log4j 2. However, staring with the Log4j 2.13.0 release Log4j can now process Log4j 1 configuration files and utilize some Logj4 1 Appenders, Filters and Layouts.


From its earliest releases Log4j 2 provided a Log4j 1 API adapter that allowed applications that coded to the Log4j 1 logging methods to have those calls routed to Log4j 2. This adapter also provided stubs for various Log4j 1 components so that applications that had references to Log4j 1 implementation classes would still compile and run, although those references generally did nothing. Log4j 2.13.0 has extended this support to do the following:

  • Provide ConfigurationFactories for the Log4j 1 XML and Properties syntax.

  • Provide bridges from some of the Log4j 1 standard components to Log4j 2 standard components.

  • Provide adapters to allow some Log4j 1 Appenders, Filters and Layouts to be called when an event is logged.

As an example, when the following Log4j 1 configuration is processed:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
  <appender name="console" class="org.apache.log4j.ConsoleAppender">
    <param name="Target" value="System.out"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
    </layout>
  </appender>

  <appender name="A1" class="org.apache.log4j.FileAppender">
    <param name="File"   value="target/temp.A1" />
    <param name="Append" value="false" />
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%-5p %c{2} - %m%n"/>
    </layout>
  </appender>

  <appender name="A2" class="org.apache.log4j.FileAppender">
    <param name="File" value="target/temp.A2" />
    <param name="Append" value="false" />
    <layout class="org.apache.log4j.TTCCLayout">
      <param name="DateFormat" value="ISO8601" />
    </layout>
  </appender>

  <logger name="org.apache.log4j.xml">
    <level value="trace" />
    <appender-ref ref="A1" />
  </logger>

  <root>
    <priority value ="trace" />
    <appender-ref ref="A1" />
    <appender-ref ref="A2" />
  </root>

</log4j:configuration>

it will be treated exactly as if this Log4j 2 configuration had been provided:

<Configuration status="ERROR">
    <Appenders>
        <Console name="console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n"/>
        </Console>
        <File name="A1" fileName="target/temp.A1" append="false">
           <PatternLayout pattern="%-5p %c{2} - %m%n"/>
        </File>
        <File name="A2" fileName="target/temp.A2" append="false">
           <PatternLayout pattern="$d{ISO8601} %p - %m%n"/>
        </File>
    </Appenders>
    <Loggers>
        <Logger name="org.apache.log4j.xml" level="trace">
            <AppenderRef ref="A1"/>
        </Logger>
        <Root level="trace">
            <AppenderRef ref="A1"/>
            <AppenderRef ref="A2"/>
        </Root>
    </Loggers>
</Configuration>

In other words, Log4j 2 is converting each of the Log4j 1 components to the Log4j 2 component that best matches. This avoids Log4j needing to bring in a lot of Log4j 1 classes but it does have some consequences:

  • The output from some Log4j 2 Layouts, such as XmlLayout, may not match the output from the Log4j 1 version.

  • Some components, such as the SocketAppender, do not work the same way in Log4j 2. In particular the SocketAppender can only send log events using Java serialization. Log4j 2 discourages this so the SocketAppender was not included.

The Log4j 2 support for Log4j 1 will also support some custom Appenders, Layouts, and Filters, so long as those classes do not require Log4j 1 classes that have not been included in Log4j 2.


Support for Log4j 1 configurations and components in Log4j 2 is considered to be experimental and is not enabled by default. To cause Log4j to scan for both Log4j 2 and Log4j 1 configuration files a system property of "log4j1.compatibility" must be set to a value of "true". To force Log4j 2 to use a specific Log4j 1 configuration set the "log4j.configuration" system property to the location of the configuration file.






7,926 views

Recent Posts

See All

Identifying the set of events to be logged

Recently one of the talented engineers I work with submitted a pull request for review where he wanted to temporarily capture more diagnostic information in the service he was working on. The informat

Why was Log4j 2 created?

From time to time I have come across comments asking the very question posed above. Why another logging framework when SLF4J and Logback already exist? For those who are curious, here is the answer.

bottom of page