109

What's the correct approach to log both an error message and an exception using SLF4J?

I've tried doing this but the exception stack trace is never printed:

logger.error("Unable to parse data {}", inputMessage, e);

In this case I want to populate {} with the inputMessage as well as logging out the exception stacktrace.

The only way I can see to do this would be to do this:

logger.error("Unable to parse data " + inputMessage, e);

which is not pretty.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
pjp
  • 17,039
  • 6
  • 33
  • 58

2 Answers2

150

As of SLF4J version 1.6, SLF4J will interpret the last parameter as you intended, i.e. as an exception. You must be using an older version of SLF4J API.

This feature is documented in a faq entry which is also referenced in the javadocs for Logger.

Ceki
  • 26,753
  • 7
  • 62
  • 71
  • 8
    Is this described in the Javadoc? I was expecting to find similar information here: http://www.slf4j.org/apidocs/org/slf4j/Logger.html – Scot Oct 09 '14 at 19:23
  • 2
    I believe you, but like @Scot, I was hoping this behavior would be documented. – Stephan Aug 19 '15 at 20:51
  • 4
    Scot, @Stephan - the aformentioned behaviour seems to be documented in their FAQ [here](http://www.slf4j.org/faq.html#paramException). – Priidu Neemre Sep 01 '15 at 08:22
  • 9
    This is like a best kept secret. Thanks for pointing it out. My follow-up question is why would they hide the fact that this is possible in a var-arg? Why can't they create a new overloaded method that takes the `Throwable` and then has a var-arg after that? Is there erasure problems? Is this a standard in other libraries to have the exception passed in as the last argument? – gaoagong Jul 08 '16 at 17:19
  • 9
    This has (since?) been documented in the FAQ: https://www.slf4j.org/faq.html#paramException . I agree that this feature should be documented more clearly. – Stephan202 May 07 '17 at 18:00
  • Is there a way to override this behavior as desired? I want to sometimes not log the exception stacktrace, but by configuration, not by changing the call to the logger. – Johny Nov 10 '21 at 12:04
3

from http://www.slf4j.org/faq.html#paramException:

Yes, as of SLF4J 1.6.0, but not in previous versions. The SLF4J API supports parametrization in the presence of an exception, assuming the exception is the last parameter. Thus,

String s = "Hello world";
try {
  Integer i = Integer.valueOf(s);
} catch (NumberFormatException e) {
  logger.error("Failed to format {}", s, e);
}

will print the NumberFormatException with its stack trace as expected. The java compiler will invoke the error method taking a String and two Object arguments. SLF4J, in accordance with the programmer's most probable intention, will interpret NumberFormatException instance as a throwable instead of an unused Object parameter. In SLF4J versions prior to 1.6.0, the NumberFormatException instance was simply ignored.

If the exception is not the last argument, it will be treated as a plain object and its stack trace will NOT be printed. However, such situations should not occur in practice.

LIU YUE
  • 1,593
  • 11
  • 19