Жалоба Sonarlint в методе записи журнала - PullRequest
3 голосов
/ 11 февраля 2020
log.info(String.format("Execution of method %s finished in %d ms", pointcut.getSignature().getName(), ms))

Sonarlint показывает следующую ошибку:

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

Соответствующее решение:

logger.log ( Level.SEVERE, «Что-то пошло не так: {0}», сообщение);

Попробуем:

log.info("Execution of method {0} finished in {1} ms", pointcut.getSignature().getName(), ms);

Должны использоваться строки формата Printf-style правильно

Совместимое решение:

String.format («Сначала% s, а затем% s», «foo», «bar»);

Я чувствую как сонарлинт просто издевается надо мной.

Это мое суждение, но я не совсем понимаю, что происходит или почему он жалуется в первую очередь:

String logMessage = String.format("Execution of method %s finished in %d ms", pointcut.getSignature().getName(), ms);
log.info(logMessage);

Есть идеи?

Ответы [ 2 ]

4 голосов
/ 11 февраля 2020

Я не очень понимаю, что происходит или почему он жалуется в первую очередь:

Причина жалобы в первом примере заключается в том, что вы безусловно проделал большую работу по созданию сообщения журнала. Работа будет потрачена впустую, если уровень журнала выше, чем INFO.


Второй пример лучше первого, поскольку строка сообщения журнала создается из шаблона только в том случае, если уровень журнала равен INFO или ниже. Выражение pointcut.getSignature().getName() по-прежнему оценивается безоговорочно, но это может быть неизбежно в зависимости от используемого вами API ведения журнала c.

(Если вы оцениваете это дорого, у вас все еще есть проблема с производительностью. Вы можете посмотреть на использование if (log.isInfoLevel()) { ... } guard или чего-то такого, что сделает вычисление выражения ленивым; например, Supplier<String>. Но лучшее решение может быть, чтобы избежать записи этого дорогого выражения.)


Жалоба сонара во втором примере, похоже, касается конкретного синтаксиса, который вы использовали в строке сообщения / формата. @ C. Ответ Лечнера объясняет это так:

  • В первой версии с {} тип {} оценивается во время выполнения.
  • Во второй с % s,% d вы определяете тип во время компиляции.

Если возможно, вы должны использовать тип, чтобы избежать неправильного использования переменных-заполнителей и позволить компилятору java выполнить некоторые дополнительные проверки.

Я не совсем уверен, что компилятор Java сделает проверку. (Это, конечно, не требуется для JLS.) Но вполне вероятно, что компилятор или (умный) анализатор кода stati c может проверить.

В любом случае строка формата будет проверена (снова ) во время выполнения.


Наконец, эта версия:

String logMessage = String.format("Execution of method %s finished in %d ms",
                                  pointcut.getSignature().getName(), ms);
log.info(logMessage);

имеет ту же проблему с производительностью, что и первая версия, но я подозреваю, что Sonar не достаточно умен, чтобы понять это .

0 голосов
/ 11 февраля 2020
  • В первой версии с {} тип из {} оценивается как время выполнения .
  • Во второй с% s,% d Вы определяете тип в время компиляции .

Если возможно, вы должны использовать тип, чтобы избежать неправильного использования переменных-заполнителей и позволить компилятору java выполнить некоторые дополнительные проверки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...