Подтвердить что ты не робот

Даже с slf4j, если вы охраняете регистрацию?

Помогите мне в обсуждении здесь..:)

Сайт slf4j здесь http://www.slf4j.org/faq.html#logging_performance указывает, что из-за параметризованного ведения журнала не требуются защитные ограждения. То есть вместо написания:

if(logger.isDebugEnabled()) {
  logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
}

Вы можете уйти с:

Object entry = new SomeObject();
logger.debug("The entry is {}.", entry);

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

4b9b3361

Ответ 1

Я постараюсь поставить свои два цента с другой точки зрения

В чем именно выгода параметризованной регистрации?

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

Делает ли параметризованное ведение журнала защиту бесполезной во всех случаях?

Нет.

В каких случаях будут полезны охранники?

Когда есть другие потенциально дорогие операции.

Например (в случае, если эта конкретная операция регистрации отключена), если у нас нет защиты журнала

logger.debug("User name: {}", getUserService().getCurrentUser());
  1. Мы заплатили бы стоимость от obj = getUserService().getCurrentUser()
  2. Мы бы сохранили стоимость из "User name: " + obj.toString()

Если мы используем защиту журнала:

if (logger.isDebugEnabled()) {
    logger.debug("User: {}", getUserService().getCurrentUser());
}
  1. Мы бы оплатили стоимость logger.isDebugEnabled()
  2. Мы бы сэкономили стоимость от obj = getUserService().getCurrentUser()
  3. Мы бы сохранили стоимость из "User name: " + obj.toString()

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

ПРИМЕЧАНИЕ: это всего лишь пример, не пытающийся обсуждать хорошие/плохие методы здесь.

Ответ 2

Запись и чтение всех этих if(logger.isDebugEnabled()) {}, вероятно, будет стоить столько же времени, сколько они вас сохранят.

Конечно, вызов метода журнала не является бесплатным, но то же самое верно для вызова isDebugEnabled(). Таким образом, вы платите больше за каждый оператор журнала, который является активным, если вы используете этот шаблон (поскольку среда ведения журнала проверит уровень дважды).

Он также загромождает код.

На практике я не нашел, чтобы штраф за производительность был достаточно большим, чтобы беспокоиться.

Если запись слишком медленная для вас, напишите неблокирующий appender, который выталкивает события журнала в очередь без нескольких проверок и использует фоновый поток для их обработки.

Фон: стандартные приписки синхронизированы, поэтому регистрация в многопоточном приложении может вызвать множество небольших пауз, где все потоки ожидают, что сообщение журнала будет записано в файл.

Ответ 3

Защитник не используется из-за создания строки.

Вместо этого он обычно используется, чтобы избежать потенциально дорогого выражения аргументов, например entry[i].retrieveExtendedDebugInformation().formatNicely(). Для этого logback гарантирует, что аргумент оценивается только тогда, когда сообщение журнала действительно напечатано, а log4j всегда оценивает аргумент перед вызовом debug().

Здесь единственный кандидат String.valueOf(entry[i]), что тоже не очень дорого, поэтому вы можете сделать аргумент, что этот защитник вообще не нужен.

Ответ 4

Проблема с выражением о регистрации как это:

logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));

заключается в том, что он будет выполнять большую работу по объединению значений в String, который тогда никогда не будет использоваться, если отладка журнала отключена. Поэтому в этом случае полезно проверить, включено ли ведение журнала отладки перед выполнением этой строки. Когда вы просто передаете параметры:

logger.debug("The entry is {}.", entry);

тогда нет необходимости строить String, который никогда не используется, и проверка не требуется; просто передача аргументов в метод не имеет очень больших накладных расходов.

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

Ответ 5

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

if (logger.isDebug()) {
   logger.debug("Of course it debug {}", sadFace);
}

Я плачу.

Я надеюсь, что стоимость создания статической строки настолько мала, чтобы быть незначительной для 99% пользователей.