Apache has announced version 1 of Log4j has reached end of life. Although Log4j version 2 was released in July 2014, version 1 was maintained until early August 2015. The new version is a full rewrite of the logging library, addressing many of the issues of version 1 and achieving unprecedented performance. Apache has made an effort to ease the upgrade, although advanced users may need some migration work.

As reported by Apache, Log4j version 1, a logging framework first released on 1999, had a number of architectural problems and release process deficiencies that made development rather hard. This motivated some of the community developers that maintained Log4j to leave the framework and start working on other projects like Logback, encouraging users to do the same. For this reason, Apache decided to write Log4j version 2 from scratch, overcoming the deficiencies of the first version and recovering some of the community base.

Despite the benefits of Log4j version 2, adoption has been slow so far. According to statistics from maven central, at the time of writing this article there were about 350 artefacts using Log4j version 2, while the count for version 1 reaches nearly 6000; in comparison, the number of artefacts using Logback is over 5000.

In order to overcome this, Apache has tried to make the upgrade process as simple as possible. For the cases where Log4j is being used through a logging facade like SLF4J, the upgrade is just a matter of swapping the binding jar file from slf4j-log4j12 to log4j-slf4j-impl-2.0, removing all references to Log4j version 1, and adding the implementation jar file for version 2. For cases where Log4j is being used directly, users should refer to Apache’s migration guide, which provides two alternatives: converting all calls to the new API, or using a bridge jar file that will capture all the calls made to infrastructure in Log4j version 1 and forward them to Log4j version 2.

Unfortunately, the bridge file will not work for users who have defined their own Appenders, Filters, etc., since these now work differently in Log4j version 2. For instance, in Log4j version 1, one would have to extend AppenderSkeleton and implement the inherited methods to define a custom Appender, however, in Log4j version 2, custom Appenders are created as plugins that need to be registered. Given that a conversion effort will have to take place, a full migration to the new version may be a better option in this scenario.

On the other hand, users who are wary about transitive dependencies may find some surprises when adding Log4j version 2. As reported by some users, the new version of the logging framework may pull in up to 30 direct dependencies, however, further inspection reveals that most of them are either in test scope or optional, meaning the actual footprint added in a production environment doesn’t have to big bigger than just two direct dependencies.

Simpler Alternatives

Users with very basic logging needs may be able to save the trouble of having to choose between different logging frameworks or having to handle upgrades: Java includes a logging facility as part of package java.util.logging since Java 4 (1.4). This facility isn’t as efficient as libraries like Log4j or Logback and falls behind in terms of functionality, but the fact that is included in the standard OpenJDK makes it a suitable option for a number of cases.