Изменить глобальные настройки для экземпляров Logger - PullRequest
39 голосов
/ 10 июня 2011

Я использую java.util.logging.Logger в качестве механизма ведения журнала для моего приложения.Каждый класс использует свой собственный регистратор, т. Е. Каждый класс имеет:

private final Logger logger = Logger.getLogger(this.getClass().getName());

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

Ответы [ 4 ]

64 голосов
/ 10 июня 2011

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

-Djava.util.logging.config.file="logging.properties" 

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

В этом файле добавьте следующую строку:

.level= INFO

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

 com.xyz.foo.level = SEVERE

Вы можете получить шаблон для файла свойств ведения журнала из jre6 \ lib \ logging.properties .

33 голосов
/ 10 июня 2011

Как ответил Энди , в большинстве случаев вам следует использовать файл свойств и аргумент виртуальной машины, поэтому он не зависит от вашего кода.

Но если по какой-то причине вы хотите работать программно (у меня в одном случае была веская причина), вы также можете получить доступ к обработчикам:

Logger rootLogger = LogManager.getLogManager().getLogger("");
rootLogger.setLevel(Level.INFO);
for (Handler h : rootLogger.getHandlers()) {
    h.setLevel(Level.INFO);
}

РЕДАКТИРОВАТЬ Я добавил setLevel к корневому логгеру, как указано в Searchengine27 в его ответе .

Обработчики - это файловые или консольные обработчики, которые вы настраиваете через свойства или программно.

Или измените фильтры следующим образом:

Logger rootLogger = LogManager.getLogManager().getLogger("");
rootLogger.setFilter(new Filter() {
    @Override
    public boolean isLoggable(LogRecord record) {
            return "something".equals(record.getLoggerName());
    }
});
22 голосов
/ 05 сентября 2014

Так что мне не совсем нравятся все ответы здесь, поэтому я собираюсь войти.

Использование файла конфигурации

Вы видите много ответов здесьговорю вам использовать файл конфигурации, потому что это лучшая практика.Я хочу лучше объяснить, как это сделать программно, но прежде чем я это сделаю, я хочу сказать, что я могу видеть, откуда они берутся, и в настроении быть объективным, я вас немного просветлю (особенно потому, что никто не говорит почему это плохая практика).Я на самом деле хочу поделиться тем, что кто-то сказал в отдельном ответе StackOverflow, касающемся программной настройки уровня регистратора ( Почему сообщения журнала Level.FINE не отображаются? ):

Это не рекомендуется, так как это приведет к переопределению глобальной конфигурации.Использование этого во всей вашей кодовой базе приведет к возможной неконтролируемой конфигурации регистратора.

В этой заметке, я думаю, у Энди Томаса есть хороший ответ, связанный с тем, что он не делает это непрограммически.

Программная установка уровня

При этом я хочу более подробно рассказать о том, как делать это программно, потому что я думаю, что он имеет свои применения.

Представьте себе сценарий, в котором вы пишетечто-то с интерфейсом командной строки, и у вас есть возможность указать подробность вашего выполнения или даже куда он идет (как в файлах динамического журнала).Я могу ошибаться, но вы, вероятно, не захотите делать это статически в файле .conf.Особенно, если вы не хотите, чтобы ваша пользовательская база отвечала за установку этих параметров (по любой произвольной причине) в файле конфигурации.Однако это происходит за счет приведенной выше цитаты.Вот пример того, как вы можете сделать это программно, сохраняя все существующие обработчики на том уровне, на котором они уже находятся, и только FileHandler принимает новый уровень:

public static void setDebugLevel(Level newLvl) {
    Logger rootLogger = LogManager.getLogManager().getLogger("");
    Handler[] handlers = rootLogger.getHandlers();
    rootLogger.setLevel(newLvl);
    for (Handler h : handlers) {
        if(h instanceof FileHandler)
            h.setLevel(newLvl);
    }
}

Я хотелподробнее об этом, за принятый ответ по одной причине, в частности.Делая это программно, вы просто хотите убедиться, что вы установили уровень для логгера и обработчика (ей).Как это работает, он проверит, не слишком ли низкий запрос для регистратора, и если это так, он отменит его.Затем обработчики проходят одинаковую проверку, поэтому вы должны убедиться, что регистраторы и обработчики установлены на желаемый уровень.

3 голосов
/ 17 марта 2017

Однострочный подход Java 8 к ответу Моря :

Arrays.stream(LogManager.getLogManager().getLogger("").getHandlers()).forEach(h -> h.setLevel(Level.INFO));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...