Почему JBoss и Logrotate создают файлы журналов, содержащие символы NUL?

Я настроил Logrotate для ночного вращения журналов JBoss Application Server 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?

3 ответа

Решение

У нас была такая же проблема для файла, записываемого log4j. Решением было установить свойство "Append" для 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>
  1. Создайте сценарий оболочки, который сжимает свернутый файл журнала.
  2. Установите этот сценарий оболочки в Crontab сервера Unix, чтобы он работал ежедневно. Например, запускается ежедневно в 0:10 утра (почему 0:10 утра? Это дает достаточно времени для log4j, чтобы завершить ролловер, на тот случай, если файлы журналов слишком велики или слишком много файлов журналов. сжать).
  3. Наконец, убедитесь, что ролловер log4j выполняется в 12:00 (по умолчанию) и задание cron, которое выполняет сценарий оболочки в 0:10.
Другие вопросы по тегам