Log4j неожиданно прекращает ведение журнала
Я создаю приложение Portlet, развернутое на сервере WebSphere Portal Server, работающем в Linux. Каждый портлет WAR использует Log4j для ведения журнала с такой конфигурацией, каждый из которых содержит два файла журнала WAR:
log4j.logger.im.the.package=DEBUG, InfoAppender, DebugAppender
log4j.appender.InfoAppender=org.apache.log4j.RollingFileAppender
log4j.appender.InfoAppender.Threshold=INFO
log4j.appender.InfoAppender.File=/tmp/infoWARName.log
log4j.appender.InfoAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.InfoAppender.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.DebugAppender=org.apache.log4j.RollingFileAppender
log4j.appender.DebugAppender.Threshold=DEBUG
log4j.appender.DebugAppender.File=/tmp/debugWARName.log
log4j.appender.DebugAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.DebugAppender.layout.ConversionPattern=%d %p [%c] - %m%n
После развертывания все работает, как чам и файлы журналов начали заполняться. Через несколько часов и в то же время остановка ведения журнала и info.log
и debug.log
вообще не обновляются. Нам нужно перераспределить WAR-сервер Portlet на сервере, чтобы возобновить ведение журнала.
Любые идеи?
Update:
Я начинаю подозревать, что это связано с моей Logging JARS. В настоящее время это JAR внутри моей папки WEB-INF/lib
:
com.springsource.org.apache.commons.logging-1.1.1.jar
com.springsource.org.apache.log4j-1.2.15.jar
com.springsource.slf4j.api-1.5.6.jar
slf4j-log4j12-1.5.6.jar
Второе обновление:
В часах от щедрости до конца, это то, как Log4j настроен в каждом приложении Portlet. Здесь web.xml
:
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:miAppLog4j.properties</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
И miAppLog4j.properties
файл находится в папке, внешней по отношению к WAR и Portal. Мы сделали его доступным в Portlet Classpath через общую библиотеку в WebSphere Portal.
Ответы
Ответ 1
Вы предоставили некоторую базовую информацию, поэтому я могу только набросать некоторые причины и вероятность кандидата:
1. Проблема с файловыми замками/ручками/потоком ввода-вывода
-
Сгенерировано с помощью каротажа журналов?
Отрицательный в вашем случае. Два отдельных файла журнала (информация и отладка) останавливаются одновременно для любой данной WAR.
Каждый файл загружается с максимальным размером по умолчанию (10 МБ). Очень маловероятно, что оба журнала всегда будут перематываться одновременно. Ошибка не должна запускаться при кадрировании журнала. Дополнительное подтверждение путем настройки log4j.appender.InfoAppender.MaxFileSize=200MB
-
Запущено пользователями, управляющими файлами Linux?
Отрицательный в вашем случае. Возможно, пользовательские/sysadmin-манипулирующие файлы могут создавать блокировки или устаревшие дескрипторы файлов. У Linux никогда не должно быть проблем с пользователем, зависящим от файла (но окна делают). У Linux могут быть проблемы с загрузкой или редактированием файлов пользователями. Но ваша проблема кажется очень повторяемой, что делает ее маловероятной, если у вас нет автоматических скриптов, управляющих файлами журнала.
-
Запущено "конкурентными" настройками конфигурации в Websphere или Spring, при дублированном использовании одних и тех же файлов журналов сервером/картой?
Кажется маловероятным в вашем случае. Кажется, вы не настраивали конфигурацию ведения Websphere commons. Ведение журнала Commons автоматически включается в родительский класс ClassLoader сервера websphere и может быть настроено на "перенос" в Log4J путем настройки:
Файл commons-logging.properties
# Set application classloader mode as PARENT_LAST when deploying in WAS as .ear
priority=1
org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.LogFactoryImpl
-
Запущено аппаратными проблемами/сбой диска?
Кажется странным, что такая проблема будет очень повторяемой.
2. Проблема с java-потоками?
- смерть смерти или тупик
-
массивная обработка/утверждение потока в "другом" коде, так что код с протоколированием не запускается
Из вашего описания я предполагаю, что приложение все еще работает и работает нормально с нормальной производительностью и функциональностью, но журналы не записываются. Можешь подтвердить? Если это так, то это не проблема потока с потоками webapp.
Также я могу подтвердить, что это не проблема потока в логике Log4J, потому что единственный раз, когда он создает/использует свой собственный поток, используется один из AsynchAppender/ExternallyRolledFileAppender/SocketAppender/TelnetAppender или когда PropertyConfigurator.configureAndWatch или Вызывается метод DOMConfigurator.configureAndWatch.
то есть. Negative.
3. Изменения в классах Log4J в ClassLoaders с использованием различной конфигурации?
-
Родительский ClassLoader сталкивается с Webapp ClassLoader
например. Сначала ваши веб-приложения начинаются с собственных настроенных классов из каталога WEBINF, и все это хорошо, но позже через какое-то время другое приложение вызывает (или один из инструментов администрирования сервера портала), заставляет класс clooting загружаться в родительский ClassLoader и ваше приложение "поднимает" эту новую незаконную версию класса и терпит неудачу.
Вполне возможно, проблема - тысячи пользователей в Google боролись с загрузчиками классов Websphere.
Рекомендуемое действие:
-
убедитесь, что все ваши веб-приложения используют PARENT_LAST ClassLoading - перейдите в консоль администратора и убедитесь, что у них есть PARENT_LAST, установленный во всех конфигурациях WebApp
-
убедитесь, что вы получаете внутренние сообщения об ошибках Log4J, записанные на консоль
Например. Умышленно проверяйте, принудительно удаляя журнал ошибок как admin во время работы приложения, создавая устаревший дескриптор. Если сообщения "Log4J:" не отображаются в консоли, это серьезная проблема.
В следующий раз, когда проблема возникнет, перехватите все подобные сообщения консоли и сообщите об этом. Кроме того, вы можете установить "-D log4j.debug" в JVM/websphere startup, чтобы точно узнать, что Log4J делал до/во время проблемы - сообщения будут отправляться на консоль.
-
Вам действительно нужно установить уровень ведения журнала на DEBUG для всех ваших пакетов и классов? Лучше установить INFO или WARN и только выборочно устанавливать, когда вы отлаживаете определенные проблемы?
Это много текста.......... B ^)
Ответ 2
В течение более 5 лет Log4j практически не исправляет ошибок: это фактически мертвый проект.
Если это приемлемо, подумайте о замене его на Logback, который реализует SLF4j напрямую.
Logback и SLF4J написаны тем же парнем, который написал Log4J (Ceki), имеет еще более либеральную лицензию и имеет хорошее сообщество. Это преемник Log4J 1 всеми возможными способами (кроме его имени).
Ответ 3
Я думаю, проблема заключается в том, что у вас есть несколько WAR, которые записываются в один и тот же файл журнала. По нашему опыту log4j не может сделать это надежно, особенно с помощью скользящих добавок. Когда кто-то идет, чтобы бросить его, другие запутались и не смогли войти в систему дальше. Или продолжить запись в старый файл.
Я подозреваю, что вам придется иметь каждый журнал WAR в другом файле.
Ответ 4
Я бы попытался переместить местоположение файла журнала где-то, кроме временной файловой системы.
Ответ 5
Я не уверен, почему log4j останавливается в вашем приложении. Но вы могли (должны) обновиться до log4j 2.0. Переключение не должно прикладывать больших усилий. Вам нужно будет переписать файл log4j.properties в файл XML, потому что новая версия больше не поддерживает файл свойств.
В Java Magazin в статье говорилось, что log4j 2.0 ведет себя более устойчиво в многопоточных средах, поэтому есть шанс, что он исправит вашу проблему. Если это не так, вы по-прежнему пользуетесь новой версией.
Он приносит некоторые приятные функции и улучшения (скопирован с log4j сайта):
Разделение API
API для Log4j отделен от реализации, что позволяет разработчикам приложений понять, какие классы и методы они могут использовать, обеспечивая при этом прямую совместимость. Это позволяет команде Log4j безопасно и совместимо улучшать реализацию.
Улучшенная производительность
Log4j 2 работает быстрее, чем Log4j 1.x в критических областях и аналогично Logback в большинстве случаев. См. "Производительность" для получения дополнительной информации.
Поддержка нескольких API-интерфейсов Хотя Log4j 2 API обеспечит лучшую производительность, Log4j 2 обеспечивает поддержку API SLF4J и Commons Logging.
Автоматическая перезагрузка конфигураций
Подобно Logback, Log4j 2 может автоматически перезагрузить свою конфигурацию после изменения. В отличие от Logback, он будет делать это без потери событий журнала, пока происходит реконфигурация.
Расширенная фильтрация
Подобно Logback, Log4j 2 поддерживает фильтрацию на основе данных контекста, маркеров, регулярных выражений и других компонентов в событии журнала. Фильтрация может быть указана для применения ко всем событиям, прежде чем передавать их регистраторам или при их передаче через Appenders. Кроме того, фильтры также могут быть связаны с Loggers. В отличие от Logback, вы можете использовать общий класс Filter в любом из этих условий.
Архитектура плагинов
Log4j использует шаблон плагина для настройки компонентов. Таким образом, вам не нужно писать код для создания и настройки Appender, Layout, Pattern Converter и т.д. Log4j автоматически распознает плагины и использует их, когда конфигурация ссылается на них.
Поддержка свойств
Вы можете ссылаться на свойства в конфигурации, Log4j будет их непосредственно заменять, или Log4j передаст их базовому компоненту, который будет динамически их решать. Свойства исходят из значений, определенных в файле конфигурации, свойствах системы, переменных среды, карте ThreadContext и данных, присутствующих в событии. Пользователи могут дополнительно настроить поставщиков свойств, добавив их собственный плагин Lookup.