I’m writing a standalone command line utility, designed to be used by people are neither Java experts nor developers. I want my code to only have a dependency on slf4j, the API that sits on top of logback (or many other logging frameworks), courtesy of a set of adapters.
When the program is working “as designed” there’s no need for logging. After all, what would a “regular” user want with a log file? And this is the problem.
So, my choices are:
- Deliver a
logback.xmlfile to sit inside the jar file.
- Deliver a
logback.xmlfile to sit outside the jar file.
- Programmatically configure logback.
All of these solutions have serious drawbacks:
Provide a configuration file inside the jar file
Providing a configuration file in this way means that there’s only one configuration available. Also, it will likely frustrate advanced users who want to control logging or replace the logging framework.
Provide a configuration file outside of the jar file
This is a bad experience for the user because, instead of one file, they now have two files to worry about. Also, the name of this file has no relation to xml2csv, so when copying the executable around they’ve got to remember to take this one, or suffer literally thousands of lines of nonsensical logging messages flying up the screen in front of them.
Programatically configure logback
This involves tightly coupling my code to logback, unless I use reflection to dynamically configure it, which isn’t a good thing. If, at a later date, I want to replace logback with something else, I’d have to change the code. There’s also a difficult question of knowing when to configure the logging. More advanced users might set up their own logging configuration and I don’t want to overwrite what they want the program to do!
So, what would be best?
If logback output nothing when unconfigured, then normal usage wouldn’t require any kind of configuration. Curious users, or users having problems who needed to switch logging on, could add a
logback.xml to enable it. For this reason, I think that this is the best behaviour for all logging frameworks.
One caveat of this is that I remember struggling greatly trying to understand why my log4j configurations years ago were failing because it was never obvious how to enable debugging messages of the logging framework. Therefore, I’d recommend putting this in big, bold, bright letters in your documentation. Something as simple as an environment variable would be ideal for my usage.
Of course, the primary reason why logback is making lots of noise is because it’s there. There’s a strong argument to be made to omit logback entirely from the main build. This would have the following advantages:
- It would fix the problem for the default use-case, where logging is not required.
- Advanced users could slot in their own logging framework without having to deal with the annoyance of logback being embedded in the jar file.
- Smaller distribution (by some 700k).
If logging was required by a user then they would have to drop a logging implementation and configuration file. For advanced, technical-savvy users this is reasonably simple. But for users who just want to use xml2csv and who are having problems, then this could be an annoyance; certainly compared to specifying a single
-logging parameter to the utility and generating a log file to send back to me.
This is the approach I’m going take with xml2csv, at least for the time being. Combined with some very explicit instructions on how to download the artifacts required to enable logging.