Slf4j: как записать отформатированное сообщение, массив объектов, исключение

Каков правильный подход для регистрации как заполненного сообщения, так и трассировки стека исключения?

logger.error(
    "\ncontext info one two three: {} {} {}\n",
    new Object[] {"1", "2", "3"},
    new Exception("something went wrong"));

Я хотел бы сделать вывод, похожий на этот:

context info one two three: 1 2 3
java.lang.Exception: something went wrong
stacktrace 0
stacktrace 1
stacktrace ...

slf4j версия 1.6.1

Ответ 1

Как и в случае с SLF4J 1.6.0, при наличии нескольких параметров, и если последний аргумент в инструкции журнала является исключением, то SLF4J предположит, что пользователь хочет, чтобы последний аргумент рассматривался как исключение, а не просто параметр. См. Также соответствующую запись в FAQ.

Итак, запись (в версии SLF4J версии 1.7.x и более поздней)

 logger.error("one two three: {} {} {}", "a", "b", 
              "c", new Exception("something went wrong"));

или запись (в версии SLF4J версии 1.6.x)

 logger.error("one two three: {} {} {}", new Object[] {"a", "b", 
              "c", new Exception("something went wrong")});

даст

one two three: a b c
java.lang.Exception: something went wrong
    at Example.main(Example.java:13)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at ...

Точный вывод будет зависеть от базовой структуры (например, logback, log4j и т.д.), а также от того, как настраивается базовая инфраструктура. Однако, если последний параметр является исключением, он будет интерпретироваться как таковой, независимо от базовой структуры.

Ответ 2

В дополнение к ответу @Ceki. Если вы используете logback и настраиваете файл конфигурации в своем проекте (обычно logback.xml), вы можете определить журнал для построения трассировки стека, используя

<encoder>
    <pattern>%date |%-5level| [%thread] [%file:%line] - %msg%n%ex{full}</pattern> 
</encoder>

% ex в шаблоне - вот что делает разницу