Log4j протоколирование дважды
Я использую log4j для регистрации ошибки и другой системной информации. но из информации, зарегистрированной дважды на уровне INFO.
public static void main(final String... args) throws Exception {
LOGGER.info("program started");
try {
// try body codes
} catch (Exception ex) {
LOGGER.info("program start-up failed.",ex);
}
}
однако, когда программа запускается или сбой дважды регистрируется, любой может помочь мне найти причину этого.
Ответы
Ответ 1
Похоже, что ваши сообщения регистрируются один раз корневым регистратором и снова конкретным регистратором, так как у вас могут быть настроены оба приложения (может быть в разных местах - в файле свойств, а затем в коде).
Это можно решить, установив аддитивность на false в вашем журнале. Log4j manual упоминает аддитивность в разделе "Агенты и макеты". Проверьте, что
Ответ 2
Согласитесь с atlantis.
log4j.rootCategory=INFO, console
log4j.logger.org.hibernate=INFO
Вышеуказанные настройки свойств вызовут двойной журнал.
Однако добавление
log4j.additivity.org.hibernate=false
исправлена проблема.
Посмотрите страницу 62 этой книги. http://books.google.com/books?id=hZBimlxiyAcC&printsec=frontcover#v=onepage&q&f=false
Ответ 3
Для этого используется формат XML:
<logger name="package.class" additivity="false">
<level value="info" />
<appender-ref ref="file" />
<appender-ref ref="console" />
</logger>
Примечание. По умолчанию у регистраторов флаг флагов установлен равным true.
Ответ 4
Просто добавьте
logger.setadditivity(false);
к вашему коду (Ссылка).
У нас есть двойные результаты в консоли, потому что appenders не являются одиночными, они аддитивны. Значение, категория наследует все приложения от своих предков (по умолчанию). Если мы добавим appender в категорию и записываем в тот же базовый поток (консоль, тот же файл и т.д.) В качестве другого приложения, одно и то же сообщение журнала будет появляться дважды (или больше) в журнале. Кроме того, если две категории в иерархии настроены на использование одного и того же имени приложения, Log4j будет писать дважды для этого приложения. Конфигурировано для этой категории
Ответ 5
Если вы можете запустить программу с помощью отладчика Java, поместите контрольную точку в программу, где происходит один из этих двойных вызовов регистрации.
Изучите объект регистратора в отладчике. Если это org.apache.log4j.Logger(v 1.2.x), то он может иметь AppenderAttachableImpl. Вы можете запросить AppenderAttachableImpl для списка приложений.
Если вы найдете более одного приложения, это может быть проблемой - и ключ к его исправлению.
Ответ 6
Потенциальной альтернативой настройке свойства additivity
является проверка ваших регистраторов от наиболее специфических до наиболее общих. В следующем примере мы ожидаем увидеть двойную регистрацию в Консоли для любых событий журнала, происходящих в foo.bar.LoggingExampleClass. Было бы безопасно удалить дополнительный консольный appender из foo.bar.LoggingExampleClass Logger, поскольку он уже покрыт корневым регистратором.
<Logger name="foo.bar.LoggingExampleClass" level="DEBUG">
<AppenderRef ref="Console" /> <!-- THIS APPENDER COULD BE REMOVED -->
<AppenderRef ref="FooBarPackageLogging" />
</Logger>
<Root level="WARN">
<AppenderRef ref="Console" />
<AppenderRef ref="MainLogFile" />
</Root>
Существуют компромиссы как с подходом корректировки аддитивности, так и с подходом к корректировке приложения. Отключение аддитивности может непреднамеренно остановить использование желаемого добавленного регистратора уровня. В приведенном выше примере установка свойства additivity="false"
в файле foo.bar.LoggingExampleClass Logger означает, что событие регистрации не будет добавлено к MainLogFile, указанному в корневом журнале.
С другой стороны, полагаться на родительские приложения может быть проблематично, если родительские приставки изменены без изучения эффектов для более гранулированных регистраторов. Например, предположим, что существует требование, чтобы события foo.bar.LoggingExampleClass записывались в Консоль. В настоящее время они находятся в приведенной выше конфигурации конфигурации из-за аддитивности, даже если удаляется приложение foo.bar.LoggingExampleClass Logger Console. Однако, если приложение консоли также было удалено из корневого регистратора без каких-либо дополнительных настроек, это требование больше не будет выполнено.
Ответ 7
У меня была такая же проблема, и я исправил ее, удалив все приложения из корневого регистратора. Я не знаю почему, но решаю мою проблему, и я делюсь:
// Root
rootLogger = Logger.getRootLogger();
rootLogger.removeAllAppenders(); // Solve my problem
// CSV
csvLogger = rootLogger.getLogger("csvLogger");
// Txt
txtLogger = rootLogger.getLogger("txtLogger");
Без этой дополнительной строки, даже при установке аддитивности в false, всякий раз, когда я регистрируюсь с помощью моего csvLogger или txtLogger, он регистрируется дважды.