log4j дважды - PullRequest
       23

log4j дважды

64 голосов
/ 18 апреля 2011

Я использую 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);
    }
}

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

Ответы [ 8 ]

92 голосов
/ 18 апреля 2011

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

Эту проблему можно решить, установив аддитивность в false на вашем логгере. Log4j manual упоминает аддитивность в разделе Appenders and Layout. Проверьте это

34 голосов
/ 08 июня 2011

Согласен с Атлантидой.

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

30 голосов
/ 12 декабря 2011

Для тех, кто использует формат XML:

<logger name="package.class" additivity="false">
    <level value="info" />
    <appender-ref ref="file" />
    <appender-ref ref="console" />
</logger>

Примечание. По умолчанию для регистраторов установлен флаг аддитивности в значение true.

4 голосов
/ 29 декабря 2014

Просто добавьте

logger.setadditivity(false);

к вашему коду ( Ссылка ).

У нас двойные результаты в консоли, потому что аппендеры не одиночные, они аддитивные. Это означает, что категория наследует всех дополнений от своих предков (по умолчанию). Если мы добавим приложение к категории и оно выполнит запись в тот же базовый поток (консоль, тот же файл и т. Д.), Что и какой-либо другой приложение, то одно и то же сообщение журнала появится в журнале дважды (или более). Кроме того, если две категории в иерархии настроены на использование одного и того же имени приложения, Log4j дважды напишет этому приложению. Настроен для этой категории

2 голосов
/ 23 сентября 2014

Если вы можете запустить программу с отладчиком Java, поместите точку останова в программу, где происходит один из этих двойных вызовов журналирования.

Проверьте объект регистратора в отладчике.Если это org.apache.log4j.Logger (v 1.2.x), то он может иметь AppenderAttachableImpl.Вы можете запросить AppenderAttachableImpl для получения списка приложений.

Если вы найдете более 1 приложения, это может быть проблемой - и ключом к ее исправлению.

0 голосов
/ 26 февраля 2019

В вашем resources/log4.properties файле.

В этом файле конфигурации, если у вас есть «log4j.rootLogger= DEBUG, file», не включайте «log4j.logger.org.springframework=DEBUG, file». Просто сохраните часть log4j.rootLogger.

0 голосов
/ 31 января 2019

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

        // Root
    rootLogger = Logger.getRootLogger();
    rootLogger.removeAllAppenders(); // Solve my problem
        // CSV
    csvLogger = rootLogger.getLogger("csvLogger");
        // Txt
    txtLogger = rootLogger.getLogger("txtLogger");

Без этой дополнительной строки, даже при установке аддитивности на false, всякий раз, когда я регистрируюсь с помощью моего csvLogger или txtLogger, он регистрируется дважды.

0 голосов
/ 29 сентября 2017

Потенциальная альтернатива настройке свойства additivity заключается в проверке ваших регистраторов от наиболее специфических до наиболее общих. В следующем примере мы ожидаем увидеть двойное ведение журнала в консоли для любых событий журнала, происходящих в foo.bar.LoggingExampleClass. Было бы безопасно удалить дополнительный Console appender из регистратора foo.bar.LoggingExampleClass, поскольку он уже покрыт корневым регистратором.

<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 будет означать, что событие регистрации не будет добавлено к файлу MainLogFile, указанному в корневом журнале.

С другой стороны, полагаться на родительских дополнений может быть проблематично, если их родительские дополнения будут изменены без изучения влияния на более детализированные регистраторы. Например, предположим, что существует требование, чтобы события ведения журнала foo.bar.LoggingExampleClass записывались в консоль. В настоящее время они находятся в приведенном выше примере конфигурации из-за аддитивности, даже если удалено приложение Console Logger foo.bar.LoggingExampleClass Logger. Однако, если приложение Console также было удалено из корневого регистратора без каких-либо дополнительных настроек, требование больше не будет выполнено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...