Даже с slf4j, вы должны охранять свою регистрацию? - PullRequest
30 голосов
/ 09 декабря 2011

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

Сайт 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);

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

Ответы [ 5 ]

45 голосов
/ 18 октября 2012

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

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

Вы просто откладываете 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() дважды, когда эта конкретная операция регистрации включена.

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

18 голосов
/ 09 декабря 2011

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

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

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

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

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

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

8 голосов
/ 09 декабря 2011

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

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

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

4 голосов
/ 09 декабря 2011

Проблема с оператором записи в журнал выглядит так:

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

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

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

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

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

3 голосов
/ 09 декабря 2011

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

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

Я плачу.

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

...