118

Why one would use one of the following packages instead of the other?

  • Java Logging
  • Commons Logging
  • Log4j
  • SLF4j
  • Logback
Loki
  • 29,950
  • 9
  • 48
  • 62
  • 4
    You might want to http://stackoverflow.com/questions/873051/, which compares SLF4j to Commons Logging. – James McMahon Jul 31 '09 at 20:04
  • 25
    Why the hell has Ceki created 3 logging frameworks!!! thats madness... – mP. Jan 04 '10 at 10:06
  • 6
    @mP. - log4j was the first, then disagreement arose, and slf4j+logback was written. slf4j is the _API_ and logback the implementation of the API. Regardless of everything else, slf4j is extremely useful. – Thorbjørn Ravn Andersen Apr 03 '12 at 09:13
  • 3
    For details on why Ceki Gülcü did create SLF4J+Logback see the following Devoxx talk: http://www.parleys.com/#st=5&id=1701 – Alex Bitek May 15 '12 at 19:00
  • The best thing to come out of this is the slf4j API which hopefully will unify the logging world. I think logback has not yet achieved critical mass with developers. – Thorbjørn Ravn Andersen Dec 21 '15 at 19:43

8 Answers8

89

In chronological order of api apperance (as far as I know):

  • Log4j because most everybody uses it (in my experience)
  • Commons Logging because open source projects use it (so they can integrate with whatever logging framework is used in the integrated solution); especially valid if you're an API/Framework/OSS and you rely on other packages that use Commons Logging.
  • Commons Logging because you don't want to "lock down" to a particular logging framework (so instead you lock down to what Commons Logging gives you instead) - I don't think it is sensible to decide using this point as the reason.
  • Java logging because you don't want to add in an extra jar.
  • SLF4j because it's newer than Commons Logging and provides parameterized logging:

logger.debug("The entry is {}.", entry);
//which expands effectively to
if (logger.isDebugEnabled()){
    // Note that it's actually *more* efficient than this - see Huxi's comment below...
    logger.debug("The entry is " + entry + "."); 
}
  • Logback because it's newer than log4j and again, supports parameterized logging, as it implements SLF4j directly
  • SLF4j/Logback because it's written by the same guy who did log4j, so he's made it better (according to Ken G - thanks. It seems to fit when looking at their earlier news posts)
  • SLF4j because they also publish a log4j adapter so you don't have to "switch out" log4j in older code - just make log4j.properties use SLF4j and it's configuration
Community
  • 1
  • 1
Stephen
  • 19,488
  • 10
  • 62
  • 83
  • 3
    As far as I can tell the idea behind commons logging is that it should be used in libraries. This way the library can always use the same logging framework (via commons logging) that the hosting application uses. – Joachim Sauer Dec 10 '08 at 13:29
  • Thanks heaps to Loki for the question. I now know that I'm not going to be using log4j as my default framework any more. SLF4j FTW! Also thanks to Ken G for pointing out that SLF4j is written by the same guy as log4j – Stephen Dec 10 '08 at 23:32
  • 3
    The comment in your code example isn't 100% correct. The actual formatting of the message is performed lazily by Logback so it will only happen if the event is really handled by an appender *and* the appender requires the formatted message - which wouldn't happen in case of e.g. an SocketAppender since the event is serialized using the unchanged message pattern + the arguments as Strings. I guess it just depends how you define "effectively" though. It would certainly emit the same message (at least if entry and object are the same ;)) so please forgive my nitpicking. – Huxi Jun 03 '09 at 03:32
  • 6
    SLF4J actually is just an API that sits on top of other logging frameworks. Similar to the goal of Commons Logging, but more intuitive from my experience. – James McMahon Jun 24 '09 at 17:57
38

I find logging in Java to be confusing, inconsistent, poorly documented, and especially haphazard. Moreover, there is a huge amount of similarity between these logging frameworks resulting in duplication of effort, and confusion as to what logging environment you are actually in. In particular, if you are working in a serious Java web application stack, you are often in multiple logging environments at one time; (e.g hibernate may use log4j, and tomcat java.util.logging). Apache commons is meant to bridge different logging frameworks, but really just adds more complexity. If you do not know this ahead of time, it is utterly bewildering. Why are my log messages not printing out to the console, etc.? Ohh because I am looking at the Tomcat logs, and not log4j. Adding yet another layer of complexity, the application server may have global logging configurations that may not recognize local configurations for a particular web application. Lastly, all these logging frameworks are WAY TOO COMPLICATED. Logging in Java has been a disorganized mess leaving developers like me frustrated and confused.

Early versions of Java did not have a built-in logging framework leading to this scenario.

Julien Chastang
  • 17,592
  • 12
  • 63
  • 89
  • 19
    Is this an answer? It looks more like a rant. – Michael Myers Mar 11 '09 at 21:47
  • 15
    I am sorry. It *is* a little bit of a rant. But it is also a cogent response to "What’s Up with Logging in Java?". The answer, in short, is it is deeply broken. – Julien Chastang Mar 11 '09 at 23:02
  • 1
    well it's not worth a -1 vote ;P But something to ponder about. – guyumu Mar 12 '09 at 05:35
  • 21
    The problems started when Sun actually added java.util.logging to Java 1.4. Before that LOG4J was well established and in wide use. After that there was the necessity of wrappers to support both LOG4J and java.util.logging. Also, since jul is contained in the java.* package, it can't be replaced by swapping a JAR - which is the way SLF4J bridges the other frameworks. This was probably the worst Sun idea ever... and it ultimately led to the wrong assumption that a "good Java citizen" should use jul. – Huxi Jun 03 '09 at 03:48
  • 4
    @Huxi, I maintain that the Calendar API was worse. In defense of Sun it wasn't their code, but came from Taglient. – Thorbjørn Ravn Andersen Apr 25 '12 at 07:17
22

There's one important point that wasn't mentioned before:

SLF4J (and both Logback and LOG4J as the logging backend) have support for a so called Mapped Diagnostic Context (MDC, see javadoc and documentation).

This is essentially a thread-local Map<String,String> which you can use to add additional context information to your logging event. The current state of the MDC is attached to every event.

This can be incredibly useful if you put stuff like the username and the URL of the request (in case of a webapp) into it. This can be done automatically using a filter, for example.

Huxi
  • 4,242
  • 3
  • 33
  • 31
17

See also answers to the question What are the best practices to log an error?, especially:

  • There are some potential classloading issues with Commons Logging.

  • Log4J and SLF4J were developed by the same person, learning from issues found in practice with Log4J.

Community
  • 1
  • 1
Ken Gentle
  • 13,277
  • 2
  • 41
  • 49
4

In our company project we use LOG4j and it is very easy to use like Stephen showed in his example. We also have written our own pattern classes for LOG4j so you can create your own output file schemas. You can describe how your log file should look like. It is possible to enhance the original log4j classes.

All LOG4j properties you can change in a log4j.properties file, so you can use different files for different projects.

Java logging is not my favorit, but this could be because i use log4j from the beginning.

Markus Lausberg
  • 12,177
  • 6
  • 40
  • 66
4

The Commons Logging overview gives the reason for its existence: logging from library code, when you have no control over the underlying logging framework. Very important for the various Apache projects, which will be linked into outside applications. Perhaps not so important for internal IT projects, where you have complete control.

That said, I write to Commons Logging, as do many of the other developers I know. The reason is to minimize mental baggage: you can change projects or jobs, and not have to learn a new framework (provided the new job/project also uses CL, and/or you can convince them to move to it).

Also, there is some value to creating your own wrappers around whatever framework you use. As described here, I like to use a LogWrapper object to provide custom stringification (important), and minimize the visual clutter of logging statements (less important).

kdgregory
  • 38,754
  • 10
  • 77
  • 102
  • 1
    There's also a commons.logging=>SLF4J bridge which can be used to route all CL logging over SLF4J. SLF4J supports bridging of commons.logging, LOG4J and (a bit cumbersome, but as good as possible) java.util.logging so all logs will end up in whatever SLF4J backend you'll use. See http://slf4j.org/legacy.html I'd use Logback, btw, but you could argue that I'm biased. – Huxi Jun 03 '09 at 03:38
2

Generally I would default to using Log4J.

I would use Java Logging if I didn't mind a dependency on Java 1.4 but I would still use Log4J in preference.

I would use Commons Logging if I was enhancing something that already used it.

Michael Rutherfurd
  • 13,815
  • 5
  • 29
  • 40
  • Didn't mind a dependency on 1.4?? Even 1.4 has hit its end of service life. – Tom Hawtin - tackline Jan 23 '09 at 15:47
  • 2
    @Tom He means jdk1.4+ dont be silly. – mP. Jan 04 '10 at 10:05
  • Actually I've recently done some work in a system that was still running under jdk 1.3 :-(, and it was less than two years ago I was last maintaining a **jdk 1.2** system. Too many places don't upgrade unless they absolutely have to, they just refuse to install the upgrades. – Michael Rutherfurd Jan 08 '10 at 07:29
0

I would suggest creating a thin logging facade that can write to any of the logging frameworks, at which point the choice of backing engine become pretty much a moot point.

tsimon
  • 8,362
  • 2
  • 30
  • 41
  • 2
    That is what commons logging does so why reinvent the wheel? Also there are some issues that your facade would have to handle that commons logging already does. – James A. N. Stauffer Dec 10 '08 at 04:23
  • +1 To counter commons logging argument, Some enterprise apps use custom logger. It always a good idea to hide underlying implementation. The 'thin' wrapper eliminates the need for another jar being packaged and is not as much as reinventing. – questzen Dec 10 '08 at 09:27
  • This approach is valid in many cases, especially when your code must run on an arbitrary platform. The underlying logging API tends to be different on application servers compared to Eclipse, for example. – McDowell Dec 10 '08 at 10:29
  • About hiding the underlying implementation: All the logging APIs mentioned can do just that: They are interfaces to pluggable implementations. – Thilo Dec 10 '08 at 23:47
  • 1
    This saved me recently when we ported our framework to the Compact Framework (in .Net). If we had hardcoded dependencies on nLog, we would have been screwed. Because we used this approach, we were able to drop in a null logger and be happy. Someone vote me back up to 0 Please :-) – tsimon Dec 15 '08 at 06:06
  • 3
    One already exists - take a look at slf4j. It's an accepted thin wrapper that allows you to switch logging frameworks on application startup by switching jars on the runtime classpath. – deterb Jun 09 '09 at 17:01
  • 1
    clogging has its own way of discovering what framework it will use - its not nice and rather convuluted. How many logging frameworks has Ceki created. One should always strive to slot a level of interdirection and hide an implementation even if it is clogging with your own logging. Behind the scenes you can then plugin whatever f/w you desire as mentioned by Travis. – mP. Jan 04 '10 at 10:03