The Ever Confusing Business of Logging in Java

I’ve been programming Java for almost 8 years now and I still haven’t fully figured out this logging problem. Log4j, slf4j, commons-logging, JCL, JUL, logback… Why are there so many? Does this really have to be so complicated? How did we end up here? Which logging framework to use?

Let’s try to start from a humble beginning. This is essentially the problem we’re trying to solve:

System.out.println("Hello world!");

Yes.. logging is all about getting your code to produce some sort of text when an interesting event happen. The value of this can be priceless, especially when you’re debugging your code, or monitoring a production environment.

So what’s wrong with System.out.println

System.out.println is probably the easiest and most widely used logging ever, and thank God for it has taught so many new programmer how to print a text to console. But printing to console alone is not good enough, since a console can only hold so much information and the information get wiped out pretty quickly.

Also depending on the stage of your software development, a logging statement might (no longer) become useful. A System.out.println("YES this function is called"); is very useful early when you’re still writing your code, but you don’t want it to keep printing once it’s deployed to production, and you don’t want to have to recompile your code just to add/remove logging statement. Trust me, in some (poorly managed) organisations you’d be amazed to see how much fear, hysteria, anxiety and stress people get just by hearing the fact that you need to “recompile and release new version of the code”.

Enter the world of logging library

Hence why we use logging libraries. Common features of logging libraries are:

  1. Ability to assign LEVEL to your logging statement to indicate the urgency of the statement
  2. To filter logging statement only from specific subset of modules / level
  3. And to configure where the output goes: console, text file, database, etc

Here’s an example of logging statement being printed by a class:

import org.apache.log4j.Logger;

public class FiddleService() {

  private static final Logger LOG = Logger.getLogger(FiddleService.class);

  public void doFiddle() {
    LOG.debug("fiddling..");
  }

}

As you can see the class above is explicitly dependant upon log4j logging library. Apart from log4j, JUL (Java Util Logging)

Good developers don’t reinvent the wheel

Yes, we Java developers don’t like reinventing the wheel. Being one of the first cross-platform language, Java really took this concept to the next level since all of a sudden everyone can write libraries regardless what OS / processor / computers they’re running, and that library become usable by everyone else.

However sometimes this creates a situation where the same problem being solved multiple times by several competing libraries. Logging is one good example of this.

Logging libraries are unique in the sense that almost all other libraries depend on a logging library of some sort. And the lack of built-in logging abstraction in Java itself has caused all this mess.

Let’s highlight this problem with some example

My awesome app uses two libraries: meow and purr. meow uses log4j for logging, and purr uses JUL (Java Util Logging). As a result now my app pulls log4j (JUL is included in JDK) transitively. If I wanted to show certain statement, I have to constantly ask the question “Hmm.. what logging library does XYZ uses again?” which is horrifying (Consider a typical java project with 40 dependency jars).

logging

Logging Facade

So to solve this problem, Logging Facade is invented. A logging facade is not a logging library by itself, but it’s just a set of interface that allows program to interact with any logging libraries.

Logging facade allows the client application to choose whatever logging provider, and simply “bridges” the logging output there. Here’s previous example refactored with slf4j logging facade:

logging2

Note that here slf4j bridges the logging into log4j, but this is entirely configurable. You can use JUL, logback or any other libraries you like.

Why slf4j?

Indeed this is a very interesting question. Apart from log4j, the other logging facade often used is JCL (Java Commons Logging). According to Ceki (the founder of log4j, slf4j and logback), slf4j is the de-facto most used logging facade in open-source community.

So if you are asking yourself, or has been asked “which logging framework to use”. I’d say the answer is slf4j. Not because it’s the best, but simply because it’s a (most widely used) facade — it allows you (or your users/customers/clients) to use whatever logging implementation they please.

Leave a Reply