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.
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.
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.
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.
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
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.
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.
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.
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.
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.
In chronological order of api apperance (as far as I know):