Документы JavaDocs дляjava.util.logging.Level
состояния:
Уровни в порядке убывания:
SEVERE
(максимальное значение)WARNING
INFO
CONFIG
FINE
FINER
FINEST
(наименьшее значение)
Источник
import java.util.logging.*;
class LoggingLevelsBlunder {
public static void main(String[] args) {
Logger logger = Logger.getAnonymousLogger();
logger.setLevel(Level.FINER);
System.out.println("Logging level is: " + logger.getLevel());
for (int ii=0; ii<3; ii++) {
logger.log(Level.FINE, ii + " " + (ii*ii));
logger.log(Level.INFO, ii + " " + (ii*ii));
}
}
}
Вывод
Logging level is: FINER
Jun 11, 2011 9:39:23 PM LoggingLevelsBlunder main
INFO: 0 0
Jun 11, 2011 9:39:24 PM LoggingLevelsBlunder main
INFO: 1 1
Jun 11, 2011 9:39:24 PM LoggingLevelsBlunder main
INFO: 2 4
Press any key to continue . . .
Постановка задачи
В моем примере устанавливается Level
значение FINER
, поэтому я ожидал увидеть по 2 сообщения для каждого цикла. Вместо этого я вижу одно сообщение для каждого цикла ( Level.FINE
сообщения отсутствуют).
Вопрос
Что нужно изменить, чтобы увидеть результат FINE
(, FINER
или FINEST
)?
Обновление (решение)
Благодаря ответу Винита Рейнольдса эта версия работает в соответствии с моими ожиданиями. Он отображает 3 INFO
сообщения и 3 FINE
сообщения.
import java.util.logging.*;
class LoggingLevelsBlunder {
public static void main(String[] args) {
Logger logger = Logger.getAnonymousLogger();
// LOG this level to the log
logger.setLevel(Level.FINER);
ConsoleHandler handler = new ConsoleHandler();
// PUBLISH this level
handler.setLevel(Level.FINER);
logger.addHandler(handler);
System.out.println("Logging level is: " + logger.getLevel());
for (int ii=0; ii<3; ii++) {
logger.log(Level.FINE, ii + " " + (ii*ii));
logger.log(Level.INFO, ii + " " + (ii*ii));
}
}
}
java
logging
java.util.logging
Эндрю Томпсон
источник
источник
Ответы:
Регистраторы только регистрируют сообщение, т. Е. Создают записи журнала (или запросы регистрации). Они не публикуют сообщения по назначению, о чем заботятся обработчики. Установка уровня регистратора приводит только к тому, что он создает записи журнала, соответствующие этому уровню или выше.
Возможно, вы используете
ConsoleHandler
(я не мог понять, где ваш вывод - System.err или файл, но я предполагаю, что это первый), который по умолчанию публикует записи журнала уровняLevel.INFO
. Вам нужно будет настроить этот обработчик, чтобы публиковать записи журнала уровняLevel.FINER
и выше для желаемого результата.Я бы рекомендовал прочитать руководство Java Logging Overview , чтобы понять базовый дизайн. В руководстве описывается разница между концепцией Logger и Handler.
Редактирование уровня обработчика
1. Использование файла конфигурации
Файл свойств java.util.logging (по умолчанию это
logging.properties
файл вJRE_HOME/lib
) можно изменить, чтобы изменить уровень ConsoleHandler по умолчанию:2. Создание обработчиков во время выполнения
Это не рекомендуется, так как это приведет к отмене глобальной конфигурации. Использование этого во всей базе кода приведет к, возможно, неуправляемой конфигурации регистратора.
источник
Handler
.Logger.getGlobal().getParent().getHandlers()[0].setLevel(Level.FINER);
Почему
В java.util.logging есть корневой регистратор, который по умолчанию используется
Level.INFO
, и прикрепленный к нему ConsoleHandler, который также по умолчаниюLevel.INFO
.FINE
меньше чемINFO
, поэтому мелкие сообщения по умолчанию не отображаются.Решение 1
Создайте регистратор для всего приложения, например, из имени вашего пакета или использования
Logger.getGlobal()
, и подключите к нему свой собственный ConsoleLogger. Затем либо попросите корневого регистратора отключиться (чтобы избежать дублирования вывода сообщений более высокого уровня), либо попросите регистратор не пересылать журналы корневому каталогу.Решение 2
В качестве альтернативы вы можете уменьшить полосу корневого регистратора.
Вы можете установить их по коду:
Или с файлом конфигурации журналирования, если вы его используете :
Понизив глобальный уровень, вы можете начать видеть сообщения из основных библиотек, например, из некоторых компонентов Swing или JavaFX. В этом случае вы можете установить фильтр в корневом регистраторе, чтобы отфильтровать сообщения не из вашей программы.
источник
почему мой журнал java не работает
предоставляет файл jar, который поможет вам понять, почему ваш вход в систему не работает должным образом. Это дает вам полный дамп того, какие регистраторы и обработчики были установлены, какие уровни установлены и на каком уровне в иерархии регистрации.
источник
ЗАЧЕМ
Как упоминалось @Sheepy, причина, по которой это не работает, заключается в том, что
java.util.logging.Logger
у корневого регистратора, который по умолчанию используетсяLevel.INFO
, иConsoleHandler
прикрепленного к этому корневому регистратору также по умолчаниюLevel.INFO
. Поэтому для того, чтобы увидетьFINE
(,FINER
илиFINEST
выход), вам необходимо установить значение по умолчанию для корневого регистратора и егоConsoleHandler
кLevel.FINE
следующим образом :Проблема вашего обновления (решение)
Как упомянуто @mins, у вас будут сообщения, напечатанные дважды на консоли для
INFO
и выше: сначала анонимным регистратором, затем его родителем, корневым регистратором, который также имеетConsoleHandler
значениеINFO
по умолчанию. Чтобы отключить корневой регистратор, вам нужно добавить эту строку кода:logger.setUseParentHandlers(false);
Существуют и другие способы предотвратить обработку журналов обработчиком консоли по умолчанию корневого регистратора, упомянутого @Sheepy, например:
Но
Logger.getLogger("").setLevel( Level.OFF );
не будет работать, потому что он блокирует только сообщение, переданное непосредственно корневому регистратору, а не сообщение, поступающее от дочернего регистратора. Чтобы проиллюстрировать, как этоLogger Hierarchy
работает, я нарисовал следующую диаграмму:public void setLevel(Level newLevel)
установить уровень журнала, определяющий, какие уровни сообщений будут регистрироваться этим регистратором. Уровни сообщений ниже этого значения будут отброшены. Значение уровня Level.OFF можно использовать для отключения регистрации. Если новый уровень равен нулю, это означает, что этот узел должен унаследовать свой уровень от своего ближайшего предка с определенным (ненулевым) значением уровня.источник
Я обнаружил свою настоящую проблему, и она не была упомянута ни в одном ответе: некоторые из моих модульных тестов вызывали многократное выполнение кода инициализации журнала в одном и том же наборе тестов, что приводило к нарушению ведения журнала в более поздних тестах.
источник
Пробовал другие варианты, это может быть правильно
источник
Это решение кажется мне лучше с точки зрения ремонтопригодности и дизайна для изменений:
Создайте файл свойств ведения журнала, встраивая его в папку проекта ресурсов, чтобы включить его в файл jar:
Загрузите файл свойств из кода:
источник