Was looking at Simple Logging Facade for Java (SLF4J), a Java logging library. One nice feature is that one can use message formats that don’t get evaluated until the log statement is executed, which in turn depends on the log level.
It seems, maybe I missed it, that using this feature disallows you from logging exceptions. For example, you can log a complicated string and the exception like so:
logger.error("Oh no, thing '"+ thing + "' took down the system!", ex);
Alternatively, you can use SLF4J’s message formatting to avoid the costly String manipulations, and just pass in the ‘thing’ object and anything else needed in the message as varargs:
logger.error("Oh no, thing '{}' took down the system!", thing);
But, where to you chain in the exception that caused this?
Solution?
Add to the API:
void error(String format, Throwable t, Object... arguments) Log an exception and message at the ERROR level according to the specified format and arguments. This form avoids superfluous string concatenation when the logger is disabled for the ERROR level. However, this variant incurs the hidden (and relatively small) cost of creating an Object[] before invoking the method, even if this logger is disabled for ERROR. The variants taking one and two arguments exist solely in order to avoid this hidden cost. Parameters: format - the message accompanying the exception t - the exception (throwable) to log arguments - a list of 3 or more arguments
Then the log could have been done as:
logger.error("Oh no, thing '{}' took down the system!", ex, thing);
But…
Of course, I’m sure the developers of SLF4j, and other libraries that change their API to take advantage of varargs, have very good reasons for the resulting changes and “limitations”.
One advice given in Java docs is:
“… you should not overload a varargs method, or it will be difficult for programmers to figure out which overloading gets called”.
Resources
