Затмение - сонар S2629 возможен ложный положительный с новой строкой - PullRequest
0 голосов
/ 28 октября 2018

Я использую последний плагин Eclipse и Sonar

В answer для регистрации есть следующая строка:

log.debug("Request body: {}", new String(body, "UTF-8"));

, которая должна создавать String, только если в DEBUGуровень:

/**
 * Log a message at the DEBUG level according to the specified format
 * and argument.
 * <p/>
 * <p>This form avoids superfluous object creation when the logger
 * is disabled for the DEBUG level. </p>
 *
 * @param format the format string
 * @param arg    the argument
 */
public void debug(String format, Object arg);

Но Sonar помечает его как squid:S2629:

«Предварительные условия» и аргументы регистрации не должны требовать оценки (squid: S2629)

И привести примеры с конкатенацией

logger.log (Level.DEBUG, "Что-то пошло не так:" + сообщение);// Несоответствующий;Конкатенация строк выполняется, даже если уровень журнала слишком высок для отображения сообщений DEBUG

Это ложное срабатывание предупреждения гидролокатора или я что-то упустил?

Это не дубликат этот вопрос , который, как правило, задает концепцию правила, то есть объединение, но не форматирование с созданием объекта, как new String

Также ссылка ответа говорит о создании new Date() не создает проблему со встроенным форматом:

public static void main(String[] args) {
    LOGGER.info("The program started at {}", new Date());
}

}

Ведение журнала таким образом позволяет избежать снижения производительности при конкатенации строк, когда на самом деле ничего не нужно регистрировать.

Ответы [ 2 ]

0 голосов
/ 28 октября 2018

Хотя использование лямбды или ленивой лямбды в порядке, все еще есть старый добрый способ isDebugEnabled:

if (log.isDebugEnabled()) {
  log.debug("Request body: {}", new String(body, StandardCharsets.UTF_8));
}

Это не исправит создаваемый String (потому что вы хотитев конце концов, отображать его), но это не израсходует память при отключенном режиме отладки.

0 голосов
/ 28 октября 2018

В режиме без отладки строка

log.debug("Request body: {}", new String(body, "UTF-8"));

вместо

log.debug(MessageFormatter.format("Request body: {}", new String(body, "UTF-8")));

избегает создания строки, которая создается с помощью MessageFormatter.format(String messagePattern, Object arg),но не создание другой строки, созданной с помощью new String(body, "UTF-8").

Это означает, что не является ложным положительным значением , поскольку аргументы вычисляются в первую очередь раньшеметод ведения журнала вызывается.

Пока SLF4J не поддерживает лямбда-выражения для ленивых вычислений аргументов (см. комментарий ЖекаКозлов ),В качестве обходного пути можно использовать следующий служебный метод:

private static Object lazyToString(final Supplier<String> stringSupplier) {
    return new Object() {
        @Override
        public String toString() {
            return stringSupplier.get();
        }
    };
}

Это можно использовать для ограничения преобразования байтового массива в строку только в режиме отладки:

log.debug("Request body: {}", lazyToString(() -> new String(body, StandardCharsets.UTF_8)));
...