java.util.logging shoddiness

I’ve recently had the (dis)pleasure of needing to convert a bunch of code that uses log4j to use JDK 1.4 logging. Why might one want to do this, you may well ask. Well, there are a couple of reasons (neither of which is THAT compelling, but hey, it’s an opensource project, so it’s all about defining ludicrous requirements and masturbating to bizarre code fetishes).

The first reason is that log4j weighs in at a whopping 350k. The code for this project (including the one other jar it requires) it 80k. So, one would (rightly) feel pretty stupid if one is lugging around a 350k jar just to log some stuff in 40k code.

The second reason is that one of the requirements for this project is a severe shortage of external dependencies; so log4j had to get the axe.

I hadn’t had much exposure to JDK 1.4 logging previously, beyond having to curse at people using jakarta-commons as a wrapper to it. The annoyance factor of java.util.logging is surprisingly high for a variety of reasons.

So, the first step was to write a custom formatter that produced vaguely sane output, while ensuring performance is slightly faster than Christopher Reeve in a 100m dash.

Consistently though, the rest of the API is likewise plagued with poor performance. Objects are created with gay abandon. Checks for log levels happen far too late. The only way to do it justice is to plug in your own implementation for handlers, loggers, formatters, and filters. Mind you, it’s pretty easy to beat log4j performance just by filling in a subset of those.

Then there’s the configuration nightmare. The option of either a class or a file path is not exactly the height of configurability. What’s so bad about url’s? Why not allow for properties files looked up in the classpath?

Surprisingly enough for Sun, the documentation is also not as clear as one would expect. I fumbled, I googled, I mostly flailed about helplessly trying to get anything chattier than INFO to show up (for some reason, just defining a global level didn’t work for me).

The level names also deserve a mention. Why on earth are there three different kinds of ‘fine’ness? The English language has an awful lot of words to describe this sort of thing. Surely to god it can’t be that hard to come up with something more helpful than FINE, FINER, and FINEST.

There’s also the pain of logging exceptions. There are no convenience methods to do this, you have to call the log method, and pass in a Level, message, and exception. A few more methods would have gone a long way in winning the love and adoration of the masses.

I’m usually quite a fan of Sun’s API (at least, ones that aren’t designed by open-to-public JSRs or apachepoo). While often performance isn’t particularly stellar, the API design is more often than not elegant and is exactly what 99% of developers need. One has to wonder what sort of accident or oversight led to the current state of java.util.logging.

13 Responses to “java.util.logging shoddiness”

  1. Clark Kent Says:

    “while ensuring performance is slightly faster than Christopher Reeve in a 100m dash.”

    Christ, Hani….I don’t know what’s sadder….the fact that you poke fun of invalids…or that I actually laughed at that line.

  2. Pawn Says:

    Hani, you may have hit the same wall I did using util.logging for the first time. The ConsoleHandler has it’s own log level setting.

  3. Bas Scheffers Says:

    Come on CK, these people fight to be treated equaly, but when you make fun of them, like you do with non-”physicaly challenged” people, you get comments like these.

    And don’t get me started on wheelchair ramps visualy mutulating otherwise perfectly photogenic entrances to monuments!

    Oh well, at least you admit to your hypocracy…

  4. Sam Says:

    In the future you might want to look at usng the commons-logging API from jakarta, as IIRC you can easily swap between using the JDK 1.4 logging or Log4j itself. And are you now enforcing that your application will only work with Java 1.4? If you didn’t have that restriction before you may of undone your work in removing the 300K odd of Log4J in an effort to reduce the applciation size – the Java 1.4 JRE is larger than 1.3, and more than 300K larger. Of course if you already had that dependancy, or you can be sure all your target audience already has the 1.4 JRE installed, then its a non issue I guess.
    As for limiting the number of dependencies on thrid party packages, can I ask what the rational behind that is? Hopefully not some management directive…

  5. SamIAm Says:

    Sam, you’re new to bileblog aren’t you. Go read some archives.

  6. Sam Newman Says:

    Not that new, brave anonymous poster. I am assuming from your economical reply that the answer to one of my questions has been answered elsewhere. Some people would of been more forthcoming with their rebuke – I can only assume that you had more important matters to attend to, and as a result you had time to reply to my post and yet not enough time to say anything useful.

  7. SamIaAM Says:

    True. Damn you’re witty. Clueless, but witty. Try again!

  8. Charles Miller Says:

    It’s “would have”, not “would of”. HTH, HAND.

  9. Kristopher Schmidt Says:

    For the visually impaired (e.g. bileindex too hard to read):
    http://www.jroller.com/page/fate/?anchor=the_evils_of_commons_logging

  10. Will Sargent Says:

    The writer of Log4J went through a bunch of this already: http://www.qos.ch/logging/thinkAgain.html

    Also see a comparison here: http://builder.com.com/5100-22-1046694.html

    Oh, and there USED to be a log4j-core.jar file which only had the absolutely necessary codebase. You could probably just take log4j, throw away most of the packages, and then check it into your source tree. Not that this is an ideal solution, but then it’s not an ideal world, is it…

  11. Will Sargent Says:

    Doh, that’s the “common logging sucks” URL. I meant this one:

    http://www.ingrid.org/jajakarta/log4j/jakarta-log4j-1.1.3/docs/critique.html

  12. Damien Says:

    There’s log4jME (Mini Edition, http://cvs.apache.org/viewcvs/jakarta-log4j/log4jMini/), which you have to compile.

  13. Lee Harvey Osmond Says:

    I’m late to this party.

    But it’s my considered opinion that java.util.logging is a pile of shit. My own beef with it is that log records with levels lower than Level.CONFIG never print.

    I’m not some clueless kiddie looking for help with my CS homework. I’m a developer with real work to do, and so far java.util.logging has wasted more of my time than did the issues I was investigating originally. I’m developing on MacOSX 10.3.9 / JDK 1.4.2, which means I even have a native application ‘JavaBrowser.app’ to hand, which when configured correctly allows one to search for classes/fields/methods/any by name, and to show API docs, and source where available and so on and so forth. [You wanna quicksort an array? There's no nice sorting API in java.util? OK, try sun.misc.Sort .]

    It appears I can’t get levels such as FINER to work because there’s a master logger with a default level of CONFIG. Do I have programmatic access to this logger, which appears to be a static field in the LogManager class, that I may alter its level at runtime? Oh. Can I get at via eg Logger.getLogger(String);? OK, suppose I copy the JRE master logging.properties file, edit the “.logger=CONFIG” setting and reconfigure at runtime from that? Even that didn’t work. I was amazed. What am I supposed to do, edit the JRE master logging.properties file on every box where I need to deploy, and screw up the logging environment for all other Java apps?

    My code even contains gems like:
    // if (true) throw new BogusException();
    from my experiments to prove that the the rest of my logging code, with Exceptions generally be being caught and logged at Level.WARN, work as advertised.

    This is *logging*, people. It really ought to be possible to read the package overview and a couple of the class API docs and then have it working satisfactorily in under an hour, rather than be still tinkering days later and mumbling “could have done better myself”.

Leave a Reply