Tuesday, 16 October 2012

Understanding Logging Frameworks In Java

Logging in Java is about reporting issues at runtime in an application. Information about an issue is collected, then formatted and at last handled by an issue handler. This handler may display the issue (log record) on a screen, report it in a file or in a database. These log records can be tagged for severity and filtered too.

History

Over time, several logging frameworks were created by different parties for Java. Therefore, Java libraries were written using different logging frameworks. This was not an issue if an application used a unique logging framework, but when they started to reference each other's libraries, it became a different game.

This is why logging interfaces were created to bridge these multiple logging frameworks. The purpose is to centralize logs calls to one framework.

Log4J

Log4J is a login framework which was created before Sun Microsystems introduced its own logging framework (called JUL of JDK Logger) in Java 1.4. Many developers chose to stick to Log4J, rather than move to the JDK Logger, because it contained better features.

However, after logging interfaces were created, some people became wary of Log4J, because it is very low level. They were using Java libraries using different frameworks. Many decided to use logging interfaces, rather than directly implementing Log4J in their code.

Java Logging API (JUL or JDK Logger)

This logging framework is available in the java.util.logging package since Java 1.4. It can be extended via the API. Many developers complained about too many logging levels: FINE, FINER, FINEST where DEGUG would have been enough, or missing features which Log4J was already offering.

Some developers also complained this framework was not well designed for web containers. For example, some containers, such as Tomcat, provided access to a common root logger shared by multiple applications. If a filter was set on it, it was set for all applications.

Jakarta Commons Logging API (JCL)

JCL is a logging interface developed by Apache. It aims at bridging different logging frameworks (Log4J, JUL, ...) through a discovery process at runtime. Unfortunately, some fundamental issues were reported, especially in multi-classloader contexts. See here for a detailed discussion.

SLF4J

SLF4J stands for Simple Logging Facade for Java, it is a logging interface. Per se, one must configure a target logging framework which will receive calls made to SLF4J. It is also possible to use bridges for third parties libraries using a different logging framework. For example, the JUL bridge to SLF4J will forward every third party log call made to JUL to SFL4J, which will call the configured logging framework.

Logback

Logback is the introduced as the successor of Log4J. It implements SLF4J natively, which improves performance dramatically in some cases. It can be used as the target framework for SLF4J.

Conclusion

There are many logging frameworks we have not covered here. Today, the safe strategy, for an application referencing 3rd party libraries using different logging frameworks, is SLF4J with corresponding bridges. For performance, configuring Logback as the target of SLF4J is a good choice.

3 comments:

  1. I have never understood why it was necessary to use anything other than log4j, which solved logging elegantly and simply. The Sun JDK 1.4 implementation of logging in particular seemed like an imitation that offered no real improvement. I use log4j in my own applications and have no plans to change.

    ReplyDelete
  2. Facade frameworks exist because people who write libraries often unthinkingly include specific loggers in their code. You, the application programmer, may have chosen Log4J for your project. Now, you choose a library that uses java.util.logging. If you do nothing, you will end up with two sets of log configuration files, and two sets of log files.

    In this case, you can use a bridge library with classes named the same as the java.util.logging classes. These forward JUL calls to your logger.

    If you are writing a library, please use a facade system so the application programmer can choose whatever real logger he wants.

    ReplyDelete
  3. Log4J is old hat, effectively unsupported now, and noticeably slower than Logback.

    You can smooth migration to a better logger by using the SLF4J logging facade with the SLF4J Log4J target, then gradually migrate all you logging statement to SLF4J facade Loggers; when completed you can choose any SLF4J logger target, including custom ones.

    SLF4J has provision to pass thread level key/value pairs and markers, these are useful for extra logging values and much more flexible log filtering; Logback supports these features.

    Logback also has wonderful features like system property use by the logging configuration XML (e.g. to reference a logger path relative to the Tomcat folder) and bundles rolling logger file features like automatic zipping up of old log files.

    ReplyDelete