Which Logging Facility for Swing Applications?
Just to give some context, I'm recapping how I've used logging frameworks in my projects so far:
- In the beginning, I used log4j.
- Circa 2001, if I remember well, I started using commons-logging, still configured with log4j. At the time I was mostly doing server-side applications; the limited amount of projects I was doing in Swing probably didn't have logging at all.
- In 2004, I was still using commons-logging, but being more involved in Jini made me more comfortable with java.util.logging.
- Since 2005/2006, I've only been using java.util.logging, partly because I dramatically increased the percentage of my Swing projects, partly because most of the server-side stuff I've been doing recently shares lots of components with my desktop projects.
Since a few months, blueMarine has been using a very simple customized version of java.util.logging: the only new feature is that every method accepts a varargs-style such as in PrintWriter.printf():
import it.tidalwave.logger.Logger;
...
Logger logger = Logger.getLogger("name");
int x = ...;
String s = ...;
logger.fine(">>>> x=%d, s=%s", x, s);
Not only this is much more readable than concatenating string literals and variables with the + operator, but it's also faster when the log is disabled. In fact the implementation of the logging methods is encapsulated in a if (...) that tests for the current logging level; this means that string concatenations are only executed when the logging is needed:
package it.tidalwave.logger;
public class Logger
{
private java.util.logging.Logger delegate = ...;
public void fine (String pattern, Object ... args)
{
if (delegate.isLoggable(Level.FINE))
{
delegate.fine(String.format(pattern, args));
}
}
}
In contrast, the direct use of java.util.logging forces passing a single message concatenated with +, which always makes use of string concatenation, even though the result will be thrown away because the related logging level is disabled. That's why, in performance critical sections, people uses to encapsulate java.util.logging in application code including the test for the level as in:
if (logger.isLoggable(Level.FINE))
{
logger.fine(...);
}
But this style introduces a lot of extra verbosity in code, making it less readable.
I don't like re-inventing the wheel, so my custom logger will be eventually replaced by SLF4J, which - among other things - offers a similar pattern-oriented logging style; furthermore, its pluggable design makes it possible to send the log data to a number of different targets. I'm not doing this immediately only because I have other priorities in blueMarine.
So, from a point of view, I would not be against the use of SLF4J in BetterBeansBinding. The only thing that worries me is that this solution introduces a dependency, while BeansBinding at the moment has got *no* dependencies. Consider that one of the constraints of BBB is to be able to work as a "drop in" replacement for BeansBinding, and with SLF4J you'd need to replace an existing jar file with TWO jar files.
So, I see the following options:
- Use java.util.logging (single jar, but verbose code)
- Copy a customized logger, similar to the one in blueMarine, to BBB (single jar, readable code, but a few classes to cut and paste, and a sensation of NIH).
- Use SLF4J and live with the dependency (multiple jars, readable code, no cut and paste).
- Use SLF4J and deliver a "OneJAR" version of BBB embedding SLF4J classes (sounds as "all pros and no cons").
Solution #4 should be compliant with the BBB and SLF4J licenses (LGPL 2.1 and MIT-like) and it's the one that I like more at the moment, but I have to check. At the moment (1.2.3-SNAPSHOT) BBB has been split in three subcomponents, so the idea of producing a "OneJAR" is already present in BBB - in addition to the capability of releasing a jar for each module, a configuration that could be used e.g. with OSGi, NetBeans Platform and in all cases when strictly replacing the original BeansBinding is not required.
Thoughts?
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)






Comments
Mark Thornton replied on Mon, 2009/04/27 - 3:01am
Surely not. I've never used jul like that. It is a little irritating packaging the arguments in an Object array, fortunately this is quite a cheap operation.
Valentin Buergel replied on Mon, 2009/04/27 - 3:13am
I used more or less the same libraries in the past (including SLF4J) before I switched to a customized logger with varargs as you did. Based on my experience I very much prefer solution 2). As the internal of the customized logger can be changed in the future, you will be able to connect the internals of that logger to a logging framework like SLF4J if this will be necessary.
Regards, Valle
Mladen Girazovski replied on Mon, 2009/04/27 - 3:50am
No offense intended, but i think that the whole "logging scene" is ridiculous.
After all, how many logging frameworks do we need?
How many times did you changethe logging implementation of an application without being forced by some bugs etc?
I have not come accross any reason not to use log4j, the oldest logging framework with the most features.But to each his own.
Fabrizio Giudici replied on Mon, 2009/04/27 - 4:16am
in response to:
Mark Thornton
Brant Boehmann replied on Mon, 2009/04/27 - 7:16am
Fabrizio Giudici replied on Mon, 2009/04/27 - 8:27am
in response to:
Brant Boehmann
John J. Franey replied on Mon, 2009/04/27 - 9:25am
I'm not sure if your primary issue is with the framework or the programming api.
If you are speaking about the api: slf4j is my choice. I find it to be suited for all log messages. There is no need for the log level test before calling the slf4j log method. In aspects important to me, slf4j api offers the same features as log4j's api or jul's api.
if you are speaking about the framewwork: slf4j is my choice, even though it is not a framework.
slf4j defers the decision of which framework to runtime. This is to the developer's benefit, not the gui user's. Your users of your gui won't care, so maybe in distribution, a small, lowcost logging framework is adequate. However, during development, more full featured framework would be prefered like the revered log4j or your fav jul. commons-logging api supports this, too, but commons-logging's dynamic discovery is not as solid as slf4j's static binding.
sfl4j api can be bound to a variety of frameworks: log4j, jul, logback, simplelog. Your runtime requirements is the primary factor in the decision, not the programming api.
slf4j also has a clean answer to the problem of third-party libraries using a framework specific api that is not the framework your application uses. For example, log4j api is used in the third-party library. What are your options there? 1) Choose the log4j framework for your own application. How tyrannic. 2) Write a log4j adapter that converts log4j requests to your framework's requests. 3) commons-logging, if it supports the framework you want. 4) implement the log4j api in terms of your preferred framework, lots of work (and this is what slf4j provides).
I am not sure whether I like logback or log4j better. But I don't think that responds to your question.
Regards,
John
Mike P(Okidoky) replied on Mon, 2009/04/27 - 11:38am
What I'm missing is log entries for anything that an application accidentally does outside of the AWT event thread. You're not allowed to interact with Swing outside the AWT thread, yet this is one of the most common cause of bugs and instabilities in the more complicated Swing applications.
Also, how about using the assert mechanism to let you bypass some of the log statements.
assert log("you did something you shouldn't");
log always return true. Only logged when running the JVM with the -ea option.
Witold Szczerba replied on Mon, 2009/04/27 - 4:03pm
I would suggest to use option #1. Simple solution, no external libraries required. This is not supposed to be rocket science, just simple logging to replace things like:
if(LOG) {
System.err.println(.....)
}
which one has to recompile in order to actually see the message. I am not sure if adding extra dependency for 3rd party libraries would be justifiable in this case. Keep it simple.
Regards,
Witold Szczerba
Jeanette Winzenburg replied on Tue, 2009/04/28 - 9:49am
Murmeltiertag :-)
In other words: we have had the exact same debate over at Swnglabs some years ago and the ,winner waaas ... stick with built-in logging, option #1, for the reasons outlined by Witold. Obviously, my preference as well.
Cheers
Jeanette
Mark Thornton replied on Tue, 2009/04/28 - 2:28pm
in response to:
Fabrizio Giudici
For both log and logp methods it comes down to a small amount of noise that would be unnecessary if varargs had been used: new Object[] {...}. About 15 characters and I could probably configure my IDE to generate it for me, but haven't been sufficiently irked to try that route.
Evan Summers replied on Wed, 2009/04/29 - 7:08am
Jean-Francois P... replied on Wed, 2009/04/29 - 9:27am
I think the first main decision (about BBB logging) to take would rather be:
"Should there be logging or not in a library that is implementing a JSR?"
I would probably say NO, because no JSR implementation should -to my viewpoint- impose any external dependency and it should not even impose jul (which is not external) because I don't think jul is logging library of choice of all Java developers.
Now if BBB is disconnected from JSR-295, then the choice is yours (ours?)!
My selection would probably go towards SLF4J which has a good API and can statically bind to any common logging library (log4j, jul...)
I would probably avoid commons-logging at all costs (even if classloader problems are less likely in GUIs than in JEE containers; but this shall change quickly with the rise of OSGi in GUI applications).
Just my 2 cents.
Tom Eugelink replied on Mon, 2009/05/04 - 2:35am
Martin Wildam replied on Mon, 2009/05/04 - 3:38am
I did not really try any of those - I only looked at documentation and code samples for some logging frameworks - and finally decided to make my own logging module as none of the existing fit my needs.
I found it strange: So many existing things and nothing is satisfying. - Strange, but applies for many other realms also for me...
Carla Brian replied on Sun, 2012/04/15 - 2:22am
Mateo Gomez replied on Thu, 2012/07/26 - 2:59am
these information are very useful and i have learned so much here
chicken burrito recipe
Matt Coleman replied on Fri, 2012/07/27 - 4:40am
logging facility swing is indeed a good thing to have
graphic design buffalo