Почему в логгере slf4j нет метода, который принимает и varargs для сообщения, и исключение? - PullRequest
0 голосов
/ 25 апреля 2018

Регистратор SLF4J имеет методы ведения журнала, которые принимают либо исключение, либо varargs , но не оба.

Есть идеи почему?

Проблема с отсутствующей подписью состоит в том, что иногда я хотел бы одновременно регистрировать исключение и предоставлять параметры сообщения, но у меня нет подписи метода для выполнения обоих действий.

Ответы [ 2 ]

0 голосов
/ 25 апреля 2018

Возможная причина в том, что varargs должен быть последним аргументом в сигнатуре, и было сложно добавить параметр Object (который предназначен для исключения), за которым следует параметр Object ....Согласно ответу @Berger кажется, что это было решено в версии SLF4J 1.6.0.Тем не менее, я решил ту же проблему по-разному.Я написал библиотеку с открытым исходным кодом MgntUtils (доступна из репозитория Maven Central и github).Одна из утилит там извлекает трассировку стека из Throwable как String.Также, опционально, эта утилита может отфильтровывать некоторые не относящиеся к делу части трассировки стека и делать ее очень сжатой и легко читаемой.Таким образом, в этом случае вы можете передать извлеченную трассировку стека вашему логгеру как часть varargs.Я нашел это очень удобным, особенно с отфильтрованной трассировкой стека.Это будет выглядеть так:

LOGGER.error("My message {} {}", MyStringParam, TextUtils.getStacktrace(e));

Вот ссылка на статью, в которой объясняется, где взять библиотеку и как ее использовать: MgntUtils Библиотека с открытым исходным кодом Библиотека поставляется с исходным кодоми Javadoc

0 голосов
/ 25 апреля 2018

Ссылаясь на При наличии исключительной ситуации / метки можно ли параметризовать оператор ведения журнала? , вы можете сделать это начиная с SLF4J 1.6.0, если исключение является последним аргументом:

Да, начиная с SLF4J 1.6.0 , но не в предыдущих версиях.API SLF4J поддерживает параметризацию при наличии исключения, а , если исключение является последним параметром .Таким образом,

String s = "Hello world";

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

напечатает NumberFormatException со своей трассировкой стека, как и ожидалось.Компилятор Java вызовет метод error, который принимает аргументы String и два Object.SLF4J, в соответствии с наиболее вероятным намерением программиста, будет интерпретировать экземпляр NumberFormatException как бросаемый вместо неиспользуемого параметра Object.В версиях SLF4J до 1.6.0 экземпляр NumberFormatException просто игнорировался.

Если исключение не является последним аргументом, оно будет обрабатываться как простой объект, и его трассировка стека НЕ ​​будет напечатана.Однако такие ситуации не должны возникать на практике.

В качестве примера реализации этот метод вызывается Logback (этот метод находится в классе ch.qos.logback.classic.spi.EventArgUtil ивызывается ch.qos.logback.classic.spi.LoggingEvent):

public static final Throwable extractThrowable(Object[] argArray) {
    if (argArray == null || argArray.length == 0) {
        return null;
    }

    final Object lastEntry = argArray[argArray.length - 1];
    if (lastEntry instanceof Throwable) {
        return (Throwable) lastEntry;
    }
    return null;
}
...