2010-06-22 3 views
5

У меня есть код Java, который я хотел бы использовать с сообщениями журнала для целей отладки. Однако окончательный (скомпилированный) производственный код не должен содержать записи, поскольку это замедляет время выполнения. Есть ли способ в Java отключить регистратор во время компиляции?Отключить ведение журнала в Java во время компиляции

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

if (logging==enabled) {// do logging} 

Но я хотел бы избежать строительства параметр как следующий в моем рабочем коде:

Logger.log("undefined state" + state + " @ " + new Date()); 

Я использую Sun, Java Compiler.

ответ

0

Я не знаю каких-либо функций компилятора об этом, но то, что вы также могли бы сделать, это создать скрипт сборки. Этот скрипт скопировал исходные (отладочные) исходные файлы Java, скопировал их во временное место, удалил бы из них записи ведения журнала и затем скомпилировал новые исходные файлы, которые затем не будут отлаживать код.

1

Существует нет встроенного способа, который делает это возможным. Вы можете использовать Java Preprocessor.

+0

Я так и думал, когда я был ... – Max

2
if(logger.isDebugEnabled()) { 
    logger.debug(expression); 
} 

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

+2

прибегая к помощи Исследовать {} -placeholders в SLF4J. –

+0

@ Thorbjørn Ravn Andersen - аккуратный - это явно лучше для многих случаев использования. _Индикация об экземпляре массива объектов, возможность ненужного автобокса и т. Д., Но многое из этого должно быть JIT-компилировано во время выполнения в любом случае. API-интерфейс slf4j не исключает необходимости использования булевых охранников, если это необходимо. – McDowell

+0

Это вопрос вкуса. Для меня {} -значение приводит к меньшему количеству кода (нет, если) и меньше беспорядка (без конкатенации строк). –

1

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

if (LOGGER.isLoggable(Level.DEBUG)) { 
    LOGGER.log("undefined state" + state + " @ " + new Date()); 
} 

Этот метод может быть использован с любым уровнем протоколирования. см. Logger#isLoggable(Level) для получения дополнительной информации. Обратите внимание, что это рекомендуемый способ избежать построения параметра метода журнала.

+0

Ты избил меня на этом! – Riduidel

+0

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

+0

, тогда параметры предварительно обрабатывают источник или используют такие вещи, как AOP, чтобы добавить журнал, когда вам нужно. – unbeli

0

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

Теперь это теория, я не проверял это на практике. Мне это любопытно. Может быть, это требует отдельного вопроса?

+0

Я не был уверен, будет ли компилятор «умным», чтобы это сделать. Я могу попробовать ... – Max

+0

Компилятор, похоже, не оптимизирует код. Время выполнения вызова пустого метода при передаче статической строки по сравнению с конкатенацией отличается на порядки (по крайней мере, при отсутствии специальных параметров компилятора). – Max

+0

В любом случае я бы не стал полагаться на него. Я установил мою среду IDE для расширения «logd» до if (log.isDebugEnabled()) {log.debug («yadayada»);} и т. Д. –

0

Вы действительно должны использовать индикатор уровня для сообщений журнала, Level.SEVERE -> Level.FINEST.

Есть предопределенные методы в Logger для этого, а именно:

Logger.info(msg); 
Logger.finest(msg); // debug/trace message. 

Logger.log(Level.CONFIG, "config message"); 

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

+0

Конечно, но если вы хотите передать строку, которая построена (см. Мой пример), конструкция будет вызываться до проверки уровня журнала. – Max

+0

Вы можете написать собственную реализацию вставки параметров, используя varargs, для использования с протоколированием, который проверяет текущий нужный желаемый уровень. Также проверьте log4j или slf4j –

5

Вы рассмотрели подход slf4j с {} -полностями. Это позволяет отложить построение toString(), что означает, что log.debug (...) является дешевым, если журнал отладки отключен.

log.debug("in loop() - a={}, b={}", a, b); 
+0

Да, я рассмотрел этот подход передачи всех параметров и конструирования их после проверки, но я все еще надеялся получить положительный ответ на обработку этого на уровне компиляции. Это мой предпочтительный способ на данный момент. – Max

+1

Затем рассмотрим инструкцию assert, которая позволяет полностью отключить части кода. К сожалению, slf4j API возвращает void, поэтому их нельзя использовать с этим - вам придется катить свою собственную оболочку. –

0

Я понимаю, что компилятор 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 достаточно низки, что вряд ли будет заметным, если у вас нет безумной суммы регистрации в вашей кодовой базе.

2

Можно постовать файлы классов java с помощью Proguard и использовать опцию для удаления вызовов регистрации. Это делается чаще всего для Android с помощью:

-assumenosideeffects class android.util.Log { 
    public static *** d(...); 
    public static *** v(...); 
} 

удалить все вызовы Log.d(TAG, "message") и т.д ...

+0

Добро пожаловать в SO.Your прошу стиль хорош, используя код в вашем вопросе, это хорошая прецессия – khan

Смежные вопросы