Ryan has posted 17 posts at DZone. You can read more from them at their website. View Full User Profile

What is Wrong with JDK Logger?

10.29.2008
| 20773 views |
  • submit to reddit

I used to use log4j because it was most popular, but recently decided to try JDK logger in my current project. I like that it is built into the JDK so there are no .jar dependencies, version conflicts, etc. All I need it to do is write to a disk file using a format String I specify, rotate logs after x KB, and to keep only y archived files. I'm just as satisfied with it as I was with log4j.

A while ago I did some reading about the history of logging frameworks to try and understand the hostility many developers still have towards JDK logger. From what I can tell log4j was the first widely popular logging framework in Java. Later, its ideas and general API design were standardized in JDK 1.4. The names of some things were changed, but the concepts are the same. There were many developers who did not want to require "the new" Java 1.4 so they continued with log4j. Later the commons-logging wrapper was created to provide libraries and applications the ability to use either log4j or JDK logger depending on what is present in the environment. Even today with the pending release of Java 1.7 many developers use log4j or commons-logging instead of the built in JDK logger.

My question to you is what is wrong with the JDK logger? Why do some people say it was disaster? Why don't you use it? I am not trying to start a flamewar, I am genuinely interested. Is it because log4j comes with many more built-in appenders such as NTEventLogAppender, JMSAppender, and SMTPAppender? I figure the JDK logger has only basic core handlers/appenders for the same reason JSF comes only with basic HTML UI components.

From http://www.ryandelaplante.com

 

Published at DZone with permission of its author, Ryan Developer.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Arek Stryjski replied on Wed, 2008/10/29 - 6:05am

I think the most honest answer will be: I don't remember any more :)

I was trying to switch from log4j to JDK logger years ago. There was definitely some functionality which I was missing, but now I cannot remember what it was...

On other hand why not use log4j? You need it anyway in your classpath because so many other library's use it and it is much more familiar after so many years.
I also never had any of your problems:
- ".jar dependencies" - well one more if you have 30-40 jars is not making big difference;
- "version conflicts" - never happened to me with log4j 

I believe there is nothing wrong with JDK logger but there is also nothing wrong with log4j. I made a decision years ago and I still trust myself. If you say there is so many things which are missed in log4j I will revisit it.
There is so many new things to learn what learning somthing which does not give any new functionality is waste of time.

 

Lee Francis Wil... replied on Wed, 2008/10/29 - 6:07am

I remember being annoyed at SUN when they decided to introduce their own logging framework instead of using the established Apache/Jakarta variant. I think I recall that the argument against using log4j was regarding lack of performance?

I think it's fair to say that the SUN of 2000/2001 was a lot less open source friendly than today and were reluctant to let others onboard. I doubt the SUN of 2008 would make the same mistake, but who knows? SUN have been known to make some pretty strange business decisions in the past.

I have myself tried to use the java.util.logging framework for many of the same reasons you mention, but I kind of got annoyed with the whole FINE, FINER, FINEST mess for debug messages. Why introduce a new framework for logging if the old one is working fine? I much rather prefer to work with log4j and it seems a lot of the industry agree, since log4j is more or less present everywhere where the JDK is. The best thing would be for SUN to adopt log4j, but I doubt it is a priority and the two seem to live happily side by side... and have been for some years now.

Radek Jun replied on Wed, 2008/10/29 - 6:11am

It's realy interesting question. I also use log4j instead of JDK logger and I'm not sure why. May be I'm only used to use log4j. Has JDK logger any outstanding features, which log4j doesn't have?

Lukas Zapletal replied on Wed, 2008/10/29 - 6:15am

JUL does not include lots of features from LOG4J and this is the problem. People that needs to rotate logs have to implement their own handlers. Thats the reason why people still prefer LOG4J.

JUL is much like a framework than a full-blown implementation.

ps - I prefer SLF4J :-)

ssaddasasd sasdasd replied on Wed, 2008/10/29 - 7:20am

I feel the worst thing is the configuration file located in JAVA_HOME/lib (workaround:http://edocs.bea.com/kodo/docs303/ref_guide_logging_jdk14.html ).

regards

Guillaume Jeudy replied on Wed, 2008/10/29 - 8:04am

I agree with Lee Francis, using FINE FINER FINEST logging levels appears just wrong, why not have a plain DEBUG level like log4j? I tried adopting JDK logging and dropped it when I saw how wrong were the logging levels.

 For my part I prefer to use commons logging with log4j underneath so I still have the freedom to switch to another logging framework implementation should I need to.

Frode Stokke replied on Wed, 2008/10/29 - 8:07am

I had to choose between JUL and LOG4J for a new project a few years ago. LOG4J provided everything I needed right out-of-the box. It was possible to extend JUL with custom classes to get the same functionality, but why bother when it was already there in LOG4J? I use SLF4J on top of LOG4J, so switching from LOG4J to something else is just a matter of swapping a couple of jars and the config files, no changes to the code.

Victor Tatai replied on Wed, 2008/10/29 - 8:13am

Two words: MDC / NDC :)

ssaddasasd sasdasd replied on Wed, 2008/10/29 - 8:16am in response to: Guillaume Jeudy

Commons logging play fine in contextes where there's just one classloader (http://www.qos.ch/logging/classloader.jsp). When I have to use commons logging in a multi classloader context I have to use slf4j over commons logging.

I think commons logging is absolutely the worst logging choice.

 regards

G.

Henk De Boer replied on Wed, 2008/10/29 - 8:24am

The JDK logger itself works really fine, except for one MAJOR FLAW. In a web environment (at least in Tomcat), the root logger is shared between web applications. Meaning, that if you install a filter on it in one web applications, other web applications are bothered by this. Worse yet, a lot of ClassCircularityExceptions may pop up because of this. 

It's a rather nasty thing... 

Nishant Kumar replied on Wed, 2008/10/29 - 8:42am

when you bundle a webapp as a war, you can bundle the default log4j.properties file along with it. You cannot do the same for jdk logger as the jdk logger conf is stored externally and is common for all the webapps.

if you have multiple webapps deployed in tomcat, you can configure in log4j so that logs from different webapps go to different log file. One cannot do the same in jdk logger out of the box.

log messages from same class files from different webapp will go in the same log file in case of jdk logger. this is true even when the class is stored in separate jars within the webapp lib folder.

I hope I remember correct :)

Guillaume Jeudy replied on Wed, 2008/10/29 - 8:50am in response to: ssaddasasd sasdasd

h3,

 Nice article link, I didnt know commons logging suffered from classloading bugs in a multi classloader context. I've seen other projects use SLF4J but I guess the problem I have is with all the dependencies on open source libraries that themselves depend on commons logging. How do you make that out?

Another thing I don't quite understand from your linked article, what is static linking, does it mean SLF4J uses compile time checking to determine which logging framework to use? I fail to see how this can be done.

 From my point of view I like to have a clean library stack so if most of my libraries use a certain logging framework I would use that same framework in my app code to reduce the number of jars I have to import. I don't know how a mix of SLF4J and commons-logging in the same classloader would play out...

Joe Farmer replied on Wed, 2008/10/29 - 11:42am

First thing that is wrong with JDK logger is that it is not an interface. SUN's logger came to the game too late to be the only one used. By creating Logger interface they would have reduced dependencies on non-java logging since most components could accept logger as a parameter. And it would have created an option to smothly transition to the java logging were desired.

ssaddasasd sasdasd replied on Wed, 2008/10/29 - 11:54am in response to: Guillaume Jeudy

(pasting from http://www.slf4j.org/manual.html#gradual)

"""

The implementation of JCL over SLF4J, i.e jcl-over-slf4j.jar, will allow your project to migrate to SLF4J piecemeal, without breaking compatibility with existing software using JCL. Similarly, log4j-over-slf4j.jar and jul-to-slf4j modules will allow you to redirect log4j and respectively java.util.logging calls to SLF4J. 

"""

 In pratice slf4j (jcl-over-slf4j.jar) implements  all the public api exposed by commons-logging, redirecting the log on log4j for instance. 

 Here (http://www.slf4j.org/legacy.html#jcl-over-slf4j) there's a good explanation.

best regards

G.

 

 

 

Ryan Developer replied on Wed, 2008/10/29 - 12:10pm

Thanks everyone for the responses. My original thinking was that if JDK logger has everything I need for the project, and libraries I'm using don't use logging (or commons-logging), then there is no reason to use something else. It would be like replacing the Collections framework just because another one is more popular. Regarding log rotation, it does have built in support for this when the file reaches a certain size. However, it does not have calendar based log rotation to support concepts such as a daily log. I like my .war files to be usable in any environment without having to change config files inside of it, so I keep log file configuration with the rest of my application configuration externally. And good point about root logger being shared between web apps. I haven't encountered this problem yet, but there is only one app in GlassFish V2 right now.

Osvaldo Doederlein replied on Wed, 2008/10/29 - 12:40pm

Years ago when JDk1.4 went FCS, I was all "it's from JCP so it's better" and I migrated a good number of my company's projects from Log4J to java.util.logging.

It was a mistake. Years later, annoyed by JUL's limitations, I migrated everything back to Log4J and never looked back.

(And no, I would never use the festering pile of crap that is Jakarta Comons Logging - for my opinion on that library, just check Hani's bileous opinion. That decision could be different, for reusable component projects, if SLF4J was available years ago; but it wasn't. And for actual applications, it makes no sense at all to use ANY logging wrapper.)

Mark Thornton replied on Wed, 2008/10/29 - 3:00pm

One difference of approach between the two is that log4j does localisation (if at all) at the time of the logging call, whereas in JUL localisation is delayed until the log record is 'rendered'. The rendering of the log record might take place on a different machine with a different locale. Also different users might each view the same log record in their own language.

 I have used FINE/FINER/FINEST but you don't have to use all three. Just pick FINE if you want a simple equivalent to DEBUG. For really fine tracing during debugging I use another mechanism altogether, but have ensured that any logging output is also present in the 'trace' output.

Robin Bygrave replied on Wed, 2008/10/29 - 3:34pm in response to: Osvaldo Doederlein

@Osvaldo in regards the "... annoyed by JUL's limitations"

Can you mention specific features/issues that made you migrate from JUL back to Log4J ?

John O'Hanley replied on Wed, 2008/10/29 - 3:39pm

I have always used JDK logging. Nothing wrong with it for me. Works fine.

 In servlet environments, the Handlers need to be configured in code, upon startup. This will avoid problems with the logging.properties file handlers, which are attached to the JRE, and not to the web app.

Each web app has a distinct classloader. When you config handlers in code, they aren't shared with other web apps. So each app can log to its own file.

Haidong Pan replied on Thu, 2008/10/30 - 9:36am

thank you johanley,  It's very helpful to me.

Osvaldo Doederlein replied on Thu, 2008/10/30 - 2:33pm in response to: Robin Bygrave

[quote=rbygrave]

@Osvaldo in regards the "... annoyed by JUL's limitations"

Can you mention specific features/issues that made you migrate from JUL back to Log4J ?

[/quote]

For an extensive coverage, see JSR47 vs log4j. I know, that's written by log4j's author, but it reflects many of my own findings:

- Lacking an abstract layer. Yes, log4j is not any better, but JSR47 is the standard so it should be much better here - it could have avoided the need of Commons Logging or SLF4J.

- The huge functionality delta. This could be much less important if extension libs were available for JSR47, perhaps in a javax.util.logging that was included in J2EE and optional for J2SE... but they aren't available at all (at least not in major, well maintained projects). And while I won't mind writing my own extensions once in a while (I wrote a couple custom appenders and renderers for both APIs), I do mind a lot to write basic stuff like a syslog appender. Or a standard formatter that doesn't suck - JSR47's SimpleFormatter is a disaster, because (1) it writes two text lines per log, and (2) it pays a huge cost to log caller class/method.

- "Moreover, the language of JSR47 configuration files is very weak. In particular, you can only configure one instance of a given handler class. This means that you can log to just one file at a time." This issue was another deal-breaker for me. I have large apps with a very complex logging structure - lots of loggers hierarchically arranged; lots of different appenders and formatters; most loggers writing to multiple appenders (with different level and formatting in each), etc. And I'll have this kind of configuration in hardwired Java code only over my dead, cold body.

There are probably other issues that I don't remember, it's been a few years that I don't touch java.util.logging.

Mark Thornton replied on Thu, 2008/10/30 - 3:29pm in response to: Osvaldo Doederlein

[quote=opinali]

- The huge functionality delta.  ... quote]

It wouldn't be hard to address these and other issues, but I can't see anyone doing so. The fallout seems to have poisoned the area, so that anyone working on it keeps a low profile.

John O'Hanley replied on Sat, 2008/11/01 - 5:59pm

@panhaidong - you are welcome.

There seems to be a lot of misunderstanding about how to configure JDK logging in a servlet  environment, as shown in previous comments. 

The logging.properties file is not meant for use by servlets. But that doesn't mean you can't use JDK logging. It just means that you need to config it using other means (the logging API.) This is unfortunate, but not a big deal - at least for me. 

ssaddasasd sasdasd replied on Mon, 2008/11/03 - 11:07am in response to: John O'Hanley

>> It just means that you need to config it using other means (the logging API.) This is unfortunate, but not a big deal - at least for me.

 it means you have to re-deploy you app just to change the logging level. For me it's inaceptable.

 regards

 G

 

Ryan Developer replied on Mon, 2008/11/03 - 11:48am in response to: ssaddasasd sasdasd

[quote=h3] it means you have to re-deploy you app just to change the logging level. For me it's inaceptable[/quote]

 No that is not true. You can change log level from API.  We configure the logger and change log level at runtime using APIs.  

ssaddasasd sasdasd replied on Mon, 2008/11/03 - 12:26pm in response to:

Maybe I'm missing the point, but if you change the log level from API (I'm not sure what you're meaning ...), I suppose you re modifying a .java  file. Then you have to redeploy your app to make the modification effective.  Am I missing something?

Ryan Developer replied on Mon, 2008/11/03 - 12:40pm in response to: ssaddasasd sasdasd

[quote=h3]

Maybe I'm missing the point, but if you change the log level from API (I'm not sure what you're meaning ...), I suppose you re modifying a .java  file. Then you have to redeploy your app to make the modification effective.  Am I missing something?

[/quote]

My app has a management web service.  The web service includes get/set log level.  The management application can call into the web service and tell it to change the log level, and it takes effect immediately.  No recompiling, no redeploying. 

As for log file configuration such as path, filename, log count, max size before rotation, etc. this data lives with the rest of my application's configuration data.  When the application starts it configures the logger using API and the data.  If I wanted to be able to change this type of logger configuration at runtime I could add more methods to my managmement web service. 

In my application I have not found any limitations in JDK Logger.  I don't mind the log level names, I like configuring the logger using API instead of disk files, and I have full control over its runtime behavior.  

Osvaldo Doederlein replied on Mon, 2008/11/03 - 1:48pm in response to:

[quote=rdelaplante]

You can change log level from API.  We configure the logger and change log level at runtime using APIs.  

[/quote]

Yeah, so you end up writing a whole lot of extra code to enable API-driven reconfiguration: you either write your own, more powerful config file support; or support JMX; or have logging options in the app's admin GUI. With Log4J I don't need anything like that, I just update the config file and Log4J reloads it (presuming configureAndWatch()). It's a big difference of productivity(*), and it's also a standard configuration mechanism that works identically for every Log4J app (can't say the same of roll-your-own management facilities).

(*) You could argue that this is mostly valid for simpler apps, because for large, complex apps, that extra code for logging configuration would be a "drop in the ocean". But in my experience, the logging structure is often as complex as the application... I have some large apps that need log4j.properties files that are several pages long. Now if I'd map that entire tree of log4j configs to, say, some standard JMX console, it would be really ugly and slow to configure, compared to the simplicity of editing log4j.properties files - or just replacing those files by pre-defined alternates, say for testing, troubleshooting and production. There's also the convenience of keeping config files in version control.

Ryan Developer replied on Mon, 2008/11/03 - 2:14pm

Osvaldo, good points.  I was trying to explain that JDK Logger does let you update it at runtime without redeploying the .war because some commenters thought that is what you have to do.  It seems to me the main points against using JDK logger are:

- issues related to .properties configuration vs API configuration

- some people don't like the names of log levels fine/finer/finest

- some people don't like using log(Level level, String message, Throwable exception) to get it to log an exception

- The built in log rotation doesn't support rotation based on calendar (such as every day at midnight)

I can see the first point being the most important one.  The rest isn't an issue for me at all.

Robin Bygrave replied on Mon, 2008/11/03 - 6:21pm in response to:

Not forgetting NDC / MDC ("Nested Diagonostic Context" / "Mapped Diagnostic Context" ) ... which some may find hard to live without and perhaps tip people towards Log4J.

Has anyone got something similar to NDC / MDC working with JDK Logger? Anyone know of any plans to add these to JDK Logger API?... probably a silly question :)

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.