Log4j2 why would you use it over log4j?

JavaLoggingLog4jLog4j2

Java Problem Overview


I must be missing something but I have been looking at this for a few days now, but why on earth would you ever use log4j2 over log4j (other than the performance)?

From what I have seen so far, log4j2 is advertised as simpler to configure, but its actually vastly more complicated (been three days now and I still cant get it to write a log in my home directory). The auto configuration simply does not work for me (or at least I cant get it to work), the configuration file itself is substantially more complex in its structure and appears to be much harder to add things in at runtime to help diagnose.

So other than the performance is there any reason to use log4j2 over original log4j?

Java Solutions


Solution 1 - Java

Reasons to upgrade from Log4j 1.x to Log4j 2

> Update: since August 2015, Log4j 1.x is officially End of Life and it is recommended to upgrade to Log4j 2. Update 2: Log4j 1.2 is broken in Java 9.

  • Community support: Log4j 1.x is not actively maintained, whereas Log4j 2 has an active community where questions are answered, features are added and bugs are fixed.
  • Async Loggers - performance similar to logging switched off
  • Custom log levels
  • Automatically reload its configuration upon modification without losing log events while reconfiguring.
  • Java 8-style lambda support for lazy logging
  • Log4j 2 is garbage-free (or at least low-garbage) since version 2.6
  • Filtering: filtering based on context data, markers, regular expressions, and other components in the Log event. Filters can be associated with Loggers. You can use a common Filter class in any of these circumstances.
  • Plugin Architecture - easy to extend by building custom components
  • Supported APIs: SLF4J, Commons Logging, Log4j-1.x and java.util.logging
  • Log4j 2 API separate from the Log4j 2 implementation. API supports more than just logging Strings: CharSequences, Objects and custom Messages. Messages allow support for interesting and complex constructs to be passed through the logging system and be efficiently manipulated. Users are free to create their own Message types and write custom Layouts, Filters and Lookups to manipulate them.
  • Concurrency improvements: log4j2 uses java.util.concurrent libraries to perform locking at the lowest level possible. Log4j-1.x has known deadlock issues.
  • Configuration via XML, JSON, YAML, properties configuration files or programmatically.

Be aware

  • log4j2.xml and log4j2.properties formats are different from the Log4j 1.2 configuration syntax
  • Log4j 2 is not fully compatible with Log4j 1.x: The Log4j 1.2 API is supported by the log4j-1.2-api adapter but customizations that rely on Log4j 1.2 internals may not work.
  • Java 6 required for version 2.0 to 2.3. Java 7 is required for Log4j 2.4 and later.

Tips when upgrading

Common issues people are having when getting started with log4j2:

  • You need (at least) both log4j-api-2.6.2.jar and log4j-core-2.6.2.jar in your classpath
  • Log4j2 looks for a log4j2.xml config file, not a log4j.xml config file
  • Config file location: either put it in the classpath or specify its path with the log4j.configurationFile system property
  • To debug the configuration, use <Configuration status="trace"> in the beginning of your config file
  • I would recommend starting with one of the many sample configurations provided in the log4j2 manual, then add more bells and whistles bit by bit.

If your problem is not one of the above, please show your config and provide more detail on what problem you are experiencing. (Not sure what you expect from auto-configuration, this is a very basic function that logs ERROR events to the console if log4j2 cannot find a configuration file. This will rarely be sufficient.)

To write to your home directory, you can use the system property lookup ${sys:PROPERTYNAME}. Below is an example configuration to demonstrate:

<Configuration status="trace">
  <Properties>
    <Property name="logfile">${sys:user.home}/log${date:yyyyMMdd}.log</Property>
  </Properties>
  <Appenders>
    <Console name="STDOUT" target="SYSTEM_OUT">
      <PatternLayout pattern="%m%n"/>
    </Console>
    <File name="FILE" fileName="${sys:logfile}">
      <PatternLayout>
        <pattern>%d %p [%t] %c{1.} %m%n</pattern>
      </PatternLayout>
    </File>
  </Appenders>
  <Loggers>
    <Root level="trace">
      <AppenderRef ref="STDOUT" level="ERROR" />
      <AppenderRef ref="FILE" />
    </Root>
  </Loggers>
</Configuration>

Solution 2 - Java

Check this. In short, from the link:

>Log4j 2.0 introduces: > > * a new plugin system > > * support for properties > > * support for JSON-based configuration and automatic reloading of its configuration. > > Support for many existing logging frameworks, including SLF4J, Commons Logging, Apache Flume and Log4j 1.x, and provides a new programmer’s API.

As you said it's also much faster.

Disadvantages are:

  • log4j 2.0 is very different than log4j 1.x, and the API is mostly incompatible.

  • Difficult to set up.

If you don't need any of the new features, you're probably fine with the older Log4j 1.x.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionScott NevilleView Question on Stackoverflow
Solution 1 - JavaRemko PopmaView Answer on Stackoverflow
Solution 2 - JavaJonasCzView Answer on Stackoverflow