log4j rootLogger, кажется, наследовал уровень журнала другого регистратора. Почему?

У меня есть установка 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 опция)

10
задан AndrewR 16 March 2010 в 22:20
поделиться

2 ответа

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

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

log4j.additivity.SGSearch=false

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

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

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

20
ответ дан 3 December 2019 в 16:09
поделиться

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

Log4J Levels

Регистраторам могут быть назначены уровни. Набор возможных уровней, то есть 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

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

6
ответ дан 3 December 2019 в 16:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: