log4j rootLogger, кажется, наследует уровень журнала другого регистратора. Зачем? - PullRequest
7 голосов
/ 16 марта 2010

У меня есть установка log4J, в которой корневой регистратор должен записывать сообщения уровня ОШИБКИ и выше на консоль, а другой регистратор записывает все в системный журнал.

log4j.properties:

# Root logger option
log4j.rootLogger=ERROR,R

log4j.appender.R=org.apache.log4j.ConsoleAppender
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d %p %t %c - %m%n

log4j.logger.SGSearch=DEBUG,SGSearch
log4j.appender.SGSearch=org.apache.log4j.net.SyslogAppender
log4j.appender.SGSearch.SyslogHost=localhost
log4j.appender.SGSearch.Facility=LOCAL6
log4j.appender.SGSearch.layout=org.apache.log4j.PatternLayout
log4j.appender.SGSearch.layout.ConversionPattern=[%-5p] %m%n

В коде я делаю

private static final Logger logger = Logger.getLogger("SGSearch");
.
.
.
logger.info("Commencing snapshot index [" + args[1] + " -> " + args[2] + "]");

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

Я подтвердил, что Log4J читает файл свойств, как мне кажется, и ничего другого (с помощью опции -Dlog4j.debug)

Ответы [ 2 ]

16 голосов
/ 16 марта 2010

То, как работает цепочка Log4j, немного нелогично (по крайней мере для меня). См. руководство по log4j . Если уровень запроса равен или превышает порог наиболее конкретного совпадающего регистратора, он принимается. Как только запрос принят, он обрабатывается всей цепочкой предков независимо от их порогов!

Чтобы подавить поведение цепочки, добавьте:

log4j.additivity.SGSearch=false

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

Еще одно предложение: не называйте логгер и аппендер одинаковыми, потому что когда-нибудь в будущем вы или коллега их перепутаете. Имя регистратора должно указывать, какой тип ведения журнала обрабатывается, имя аппендера должно указывать, куда ведется регистрация. Поэтому в этом случае я думаю, что «SGSearch» может быть именем регистратора, а appender должен называться как «LocalSysLog».

Кстати: по моему мнению, вы поступаете правильно, ограничивая корневой регистратор высоким порогом и снижая его для определенных регистраторов. Это позволяет избежать беспорядка в громких библиотеках (у Apache есть несколько печально известных).

6 голосов
/ 16 марта 2010

Краткая информация об уровнях

Уровни Log4J

Регистраторам могут быть назначены уровни. множество возможных уровней, то есть DEBUG, INFO, WARN, ERROR и FATAL - это определенный в org.apache.log4j.Level класс.

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

Корневой регистратор находится в верхней части иерархия регистратора. Всегда существует и всегда имеет назначенный уровень.

Я изменил ваш пример конфигурации log4j для работы следующим образом:

# Root logger option
log4j.rootLogger=ALL,R

log4j.appender.R=org.apache.log4j.ConsoleAppender
log4j.appender.R.Target=System.out
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d %p %t %c - %m%n
log4j.appender.R.Threshold=ERROR

log4j.appender.SGSearch=org.apache.log4j.net.SyslogAppender
log4j.appender.SGSearch.SyslogHost=localhost
log4j.appender.SGSearch.Facility=LOCAL6
log4j.appender.SGSearch.layout=org.apache.log4j.PatternLayout
log4j.appender.SGSearch.layout.ConversionPattern=[%-5p] %m%n
log4j.appender.SGSearch.Threshold=DEBUG

Надеюсь, это поможет вам.

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