I am a great fan of Java commons Logging
- It bonds to multiple back ends, Log4J and SmartFrog logging among them, SF Logging is unusual in that you can have per-instance loggers (with different outputs and levels), rather than just per-class logging.
- It's got a simple API and log levels.
- It doesn't require a configuration file, or tell you off if you lack one
- It falls back to console logging in the absence of a higher level back end
- It falls back to logging at info level, unless you say otherwise. That said, if you use log4J as the back end, well, the latest Log4J releases don't log unless you tell it to (annoying)
Where it is great is in libraries that you or other people write for embedding in other apps. By using commons-logging, you say "we don't dictate what your logging plans are".
That said, it's not been updated for a while, and a fair bit of code is starting to use SLF4J for logging. Which has some nice developer features. In particular the varargs style parameter parsing skips the checks and round tripping overhead of seeing if a log level is enabled before you concatenate a string together. But I find it more troublesome in production.
You can easily end up with code that uses SLF4J and Log4J. Jetty, for example, has its own log class, but the default back end? SLF4J. So you end up with an application using that, some other libraries using commons-logging, and log4j behind the scenes, and you end up having two separate ways to configure and route logging. Which is wrong.
embeddable libraries should not be dictating to the applications that use them how they log
I've ended up adding a direct Jetty-to-commons-logging bridge into the SmartFrog Jetty component so that we can go back to one logging system, but the problem runs deeper. I'll need to take that code and get it into Hadoop core, for example -unless I can get the Jetty team to put it into their codebase.
Now, I could give up, embrace SLF4J, and I'm sure my life will be better, but it's not what we use in SmartFrog, and there are so many existing things out there built against commons-logging.
What to do?
I'm feeling subversive today.
- The java.utils.logging API is dead, it never took off. It offered nothing above the existing logging tools except being really painful to configure. If this is the best the Java Community Program could offer, then I don't mourn its reduction from being a community to being more like the Congress of Soviets, where you were allowed to praise your glorious leaders, but not criticise them.
- Apache Commons Logging is open source, and that gives me the right to work on it, even if it hasn't been updated for a long time. If it needs updating, I am one of many who can do it.
- I am starting to wonder if it is time to release a commons-logging 2.0
What then, would a Commons-logging 2.0 library do?
- Retain 100% backwards compatibility at the API level with callers of the code
- Don't necessarily be compatible with any back ends.
- Offer the string construction methods to dynamically create messages if the target log-level is in use, skip the construction when not.
- Talk behind the scenes to Log4J and SmartFrog logs -doing string expansion
- Talk to SLF4J, delegating the string expansion to it (reduces round trip costs).
- Bind to whatever back end the JVM properties tell it to.
- Bind to Log4J and then SLF4J if found.
- Fall back to the console, logging at info and up.
- Have very minimal POM dependencies; no explicit dependencies on anything.
- Have a diagnostics option that prints to stderr what is going on with binding.
- Add a special jetty-bridge jar that bridged Jetty to this (yes! another layer of indirection! rejoice!)
It all sounds (fairly) straightforward. But I know seeing what logging code looks like, the troublespots are in binding and fallback, in diagnosis. Plus to test all this you need to actually grab the console and see what the log tools really printed, so you need your own console streams that print to the real console and to a buffer, so your tests can assert on the output.
Like I said, I'm thinking of this. Not yet coding it, but commons-logging is a wonderfully ubiquitous part of the Java infrastructure, and rather than just hoping it should go away, we should recognise its ubiquity and benefits, and improve it, rather than ignore it.