Как контролировать ведение журнала сторонними компонентами в веб-приложении в Tomcat 5.5?
Мы используем Tomcat 5.5 в Linux. Наше веб-приложение использует log4j для ведения журналов (на функциональной основе и не для многих регистраторов) и намеренно устанавливает аддитивность регистраторов на false. Наши регистраторы регистрируются в нашем собственном лог-файле. Никто из них не входит в консоль.
Проблема, с которой мы сталкиваемся, состоит в том, что, когда уровень наших регистраторов установлен на DEBUG, мы начинаем получать большое количество отладочных журналов в catalina.out от сторонних компонентов, в частности, от oscache.
Существует минимальный файл log4j.properties в.../common/classes:
log4j.rootLogger=INFO, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
# Print the date in ISO 8601 format
log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
В файлах.../webapps/ourapp/WEB-INF/classes нет файла log4g.properties.
Первое, что я попробовал, изменилось на log4j.rootLogger=ERROR, A1
но это не имело значения.
Следующим, что я попробовал, было создание файла.../webapps/ourapp/WEB-INF/classes/log4j.properties, содержащего одну строку
log4j.logger.com.opensymphony.oscache=ERROR
чтобы увидеть, остановит ли это ведение журнала oscache. Это произошло, но на удивление (для меня) он остановил все нежелательные журналы, а не только журналы oscache. Поэтому я прокомментировал строку и попробовал еще раз. По-прежнему никаких нежелательных записей в журнале. Я отодвинул файл в сторону, и теперь вернулась нежелательная регистрация. Я создал log4j.properties нулевой длины, и все нежелательные журналы снова исчезли (!). Хотя это в краткосрочной перспективе то, что я хочу, это заставляет меня задуматься о том, какие другие журналы удаляются (и почему!). Так что мне неудобно просто полагаться на это.
В главе "Ведение журнала" в документах Tomcat 5.5 просто говорится, что вы можете выполнить настройку для каждого приложения, поместив файл свойств в WEB-INF / classes, но не (по крайней мере, я не могу найти) рассказать о том, как это взаимодействует с конфигурация указана в общих / классах.
Так:
- Как сторонние компоненты регистрируются на catalina.out? Я предполагаю, что их журналы могут пузыриться к корневому регистратору, но тогда почему они все еще регистрируются, даже когда уровень корневого регистратора повышен до ОШИБКИ?
- Почему установка уровня регистрации на наших регистраторах на DEBUG приводит к началу регистрации? У нас есть свои собственные имена для наших регистраторов, поэтому ни у кого не может быть предков наших регистраторов.
- Почему даже файл WEB-INF / classes / log4j.properties нулевой длины останавливает целую кучу журналирования?
- Как я могу сделать это "правильным" способом и ограничить логирование значимым образом, а не полагаться на какой-то странный (для меня) побочный эффект, чтобы отключить его?
Любопытнее и любопытнее. Я попробовал предложение Мэтта включить отладку. Я также сделал более обширный файл log4j.properties для веб-приложения:
log4j.rootLogger=INFO, SSOA1
log4j.appender.SSOA1=org.apache.log4j.ConsoleAppender
log4j.appender.SSOA1.layout=org.apache.log4j.PatternLayout
# Print the date in ISO 8601 format
log4j.appender.SSOA1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
log4j.logger.com.opensymphony.oscache=ERROR
#log4j.additivity.com.opensymphony.oscache=false
Когда кот запускается, я вижу:
log4j: Using URL [file:/srv/www/tomcat5/base/webapps/myapp/WEB-INF/classes/log4j.properties] for automatic log4j configuration.
log4j: Reading configuration from URL file:/srv/www/tomcat5/base/webapps/myapp/WEB-INF/classes/log4j.properties
log4j: Parsing for [root] with value=[INFO, SSOA1].
log4j: Level token is [INFO].
log4j: Category root set to INFO
log4j: Parsing appender named "SSOA1".
log4j: Parsing layout options for "SSOA1".
log4j: Setting property [conversionPattern] to [%d [%t] %-5p %c - %m%n].
log4j: End of parsing for "SSOA1".
log4j: Parsed "SSOA1" options.
log4j: Parsing for [com.opensymphony.oscache] with value=[ERROR].
log4j: Level token is [ERROR].
log4j: Category com.opensymphony.oscache set to ERROR
log4j: Handling log4j.additivity.com.opensymphony.oscache=[null]
log4j: Finished configuring.
Но, несмотря на тот факт, что уровень лога oscache настроен на ошибку, я все равно вижу такие вещи в журнале:
2011-03-30 14:53:22,076 [main] DEBUG com.opensymphony.oscache.base.algorithm.AbstractConcurrentReadCache - get called (key=AUDIT_KEY_OLDEST_TIMSTAMP)
Если я перевожу уровень регистратора oscache на ERROR (о чем говорит вывод отладки log4j), то почему вообще отправляется это сообщение DEBUG? Дочерний логгер переопределяет уровень в коде?
Что я заметил, так это то, что если я раскомментирую строку "addidity" для регистратора oscache в файле log4j.properties веб-приложения, тогда регистрация действительно исчезнет. Таким образом, создается впечатление, что регистрация в oscache основана на дополнениях предка, а не на его собственных. Но тогда кажется странным, что установка уровня регистратора колебаний на ERROR не останавливает эти вещи.
2 ответа
Я понял, что, черт возьми, происходит. Проблема в том, что в недрах другой части веб-приложения скрыт следующий код, который запускается, когда этот компонент переводится в режим отладки:
public static synchronized void setDebugOn(boolean debugOn) {
if (isAllDebugOn() ^ debugOn) {
setAllDebugOn(debugOn);
Enumeration en = LogManager.getCurrentLoggers();
while (en.hasMoreElements()) {
setDebugOn((Logger) en.nextElement(), debugOn);
}
setDebugOn(LogManager.getRootLogger(), debugOn);
}
}
public static void setDebugOn(String name, boolean debugOn) {
setDebugOn(getLogger(name), debugOn);
}
private static void setDebugOn(Logger logger, boolean debugOn) {
logger.setLevel(debugOn ? Level.DEBUG : Level.INFO);
}
Другими словами, когда этот компонент переводится в режим отладки, он также переводит КАЖДЫЙ ОДИНОЧНЫЙ ЛОГЕР LOG4J В WEBAPP в режим отладки (что я проверил, изменив код для вывода имени каждого регистратора внутри последнего метода эти три. Итак, blammo - все сторонние программы, использующие log4j, начинают регистрировать свои выходные данные отладки независимо от того, что говорит log4j.properties.
Когда я изменяю метод с этим циклом, чтобы связываться только с уровнями определенных регистраторов, связанных с этим компонентом, тогда моя конфигурация log4j.properties начинает работать как ожидалось.
Вы можете настроить log4j.properties, чтобы получать только журналы вашего кода, как показано ниже, и помещать их в другой файл, чем catalina.out.
handlers = org.apache.juli.FileHandler
org.apache.juli.FileHandler.level = ALL org.apache.juli.FileHandler.directory = $ {catalina.base} / logs org.apache.juli.FileHandler.prefix = yourapp-name.
com.yourproject.module.package.level = ALL