У меня есть некоторый код Java, который я хотел бы оснастить с сообщениями журнала для отладки целей. Финал (скомпилировал) производственный код, однако, не должен содержать вход, поскольку он замедлил бы время выполнения. Есть ли какой-либо путь в Java для отключения регистратора во время компиляции?
Я не боюсь места, которое проверка в методе журнала времени выполнения позволила/отключила регистратору, добавит.
if (logging==enabled) {// do logging}
Но я хотел бы избежать конструкции параметра как следующее в моем производственном коде:
Logger.log("undefined state" + state + " @ " + new Date());
Я использую Компилятор Java Sun.
Я не знаю ни о каких функциях компилятора по этому поводу, но вы также можете сделать создать сборочный скрипт. Этот сценарий копирует исходные (отладочные) исходные файлы Java, копирует их во временное место, удаляет из них операторы регистрации и затем компилирует новые исходные файлы, которые в этом случае не содержат отладочного кода.
Уродливая уловка, которая может сработать, - это скрыть реализацию библиотеки Logger с пустой реализацией. Оптимизатор встроит их, и удаление мертвого кода должно удалить конструкцию параметра. Это не сработает, если конструкция параметра содержит побочные эффекты.
Это теория, я не проверял это на практике. Хотя мне это любопытно. Может быть, это требует отдельного вопроса?
Я понимаю, что компилятор Java может удалять блоки кода, которые защищены выражением константы времени компиляции. Так что теоретически вы можете сделать это примерно так:
public class Logging {
public static final boolean ENABLED = true; // change to false
}
public class Something
....
if (Logging.ENABLED) {
logger.debug("hello mum");
}
}
К сожалению, вам нужно перекомпилировать каждый класс, который зависит от флага Logging.ENABLED, всякий раз, когда вы меняете его значение. Поэтому я предпочитаю следующее:
public class Something
....
if (logger.isDebugEnabled()) {
logger.debug("hello mum");
}
}
, преимущество которого состоит в том, что вы можете выполнять тонкую настройку уровней ведения журнала во время конфигурации или даже во время выполнения; например с использованием отладчика, JMX и т. д. Кроме того, накладные расходы на вызов logger.isDebugEnabled ()
в log4j достаточно низки, поэтому они вряд ли будут заметны, если у вас не будет безумного количества журналов в вашей кодовой базе.
Рассматривали ли вы подход slf4j с {}-местодержателями. Это позволяет отложить построение toString(), что означает, что log.debug(...) будет дешевым, если отладочная регистрация отключена.
log.debug("in loop() - a={}, b={}", a, b);
if(logger.isDebugEnabled()) {
logger.debug(expression);
}
Каждая структура ведения журнала, которую я использовал, требует, чтобы вы использовали вышеуказанный шаблон, чтобы избежать ненужной оценки выражения журнала.
Похоже, это именно то, что вы ищете:
что на самом деле делает log4j, когда мы включаем или выключаем некоторые места в журнале?
Нет встроенного способа, который делает это возможным. Вы можете использовать Препроцессор Java .
Вам действительно следует использовать индикатор уровня для сообщений журнала, Level.SEVERE -> Level.FINEST.
Для этого в логгере есть предопределенные методы, например:
Logger.info(msg);
Logger.finest(msg); // debug/trace message.
Logger.log(Level.CONFIG, "config message");
это позволит вам настроить минимальный уровень логирования на уровне приложения и включать/выключать сообщения ниже настроенного уровня, используя командную строку, файлы конфигурации или вручную с помощью LogManager
Один из способов - выполнить проверку вне метода журнала. Практически такая же проверка, как вы упомянули, но вы делаете ее сами:
if (LOGGER.isLoggable(Level.DEBUG)) {
LOGGER.log("undefined state" + state + " @ " + new Date());
}
Этот метод можно использовать с любым уровнем ведения журнала. см. Logger # isLoggable (Level) для получения дополнительной информации. Обратите внимание, что это рекомендуемый способ избежать построения параметров метода журнала.