Я настроил Logrotate для еженощной ротации журналов сервера приложений JBoss 4.2.2.GA. После того, как файлы журнала были повернуты и JBoss снова начнет писать в них, новые файлы журнала начинаются с того же количества символов NUL, сколько было символов в предыдущем файле журнала, за которым следуют новые сообщения журнала. Например, если размер файла JBoss server.log составляет 5000 байтов, то после ротации новый файл server.log будет начинаться с 5000 символов NUL. По прошествии нескольких дней server.log начинается с символов NUL, эквивалентных символам всех файлов журнала за предыдущие дни вместе взятых. Похоже, что JBoss запоминает свою позицию в файле журнала и продолжает работу с того места, где он остановился в усеченном файле. Вот моя конфигурация logrotate для JBoss:
/apps/jboss-4.2.2.GA/server/default/log/*log {
daily
rotate 30
compress
notifempty
copytruncate
missingok
nocreate
}
Я не могу перезапускать JBoss каждую ночь, потому что это было бы слишком долго. Я также не могу использовать log4j DailyRollingFileAppender, поскольку он не удаляет старые файлы журналов. Кто-нибудь получил, что logrotate правильно работает с JBoss?
У нас была такая же проблема для файла, записываемого log4j. Решением было установить для свойства «Добавить» для FileAppender значение «true». После этого изменения мы не наблюдали этой проблемы с файлами, имеющими NUL при вращении внешней программой, например logrotate.
По моему опыту - и причина того, что мы не используем logrotate с Log4j, заключается в том, что logrotate работает так: он переименовывает файлы, а затем инструктирует программу закрыть свои журналы и снова открыть их со старым именем файла (которого больше не существует. ), обычно с использованием сигнала HUP.
Но нельзя указать Log4j повторно открывать свои файлы журналов, поэтому я вижу, что вы используете copytruncate
вместо этого копировать файлы - проблема в том, что Log4j использует буферизованные средства записи, которые отслеживают текущую позицию записываемого файла, и когда вы усекаете файл журнала, log4j продолжает писать с того места, где он прекратил запись, до усечения. В зависимости от реализации вашей файловой системы это должно создавать «файлы с дырами» - т.е. символы NULL, которые вы видите там, на самом деле не существуют - размер файла на самом деле равен фактическим данным, а символ NULL - это то, как ваше средство просмотра представляет отверстие. С другой стороны, некоторые файловые системы не поддерживают дыры и действительно заполняют файл символами NULL, когда Log4j возобновляет запись.
Я предлагаю - не используйте logrotate, найдите способ повернуть файлы в Log4j с помощью RollingFileAppender (который поддерживает удаление старых файлов) или с помощью DailyRollingFileAppender и cronjob, который удаляет старые файлы извне (так как это должно было быть сделано ).
Это прекрасно работает. Подводя итог тому, что предложил @Guss:
1. Откройте свой «log4j.xml» и добавьте следующий аппендер (я использовал класс DailyRollingAppender и настроил его на ежедневное обновление):
* ПРИМЕЧАНИЕ. Частота ролловеров зависит от DatePattern. Видеть: http://www.codejava.net/coding/configure-log4j-for-creating-daily-rolling-log-files
<appender name="RollingAppender" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="/logging_directory_path_here/server1.log" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%p] %d %c %M - %m%n"/>
</layout>
</appender>
<root>
<priority value="info" />
<appender-ref ref="RollingAppender" />
</root>