Are there technical reasons to prefer using logback instead of log4j?

JavaLoggingLog4jLogback

Java Problem Overview


Should new projects use logback instead of log4j as a logging framework ?

Or with other words :'Is logback better than log4j (leaving the SLF4J-'feature' of logback beside)?'

Java Solutions


Solution 1 - Java

You should use SLF4J+Logback for logging.

It provides neat features like parametrized messages and (in contrast to commons-logging) a Mapped Diagnostic Context (MDC, javadoc, documentation).

Using SLF4J makes the logging backend exchangeable in a quite elegant way.

Additionally, SLF4J supports bridging of other logging frameworks to the actual SLF4J implementation you'll be using so logging events from third party software will show up in your unified logs - with the exception of java.util.logging that can't be bridged the same way that other logging frameworks are.

Bridging jul is explained in the javadocs of SLF4JBridgeHandler.

I've had a very good experience using the SLF4J+Logback combination in several projects and LOG4J development has pretty much stalled.

SLF4J has the following remaining downsides:

  • It does not support varargs to stay compatible with Java < 1.5
  • It does not support using both parametrized message and an exception at the same time.
  • It does not contain support for a Nested Diagnostic Context (NDC, javadoc) which LOG4J has.

Solution 2 - Java

The author (of both Logback and Log4j) has a list of reasons to change at http://logback.qos.ch/reasonsToSwitch.html.

Here are a few that stuck out at me;

  • Faster implementation

    Based on our previous work on log4j, logback internals have been re-written to perform about ten times faster on certain critical execution paths. Not only are logback components faster, they have a smaller memory footprint as well.

  • Automatic reloading of configuration files

    Logback-classic can automatically reload its configuration file upon modification. The scanning process is both fast and safe as it does not involve the creation of a separate thread for scanning. This technical subtlety ensures that logback plays well within application servers and more generally within the JEE environment.

  • Stack traces with packaging data

    When logback prints an exception, the stack trace will include packaging data. Here is a sample stack trace generated by the logback-demo web-application.

    14:28:48.835 [btpool0-7] INFO c.q.l.demo.prime.PrimeAction - 99 is not a valid value java.lang.Exception: 99 is invalid
    at ch.qos.logback.demo.prime.PrimeAction.execute(PrimeAction.java:28) [classes/:na] at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431) [struts-1.2.9.jar:1.2.9] at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236) [struts-1.2.9.jar:1.2.9] at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432) [struts-1.2.9.jar:1.2.9] at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) [servlet-api-2.5-6.1.12.jar:6.1.12]
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502) [jetty-6.1.12.jar:6.1.12] at ch.qos.logback.demo.UserServletFilter.doFilter(UserServletFilter.java:44) [classes/:na] at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1115) [jetty-6.1.12.jar:6.1.12] at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:361) [jetty-6.1.12.jar:6.1.12] at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:417) [jetty-6.1.12.jar:6.1.12] at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230) [jetty-6.1.12.jar:6.1.12]

    From the above, you can recognize that the application is using Struts version 1.2.9 and was deployed under jetty version 6.1.12. Thus, stack traces will quickly inform the reader about the classes invervening in the exception but also the package and package versions they belong to. When your customers send you a stack trace, as a developer you will no longer need to ask them to send you information about the versions of packages they are using. The information will be part of the stack trace. See "%xThrowable" conversion word for details.

    This feature can be quite helpful to the point that some users mistakenly consider it a feature of their IDE.

  • Automatic removal of old log archives

    By setting the maxHistory property of TimeBasedRollingPolicy or SizeAndTimeBasedFNATP, you can control the maximum number of archived files. If your rolling policy calls for monthly rollover and you wish to keep one year's worth of logs, simply set the maxHistory property to 12. Archived log files older than 12 months will be automatically removed.

There may be a bias there, but the same guy did write both frameworks and if he is saying use Logback over Log4j he's probably worth listening to.

Solution 3 - Java

I would use slf4j for logging in all cases. This allow you to choose which actual logging backend you want to use, at deploy time instead of code time.

This has proven to be very valuable to me. It allows me to use log4j in old JVM's, and logback in 1.5+ JVM's, and also java.util.logging if needed.

Solution 4 - Java

Logback more Java EE aware:
in general (from code to documentation) it’s keeping in mind containers – how multiple apps coexist, how class loaders implemented etc. Contexts for loggers, JNDI, JMX configuration included etc.

from developer prospective almost same, Logback adds Parameterized logging (no need to use if(logger.isDebugEnabled()) to avoid string concatenation overhead )

Log4j – only giant plus is old JVM support, small (IMO) NDC (Logback only MDC), some extensions. For example I wrote extension for configureAndWatch for Log4j, no such thing for Logback

Solution 5 - Java

the original log4j and logback were designed and implemented by the same guy.

several open source tools have used SLF4J. I don't see any significant deficiencies in this tool. So unless you have a lot extensions to log4j in your codebase, I would go ahead with logback.

Solution 6 - Java

I would think that your decision should come down to the same one it would if you were deciding between using log4j or Jakarta Commons Logging - are you developing a library which will be included in other applications? If so, then it doesn't seem fair to force users of your library to also use your logging library of choice.

If the answer is no, I would just go with what is simpler to add and what you are more comfortable with. Sounds like logback is just as extensible and reliable as log4j, so if you're comfortable using it, go ahead.

Solution 7 - Java

I'm not familiar with SLF4J, and I've only taken a brief look at logback, but two things come to mind.

First, why are you excluding a tool from examination? I think it's important to keep an open mind and examine all possibilities to choose the best one.

Second, I think that in some projects one tool is a better than another tool, and the opposite might be true in a different project. I don't think that one tool is always better than another tool. There is, after all, no silver bullet.

To answer your question - Yes and no. It depends on the project, and how familiar the team is with one tool. I wouldn't say "don't use log4j" if the entire team is very comfortable with it, it meets all the needs, and logback doesn't offer anything that we need to complete the task.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTimmiBView Question on Stackoverflow
Solution 1 - JavaHuxiView Answer on Stackoverflow
Solution 2 - JavaJames McMahonView Answer on Stackoverflow
Solution 3 - JavaThorbjørn Ravn AndersenView Answer on Stackoverflow
Solution 4 - JavawebstrangerView Answer on Stackoverflow
Solution 5 - JavaanjanbView Answer on Stackoverflow
Solution 6 - Javamatt bView Answer on Stackoverflow
Solution 7 - JavaThomas OwensView Answer on Stackoverflow