# Second Logging System
I've often thought [SLF4J](http://www.slf4j.org) is a clear-cut case of [second-system effect](http://c2.com/cgi/wiki?SecondSystemEffect). It features strict separation of interface and implementation, complete with at least five different backends and a really elegant trick for determining which is actually in use of runtime... for logging. Something that's built into the JVM (though few seem to actually use java.util.logging these days, probably for good reason), or at least had a fully functional monolithic implementation in [log4j](http://logging.apache.org/log4j/1.2/); I suspect a large proportion of slf4j users are simply using the slf4j-log4j backend (my previous employer mandated the use of Logback for a while, but given that none of us knew how to configure it and its supposed advantages never materialized, eventually sense was seen), meaning all it gives us is an extra layer of indirection. How much worse, then, is it when a project feels the need to provide its own internal logging API, abstracting away the dependency from the rest of their code and ensuring that it would be trivial to swap out log4j and replace it with slf4j using log4j as a backend. Occasionally we even see both internal "backends" maintained, and this swap really is possible - but as with most cases of premature genericization, usually the layering is an illusion and there's only ever one implementation of the logging interface.
And yet... there's something seductive about it. I recently started working on a new project that had some logging wrapper utility classes and... I could see the problems they were trying to solve. It took a conscious efort of will to keep from immediately expanding them, adding my own elegant layers to hide away the two or three problems that I already know exist in log4j, structuring the packages to lead users to program in my style. The fact I was pair-programming helped rein me in, and I merely added the minimum needed to support my structured logging use cases - though I suspect by my pair's standards I already went too far.
There is, I think, something about logging that appeals to a certain frame of mind. It's large enough to be interesting, and give opportunities for elegance, but small enough that one person can attempt it on their own, as a small part of a big project, even if they'd shy away from implementing their own ORM framework or DI container or web application framework. It's a truly cross-cutting concern - something that almost every part of a program wants to *do* but not *care about* - and it is (or seems) substantially the same for almost every program out there. The fact that there are still new logging frameworks being written and published in Java, a language that's getting on for 20 years old, speaks to the insanity of our industry - but it's a very human insanity, and one that I understand a lot better now than before this particular experience.
What's the solution? Maybe we should abandon the idea of a "perfect" framework, use whichever has the most momentum, and put up with the inelegancies - certainly the most successful product I've worked on was a reasonably plain spring/hibernate webapp, where used log4j for its logging, including some quite complicated filters, and got on with things. On the other hand, that same logic might lead to not using [Wicket](http://wicket.apache.org/), which is the biggest mistake you can make in programming. Using a more elegant framework - as long as this is an engineering-driven decision, taken with features in mind - is certainly something I can get behind. The case for writing one's own framework is harder; the idea that thousands of applications are papering over the same cracks in major frameworks is horrifying, but the idea of each having its own custom framework is even worse. There's certainly value in separating out a framework layer even if it's only used internally, but I think again the key is to be feature-driven; only extend or replace a framework if it's the best way to accomplish a direct product goal. I've seen every stage of the transition from workarounds in a few classes to a utility package, then a distinct module, and finally a project suitable for release as a standalone framework; it really is possible to write a framework in a series of 2-week iterations, and the results are generally far better than when one sets out to write a framework (something I've also done).
For now, I'm busy writing a replacement for the django template system. Even *I* think I'm crazy, but the siren song of greater elegance is impossible to resist.
comments powered by Disqus