Мы знаем, что можем сконфигурировать log4j для выключения входа в систему определенные места (класс или пакет в Java) через его свойства/конфигурационный файл. Мои вопросы сопровождаются:
спасибо,
Да, операторы журнала по-прежнему будут выполняться. Вот почему рекомендуется сначала проверить уровень журнала: что-то вроде
if (log.isInfoEnabled()) {
log.info("My big long info string: " + someMessage);
}
Это необходимо для предотвращения перераспределения пространства для информации String
, когда уровень журнала не поддерживает INFO
заявления.
Это не что-то вроде #ifdef
- #ifdef
- это директива компилятора, тогда как конфигурации Log4J обрабатываются во время выполнения.
Редактировать : Я ненавижу, когда меня начинают понижать из-за незнания, поэтому вот одна статья, подтверждающая мой ответ.
Из http://surguy.net/articles/removing-log-messages.xml :
В Log4J, если вы регистрируете сообщение на уровне DEBUG, и текущий Appender настроен на регистрацию только сообщений уровня INFO и выше, тогда сообщение не будет отображаться. Потеря производительности при вызове самого метода журнала минимальна - несколько наносекунд. Однако может потребоваться больше времени, чтобы оценить аргументы журнала { {1}} метод. Например:
logger.debug ("Большой объект " + largeObject.toString ());
Оценка largeObject.toString () может быть медленной, и это оценивается перед вызовом регистратора, поэтому регистратор не может предотвратить его оценку, даже если он не будет использоваться.
Редактировать 2 : из самого руководства log4j ( http://logging.apache.org/log4j/1.2/manual.html ):
Пользователь должен знать о следующие проблемы с производительностью.
Производительность ведения журнала при отключении ведения журнала. Когда ведение журнала отключено полностью или только для набора уровней, стоимость запроса журнала состоит из вызова метода и целочисленного сравнения. На машине Pentium II с тактовой частотой 233 МГц эта стоимость обычно находится в диапазоне от 5 до 50 наносекунд.
Однако вызов метода включает в себя «скрытые» затраты на создание параметра.
Например, для некоторого регистратора cat, запись
logger.debug ("Номер записи:" + i + "равно" + String.valueOf (entry [i]));
требует затрат на создание параметра сообщения, то есть на преобразование целого числа i и entry [i] в строку и объединение промежуточных строк, независимо от того, будет ли сообщение регистрироваться или нет. Стоимость построения параметров может быть довольно высокой и зависит от размера задействованных параметров.
Чтобы избежать затрат на создание параметра, напишите:
if (logger.isDebugEnabled () {
logger.debug ("Номер записи:" + i + "is" + String.valueOf (entry [i ]));
}
Это не повлечет за собой затрат на создание параметров, если отладка отключена. С другой стороны, если для регистратора включена отладка, это потребует вдвое больше Стоимость оценки того, включен ли регистратор: один раз в debugEnabled и один раз при отладке. Это незначительные накладные расходы, поскольку оценка регистратора занимает около 1% времени, необходимого для фактического ведения журнала.
Я запустил простой бенчмарк для проверки.
for (int j = 0; j < 5; j++) {
long t1 = System.nanoTime() / 1000000;
int iterations = 1000000;
for (int i = 0; i < iterations; i++) {
int test = i % 10;
log.debug("Test " + i + " has value " + test);
}
long t2 = System.nanoTime() / 1000000;
log.info("elapsed time: " + (t2 - t1));
long t3 = System.nanoTime() / 1000000;
for (int i = 0; i < iterations; i++) {
int test = i % 10;
if (log.isDebugEnabled()) {
log.debug("Test " + i + " has value " + test);
}
}
long t4 = System.nanoTime() / 1000000;
log.info("elapsed time 2: " + (t4 - t3));
}
elapsed time: 539
elapsed time 2: 17
elapsed time: 450
elapsed time 2: 18
elapsed time: 454
elapsed time 2: 19
elapsed time: 454
elapsed time 2: 17
elapsed time: 450
elapsed time 2: 19
С 1.6.0_18, что удивило меня, так как я думал, что инлайнинг предотвратит это. Возможно, Java 7 с анализом escape предотвратит это.
Однако я бы все равно не стал оборачивать отладочные утверждения в предложение if, если только улучшение времени порядка половины микросекунды не станет важным!
log4j обработает оператор журнала и проверит, включен ли конкретный регистратор на определенном уровне ведения журнала. Если это не так, то выписка не будет регистрироваться.
Эти проверки значительно дешевле, чем фактическая запись на диск (или консоль), но они все же оказывают влияние.
нет, в java нет такой концепции, как #ifdef (в любом случае есть предварительные компиляторы java)