Is Log4j being abandoned in favor of Slf4j? [closed] - java

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
It seems that log4j has some class loading issues (among others) and it seems to me the trend is to move out of log4j toward slf4j. (Hibernate stopped using the first in favor of the latter)
Is it true?
What are the main issues in log4j that slf4j solves?
Is slf4j the final word or is there even a better "the next next log4j" industry standard?
Update:
So this answer by delfuego confuses me, can you accept / object it?:
You appear to have stumbled upon the
major problem with log4j (and the
Apache Commons Logging library),
namely that they have a ridiculously
hard time discovering and interacting
with the right classloaders as they're
being used. There's a very dense
explanation, complete with examples,
here; the take-home message is that
one of the primary driving forces for
the new logging framework SLF4J was to
eliminate these issues entirely. You
might want to swap it in and see if
your life is made any easier.
More classloading issues by log4j: http://articles.qos.ch/classloader.html

Slf4j is indeed just a logging facade. However, Log4j is intended to be succeeded by Logback, from the very same authors.
Update: if you'd like to know about another benefit of Slf4j, it's the fact that following (ugly) constructs aren't needed anymore to avoid the toString() unnecessarily been called:
if (logger.isDebugEnabled()) {
logger.debug("Message: " + bigObject + ", " + anotherBigObject);
}
You can instead make use of parameterized messages:
logger.debug("Message: {}, {}", bigObject, anotherBigObject);
Also see What is the fastest way of (not) logging?

Slf4J is not an alternative for Log4j, but rather provides a Façade for logging, so one can you can plug in your own logging framework. It's mainly useful for libraries.
from slf4j.org:
The Simple Logging Facade for Java or
(SLF4J) serves as a simple facade or
abstraction for various logging
frameworks, e.g. java.util.logging,
log4j and logback, allowing the end
user to plug in the desired logging
framework at deployment time.
To answer your question: Slf4j is being adopted by frameworks now, but in your projects, you can keep on using Log4J (or any other)

First: an important point: Slf4j is the frontend logging (the API), which can use below most of the main loggin systems: log4j or java.util.logging for instance. So it is better to compared sfl4j to commons-logging.
About the state of Log4j, quotes from The state of java logging (one year ago)
One thing that I hadn't realized is that log4j development is essentially dead. It's currently at version 1.2, and plans for version 1.3 were abandoned in favour of developing log4j 2.0. However, it doesn't appear that 2.0 is in active development. It is worth noting that Ceki Gülcü, the original founder of the log4j project, has moved on to slf4j (see below).

Looking at the slf4j page it doesn't look like it would replace log4j - it would just allow you to use the same underlying logging framework (e.g. log4j) for your whole application, allowing libraries to hook into that automatically.
It looks more like a replacement for Apache Commons Logging than log4j.

SLF4J has, in my opinion, the huge advantage that you can unify the logging of all the libraries that you use through the bridges that it provides. Neither of the other logging frameworks allows this. This allows projects to smoothly move to SLF4J and ignore the logging framework choices that dependencies have made.

Slf4j is not a real logging facade.
Slf4j does not support many features of its implementors.
For short, I mention log4j examples below.
Slf4j cannot specify a user selected configuration file, but forces user to use default (log4j.properties or log4j.xml) at one of so many Java roots (each Jar has one root plus JVM root and classes or bin). If two JAR files have it, it is hard to control which one to use safely.
Slf4j cannot support all Log4j levels, such as 'fatal'. When switch big code from Log4j to Slf4j, huge code change effort is needed (e.g. deciding how to rearrange levels).
Two key Jar files (log4j-over-slf4j.jar or slf4j-log4j12.jar) must be chosen. If classpath both, won't work. If choose one randomly, lose unexpected features (e.g. log4j-over-slf4j.jar does not support multiple log files for same classes; e.g. one for events log and one for raw data log).

Related

migrating a project from log4j to slf4j+log4j

I have a large web project that uses log4j directly, together with many 3rd-party libraries and a mix of logging libraries.
our code base - uses log4j directly.
Hibernate - uses slf4j, and the slf4j-log4j binding.
Spring - uses commons-loggings. Thus, it uses the jcl-over-slf4j bridge api, slf4j itself, and slf4j-log4j binding.
Other numerous libraries, using either commons loggings or log4j.
I am considering migrating our own code base to slf4j api, but I am not sure if the benefits are strong enough and worth the effort. Currently I am aware of the following benefits:
Cleaner api.
Performance improvements - namely the ability to use parameterized logging methods.
Ability to switch easily to logback in the future (currently logback is out of the question).
No need for additional jars, since I already have them.
Are there any other benefits? Are there any drawbacks that I am not aware of yet?
The only benefit I see for switching, is that you can funnel all the logging frameworks through only one framework, which might simplify your configuration.
Probably the main reasons why I moved to slf4j (this only applies to slf4j + logback) is that you can reload the configuration via JMX, which is GREAT when you have a problem that disappears with a server restart.
For me, there were four "killer" features which were worth the pain in moving over to Logback, on top of the ones you already mentioned (I personally switched my current major project, working flawlessly):
Automatic reloading of config files. This is awesome for production systems. If you just want to set "debug" to one class, but not bring down the whole system, this one is priceless.
Ability to use include files in the config. This allows you to have a "master" set of logging settings for all your services/JVMs, and then you can specify any packages which might require special processing. We have about ~10 services currently, and they have all a large, but mostly similar, copy of log4j.xml. We're now changing it to one master logback config file, and have that file included in every service's logback config file. The master file will still be large, but the service-specific ones should be very small. Much more maintainable.
Conditional processing. This way you can specify things like "if QAServer => then set logging levels to "DEBUG", else "INFO". Again, great for having a single config that doesn't have to change between production and dev/QA servers.
Automatic compression and deletion of old log files. You can specify how many archived files you want to keep, and optionally compress them. After creating the n+1 file, it will detect that there's one too many, and will delete the oldest one. Again, configurable per file/service, no need to do anything system-specific (batch files and/or scripts).
By the way, after doing this change, it's trivially easy to switch back to log4j. Since migrating to Logback required using SLF4J, which Log4j also supports, switching back and forth only requires you to choose which jar file to drop (Log4j's or Logback's). As long as the corresponding log4j.xml or logback config files are in the classpath, logging will work correctly.

What is the issue with the runtime discovery algorithm of Apache Commons Logging

Dave Syer (SpringSource) writes in his blog:
Unfortunately, the worst thing about commons-logging, and what has made it unpopular with new tools, is also the runtime discovery algorithm.
Why? What is the issue with its runtime discovery algorithm? Performance?
Why? What is the issue with its runtime discovery algorithm? Performance?
No, it's not performance, it's classloader pain. JCL discovery process relies on classloader hacks to find the logging framework at runtime but this mechanism leads to numerous problems including unexpected behavior, hard to debug classloading problems resulting in increased complexity. This is nicely captured by Ceki (the author of Log4J, SLF4J and Logback) in Think again before adopting the commons-logging API (which also mentions memory leaks problems observed with JCL).
And this is why SLF4J, which uses static bindings, has been created.
Ceki being the author of SLF4J, you might think his articles are biased but, believe me, they are not and he is providing lots of references (evidences) to prove his point.
To sum up:
Yes, JCL is known to be broken, better stay away from it.
If you want to use a logging facade (not all projects need that), use SLF4J.
SLF4J provides a JCL-to-SLF4J bridge for frameworks still using JCL like Spring :(
I find Logback, Log4J's successor, to be a superior logging implementation.
Logback natively implements the SLF4J API. This means that if you are using Logback, you are actually using the SLF4J API.
See also
Commons Logging was my fault
Think again before adopting the commons-logging API
SLF4J Vs JCL / Dynamic Binding Vs Static Binding
Commons logging is a light weight logging facade which is placed on top of the heavy weight logging API be that log4j, java.util.logging or another supported logging API.
The discovery algorithm is what commons logging uses to determine what logging API you use at runtime so it can direct log calls through its API to the underlying logging API. The benefit of this is that if you wanted to create a library that does logging, you do not want to tie down users of your library to any particular heavy weight logging system. Callers of your code can configure logging via log4j, java.util.logging etc. and commons logging will forward to that API at runtime.
Common gripes for commons logging:
Even though you don't use it, a library you depend on might so you have to include it in your classpath anyway.
Runs the discovery algorithm for each classloader you want to do logging in, which can produce unwanted results so make sure you put commons-logging.jar in the right classloader.
Greater complexity than the underlying logging framework.
Less features that underlying logging framework.
A perceived greater complexity as well as unpredictability in complex classpath hierarchies without any perceived benefits make users of commons-logging agitated. Given also that this choice may be forced on you does not make users sympathetic. See this article for a compelling argument against using commons-logging.
I can't speak about the "believed unpopular" aspect, I can only speak for myself:
Commons Logging is a facade over top of whatever your "real" logging framework may be: Log4j, Logback or whatever.
The idea of a logging facade is that your app gains the flexibility to decide at runtime which logging implementation it wants to work with. The facades are clever enough to find logging implementations at runtime.
My older Java apps use Log4j, directly. Works fine, I see no need to change them. My newer Java apps will probably use Logback. I think the ability to dynamically choose a logging framework is something none of my apps will ever need. Of course, other peoples' mileage may vary.
EDIT: Looks like I was wrong about the rationale for Commons Logging. The links given by #Pascal Thivent, especially the first one, explain this far better.
Commons Logging contains logic to determine at runtime whether to use log4j or java.util.logging.*.
That code used to be seriously broken, essentially only working with JUL.
Based on the experiences with this, slf4j was written which uses static binding (or used to, Im not sure with version 1.6) to choose the appropriate framework to use of log4j, JUL or the log4j fork logback (and more), and it includes a bridge to allow existing Commons Logging code to use slf4j transparently.
If you can, then go for slf4j.

Logging Facade or Logger in an Application for a newcomer

I am at the point for my little test-webapplication that I need some logging. I have no real experience in log4j nor java.util.logging and I was thinking if I should start right away with a logging facade (slf4j).
I was reading that a logging facade should be used for libraries that are shared (frameworks) which makes sense. But in case if a particular application I am not sure where to go. Would it be better to use log4j (or logback) directly due to performance? Or should I start with slf4j right away since I dont know the others anyway?
Thanks
Log4j, Java Logging are logging frameworks (A)
SLF4J, Commons-Logging are logging-facade frameworks (B)
www.slf4j.org/faq.html#when
Even when you use anything in list (B) above you still need to give it an underlying actual logger implementation (which is something from list A) for it to work properly.
So if you are doing a library which you will ship to someone (and you don't know which of the frameworks they will use from list A) THEN you should go for something in list B (SLF4J being the ideal)
If you are doing a standalone app then in all probability log4j (from list A) should solve your purpose.
For a standalone application I would start with Jakarta Commons Logging together with log4j.
I don't recommand java.util.logging, as finding a configuration mistake with it is a nightmare. The best choices are:
log4j for backend
commons-logging (more popular) or slf4j (more recent) for frontend
UPDATE: this recent blog entry can help you choose decent / recent / usable logging frontend and backend
SLF4J was created as an improvement to log4j, issues addressed include performance and, i think the most beneficial, the ability to plug in a logging framework at deployment time.
I suggest you start with the first, log4j, its very simple and will make understanding SJF4J easier as well.

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

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)?'
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.
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.
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.
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
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.
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.
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.

Java Logging vs Log4J [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Is it still worth to add the log4j library to a Java 5 project just to log
let's say some exceptions to a file with some nice rollover settings.
Or will the standard util.logging facility do the job as well?
What do you think?
I'd say you're probably fine with util.logging for the needs you describe.
For a good decision tree, have a look at Log4j vs java.util.logging
Question One :
Do you anticipate a need for any of the clever handlers that Log4j has that JUL does not have, such as the SMTPHandler, NTEventLogHandler, or any of the very convenient FileHandlers?
Question Two :
Do you see yourself wanting to frequently switch the format of your logging output? Will you need an easy, flexible way to do so? In other words, do you need Log4j's PatternLayout?
Question Three :
Do you anticipate a definite need for the ability to change complex logging configurations in your applications, after they are compiled and deployed in a production environment? Does your configuration sound something like, "Severe messages from this class get sent via e-mail to the support guy; severe messages from a subset of classes get logged to a syslog deamon on our server; warning messages from another subset of classes get logged to a file on network drive A; and then all messages from everywhere get logged to a file on network drive B"? And do you see yourself tweaking it every couple of days?
If you can answer yes to any of the above questions, go with Log4j. If you answer a definite no to all of them, JUL will be more than adequate and it's conveniently already included in the SDK.
That said, pretty much every project these days seems to wind up including log4j, if only because some other library uses it.
I recommend that you use the Simple Logging Facade for Java (SLF4J). It supports different providers that include Log4J and can be used as a replacement for Apache Commons Logging.
Log4j has been around for a long time, and it works very well. I have no scientific study to back it, but based on what I've seen at a large number of clients, it is easily the logging framework that I see used more than any other. It has been around for a long time, and not been replaced by the Next Big Logging Framework, which says something.
It is dead simple to set up, and easy to learn the basic appenders (outputs). There are a whole host appenders that are available, including:
ConsoleAppender
DailyRollingFileAppender
ExternallyRolledFileAppender
FileAppender
JDBCAppender
JMSAppender
NTEventLogAppender
RollingFileAppender
SMTPAppender
SocketAppender
SyslogAppender
TelnetAppender
WriterAppender
Plus others. It isn't difficult to write your own appender either. Additionally there is a great deal of flexibility in each of the appenders that allow you to control specifically what is output in your log.
One note, I had a series of classloader problems when I used apache commons logging in addition to log4j. It was only for one specific application, but I found it simpler to use log4j alone, rather than to have the flexibility offered when using an abstraction layer like commons logging.
See this article for
more details:
Good luck!
java.util.logging offers a comprehensive logging package without the excess baggage some of the others provide..
log4j is a much nicer package overall, and doesn't have some of the hiccups that java.util.logging contains. I'd second that using log4j directly is easier than using the commons logging.
I recommend using Apache Commmons Logging as your logging interface. That way you have the flexibility to switch logging implementations anytime you want without requiring any code changes on your end.
I would go with log4j. The possibilites with log4j is not obsolete at all!

Categories