views:

1830

answers:

16

Per the title, do you find the default Java logging framework sufficient for your needs?

Do you use alternative logging services such as log4j or others? If so, why? I'd like to hear any advice you have regarding logging requirements in different types of projects, and when integrating frameworks is actually necessary and/or useful.

+1  A: 

We use log4j with commons logging. I think we just use them because everyone else does. That and we were using log4j before the jdk supported logging.

Edit: The just because everyone else does was a joke, but probably why I started out with log4j and commons logging.

Here are some reasons to use commons logging.

ScArcher2
Normally, only people developing a component will opt to use commons logging. Someone developing a standalone application usually will not use commons logging.
Eddie
Ditto for me - log4j with Apache Commons Logging. For the life of me, I can't understand why Sun didn't simply adopt log4j as the standard and be done with it.
duffymo
Commons logging have had some serious class loader issues with the logging framework discovery code. In complex scenarios, you may run into problems.
Thorbjørn Ravn Andersen
Rod Waldhoff apologized for having developed Commons Logging: http://radio.weblogs.com/0122027/2003/08/15.html SLF4J is a wonderfull alternative.
Jim Ferrans
+10  A: 

SLF4J is the new kid. I've done a little work with it and it's pretty nice. It's main advantage is parametrized logging, which means you do this:

logger.debug("The new entry is {}. It replaces {}.", entry, oldEntry);

Rather than this:

logger.debug("The new entry is " + entry + ". It replaces " + oldEntry + ".");

And all that string manipulation is done only if the statement is actually logged. Looks cleaner too.

It should be noted that SLF4J is a wrapper like commons-logging, though it claims to be less prone to commons-logging's classloader problems.

sblundy
could build that on top of the "standard" logging with message formatters.
TofuBeer
Yeah. That's pretty much what the authors of SLF4J did. It's nice to have someone else do the work though.
sblundy
actually the main advantage of SLF4J over log4j is that is a thread safe library
Boris Pavlović
Log4j is also thread safe according to their FAQ.
ScArcher2
I don't know why SL4J would invent their own message format rather than (shock) using java.util.Formatter. Makes no sense.
cletus
SLF4J's message formatter is 10 times faster than java.util.Formatter. It actually makes a measurable difference at the end.
Ceki
@Ceki - really? So I'm better off using slf4j's logging methods than for example commons-logging with debug(String.format("%d %s %s" anInt, aString, anotherString))?
Chochos
@Ceki, perhaps you could link to the performance measurements you made back then?
Thorbjørn Ravn Andersen
I like the parametrized logging but you could always use String.format.A little longer I know:logger.debug(String.format("The new entry is %s. It replaces %s", entry, oldEntry))
Shawn
+1  A: 

I thought I'd use log4j -- as mentioned by @ScArcher2, just because everyone does. But after dealing with both options, I found out java.util.logging is far enough sufficient for most of my needs -- and I am talking about a huge system with many spread components working together.

So, in my opinion, there is no need to use alternative services. Java.util.logging is powerful enough for most cases.

Paulo Guedes
+6  A: 

Unless there is a compelling reason to use something outside of the JDK I prefer to use what is provided by Sun.

Many of the projects that use the Log4J logging were using it before the "standard" logging API existed.

TofuBeer
+3  A: 

I was unable to figure out how to control the logging level of individual classes in the java.util.logging framework, something that is possible in log4j. If I'm having trouble diagnosing a bug or there is a high-traffic class that logs important information, I can change the level for a single class to log more and leave the rest of my classes relatively quiet.

N.B. It could be that I couldn't figure out how to do it, or java.util.logging could have changed since I tried.

Michael Sharek
+1 I found controlling java.util.logging to be bewildering and as far as I oculd tell, I couldn't just set one class to debug level logging.
cletus
When you say "just one class", you mean "just one logger" right? It really is pretty easy in jul. Use logger.level=FINE (or whatever) in the config file and make sure that the handler level is at that level or finer
oxbow_lakes
@oxbow_lakes: no. For example you can tell log4j that every logging statement in Foo class at DEBUG or higher should come out, and every logging statement in Bar class should only come out if it's FATAL or higher...very useful if you want to see what Foo is doing without any noise from Bar
Michael Sharek
Java logging also has a distinction between the log level of the class and the log level that the handler will output. You can change it to fine but it doesn't come out. Change the handler to output fine instead of info and you get lots of noise you're not interested in. Its bizarre.
cletus
A: 

One of the problems I have with ALL logging frameworks is that unless everyone on your team spends the time to become proficient at exactly how to set it up and control it, you never know if a given debug statement will print out or not.

You may have a level (debug) turned off, or you may have one package turned off.

I've wasted too much time assuming that a debug statement would print and it doesn't. Now I mostly rely on System.out.println() and just go through and delete or convert them when I'm done debugging.

I know this doesn't answer your question--I'm just saying that you may want to consider how much justification you have before adding complexity.

Logging isn't that complicated and is certainly justified on most larger projects.

Bill K
Given a high enough debugging level, how can a logger.debug("something") statement not print?
Yuval A
If you aren't an expert with the given logger, how do you know your logging level is high enough. This isn't a problem when you're always on the same loggers, but after using 5 each with a custom interface (some set in Eclipse, some in xml, some in properties), I just have trouble trusting.
Bill K
A: 

Personally I use Simple Logger, but at work I use our corporate wrapper to the JDK logger. I use Simple Logger, due to the ease of getting it set up and the fact that it supports logging of 7 levels between Fatal and Ludicrous.

shrub34
+13  A: 

Logging Dependencies with Third Party Libraries

Java JDK logging in most cases is not insufficient by itself. However, if you have a large project that uses multiple open-source third party libraries, you will quickly discover that many of them have disparate logging dependencies.

It is in these cases where the need to abstract your logging API from your logging implementation become important. I recommend using slf4j or logback (uses the slf4j API) as your API and if you want to stick with Java JDK logging, you still can! Slf4j can output to many different logger implementations with no problems.

A concrete example of its usefulness happened during a recent project: we needed to use third-party libs that needed log4j, but we did not want to run two logging frameworks side by side, so we used the slf4j log4j api wrapper libs and the problem was solved.

In summary, Java JDK logging is fine, but a standardized API that is used in my third party libraries will save you time in the long run. Just try to imagine refactoring every logging statement!

Elijah
We're very happy with SLF4J too. We began by mapping java.util.logging, Log4J, Commons Logging, and SLF4J APIs into SLF4J APIs, then connected those to the Logback implementation. That only required us to drop a few JAR files in the classpath. Later we realized that generating java.util.logging messages would make it easier to process our messages in the Glassfish console: all we needed to do was replace one SLF4J jar file with another. Ceki Gülcü has put together a very elegant successor to his Log4J.
Jim Ferrans
@Jim, slf4j does not succeed log4j, logback is his fork of log4j intended to succeede log4j- slf4j is something new.
Thorbjørn Ravn Andersen
+1  A: 

java.util.logging is nice but does not have a configuration which is picked up by default from the classpath. That is rather a pain point for us as we have many deployments which does not share logging configurations and it is rather messy to do this in j.u.l.

Log4j is currently not being developed much so if there is a need for development on the backend part logback is at the moment the most dynamic option in my opinion.

(caveat: involved in some obscure development of slf4j and logback but that is due to and not causing the statements I make above :) )

Thorbjørn Ravn Andersen
Nice? Really? Even though it, for example, splits log messages across two lines? Personally I think it's an awful API.
cletus
Yes. The splitting over lines is just the default configuration - if you don't like it, change it.The ability of slf4j to use placeholders is in my opinion the real killer feature. log.debug("a={}, b={}", a, b) avoids the ifDebugEnabled check.
Thorbjørn Ravn Andersen
I still don't understand why they invented that format instead of using java.util.Formatter or MessageFormat, which could've done the same thing in either case.
cletus
MessageFormat versus slf4j was benchmarked in http://www.mail-archive.com/[email protected]/msg10119.html - the slf4j approach is much faster.
Thorbjørn Ravn Andersen
A: 

It's pretty easy to write a j.u.l LogManager class which will defer all logging to a bespoke implementation which uses Log4J. This means that you can use log4j but still have the nice feature that libraries which log using j.u.l can be controlled as-if they had used Log4J.

Having used both (and commons-logging), I have to say that the thing which really, really, really annoys me is this:

log4j.error("An Exception", e);

jul.severe("An Exception", e); // GRRR! no such method

jul.log(Level.SEVERE, "An Exception", e); //Must use this method

Why did they make this design choice? Why? The other thing is that there's no PatternFormatter which ships with j.u.l - you have to roll your own.

That said, I'm erring to use j.u.l from now on as it cuts down on external dependencies and isn't any more complicated to use.

oxbow_lakes
A: 

In the projects I work on, we tend to use commons-logging from Jakarta. That is not a logging system itself, instead it is able to wrap some of the most common loggers - log4j, java.util.logging or others.

With that, it is relatively easily possible to switch the logging based on environment the application is deployed to (a developer may want to use simplelog or java.util.logging on his machine because of ease of maintenance, while on a SIT system, log4j with a common configuration for all apps may be deployed, etc.)

david a.
+11  A: 
Huxi
Where does the log4j web pages say that logback is the official successor?
Thorbjørn Ravn Andersen
Well, I changed that bit but it certainly depends on the definition of "official". The Logback site states "Logback is intended as a successor to the popular log4j project." and since Ceki was the driving force behind log4j I'd call this pretty official. If Linus left the Linux Foundation (yes, unlikely;)) and forked a new kernel with innovative new features, I'd still call that kernel the successor of the Linux kernel, whether approved by the Linux Foundation or not. Log4j development at Apache stalled a long time ago. I'd call that project dead. Unofficially. ;)
Huxi
+3  A: 

The JDK logging facilities have always done what I need them to do - never had a problem with it.

To me, third party logging tools are neither necessary nor desirable.

John O
A: 

If you need logging in your app then youve probably done smething really wrong. I would argue that reporting the occasional problem is ok, but having debug, info etc statements in lots of classes with logic is plain wrong. Any large application with logging statements in most of its logic filled classes is going to amount to information overload even if one picks just the right loggers on. Most of the time the information will be incomplete, noisy or the actual information you need is plain missing.

Im basically saying that you should only need to write debug statements to inform the user about program reactions to external factors

  • formating problem in a text based config file.
  • Problems with opening or locating a required file.
mP
+3  A: 

We use java.util.logging throughout. Also for large projects. There is a few things you should tweak (e.g. the default formatting) but that's off the real point. I find the number of logging frameworks in Java and the feature creep they implemented rather annoying and somewhat embarassing for the Java community. The level of religuous debate about logging is a sure sign that something went seriously wrong.

What JUL gives you is a simple but sufficient API and a single place to configure what log output you want to see (logging.properties or JMX...). And its always there and stable.

All code that wants to log should stick to the standard conventions (default level is INFO) and otherwise do no more but use loggers of a meaningful name (e.g. package or class name) and you will be fine.

gnomie
+1  A: 

It all really depends on what your logging requirements are. It is not just the API that the application developers use that you look at, and frankly that's the least of the issue as logging APIs for the most part are easy to adapt no matter which choice you make.

The important part is what kind of logging configuration you require for operations and they should tell you what they require.

  1. It can be as simple as text files that roll over.
  2. It can be more complicated like logging to a JMS or database.
  3. It may require separate logs for performance, audit, etc.
  4. It may require e-mailing details when a log event happens.

Log4J in their varia package has had support for these and more and tested with their APIs. Now with java.util.logging you should be able to download them, but they are not as common knowledge as Log4J and may be harder to find information for.

Another thing to consider is the vendor API you are using. Most vendors "force upon" a logging API for you. Spring is one of them which requires commons-logging.

As a developer, I would try to use java.util.logging if I can for my own stuff, but in real world scenarios you have to shake what they would need in operations and let that drive your choice because they are the ones who have to use these logs when the application goes live. It is neither the application architect nor the developers who should make that choice, though they should make suggestions.

Archimedes Trajano