Logrotate Успешно, оригинальный файл возвращается к исходному размеру


11

У кого-нибудь были проблемы с logrotate до того, как файл журнала был повернут, а затем вернулся к тому же размеру, который был изначально? Вот мои выводы:

Logrotate Script:

/var/log/mylogfile.log {
    повернуть 7
    ежедневно
    компресс
    olddir / log_archives
    missingok
    notifempty
    copytruncate
}

Подробный вывод Logrotate:

копирование /var/log/mylogfile.log в /log_archives/mylogfile.log.1
усечение /var/log/mylogfile.log
сжатие журнала с помощью: / bin / gzip
удаление старого журнала /log_archives/mylogfile.log.8.gz

Файл журнала после усечения происходит

[root @ server ~] # ls -lh /var/log/mylogfile.log
-rw-rw-r-- 1 часть1 часть1 0 11 января 17:32 /var/log/mylogfile.log

Буквально через несколько секунд:

[root @ server ~] # ls -lh /var/log/mylogfile.log
-rw-rw-r-- 1 часть1 часть1 3.5G 11 января 17:32 /var/log/mylogfile.log

Версия RHEL:

[root @ server ~] # cat / etc / redhat-release 
Red Hat Enterprise Linux ES выпуск 4 (обновление Nahant 4)

Версия Logrotate:

[root @ DAA21529WWW370 ~] # rpm -qa | grep logrotate
Logrotate-3.7.1-10.RHEL4

Несколько заметок:

  • Служба не может быть перезапущена на лету, поэтому я использую copytruncate
  • Журналы вращаются каждую ночь, в соответствии с olddirкаталогом, содержащим файлы журналов в нем каждую ночь.

Ответы:


18

Вероятно, это связано с тем, что даже если вы усекаете файл, процесс записи в файл будет продолжать запись с любым смещением, которое было в конце. Итак, что происходит, так это то, что logrotate усекает файл, размер равен нулю, обрабатывает запись в файл снова, продолжая со смещением, в котором он остановлен, и теперь у вас есть файл с NULL-байтами до точки, где вы его урезали, плюс новый Записи записываются в журнал.

od -c после усечения + внезапный рост, сгенерированный вывод по направлениям:

0000000  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
33255657600  \0   C   K   B   -   s   e   r   v   e   r       [   h   t   t
33255657620 <more log output>

Это говорит о смещении от 0 до 33255657600, ваш файл состоит из нулевых байтов, а затем некоторых разборчивых данных. Достижение этого состояния не занимает столько же времени, сколько потребовалось бы для записи всех этих нулевых байтов. Файловые системы ext {2,3,4} поддерживают то, что называется разреженными файлами, поэтому, если вы будете искать за областью файла, которая ничего не содержит, предполагается, что эта область содержит нулевые байты и не будет занимать место на диске. Эти нулевые байты на самом деле не будут записаны, просто предполагается, что они есть, поэтому время, необходимое для перехода от 0 до 3,5 ГБ, не занимает много времени. (Вы можете проверить количество времени, которое требуется, выполнив что-то вроде dd if=${HOME}/.bashrc of=largefile.bin seek=3432343264 bs=1этого, это должно создать файл размером более 3 ГБ за несколько миллисекунд).

Если вы запускаете ls -lsсвои файлы журналов после того, как они были усечены и снова имели неожиданный рост, теперь в отчете должно появиться число, представляющее фактический размер (в блоках, занятых на диске), который, вероятно, составляет порядки величины. меньше, чем размер, указанный просто ls -l.


Я так не думаю - за считанные секунды файл журнала уходит от 0 байтов до 3,5 ГБ. Общее время, необходимое для завершения logrotate, составляет около 5 минут. Файлы журналов записываются не так быстро, И размер всегда равен исходному размеру, что кажется слишком случайным.
drewrockshard

Должен быть простой способ проверить это, проверить файл и посмотреть, есть ли в нем что-нибудь. Начните с запуска od -c filename | head -n 100. Скорее всего, он скажет вам в несколько строк, что есть грузовик с нулевыми байтами плюс последние записи в журнале.
Kjetil Joergensen

Если это так, то можем ли мы проверить, урезает ли cat / dev / null> /var/log/mylogfile.log файл таким образом, чтобы решить эту проблему, вместо использования logrotate, встроенного в copytruncate?
Мтинберг

2
Проблема не в том, как файл обрезается, а в том, как программа записывает файл журнала. Для усечения лог-файла, чтобы быть жизнеспособным подходом, вы должны заставить программу записи в лог-файл как-то стремиться к позиции 0. Возможно, что файловая система, которая не поддерживает разреженные файлы, не будет иметь этой проблемы, хотя я не У меня нет способа проверить это прямо сейчас.
Kjetil Joergensen

1
Этот окончательный ответ на самом деле имел больше смысла, и исправление, вероятно, приведет к перезапуску приложения.
drewrockshard

2

Я чрезвычайно уверен, что Kjetil ударил его. Дрю, возможно, ты еще не убежден его объяснением, но я призываю тебя внимательно прочитать то, что он сказал.

Если вы примете это, исправление будет либо останавливать и перезапускать ваше приложение, когда журналы вращаются, либо использовать инструмент, подобный «rotatelogs» apache, где вы передаете вывод журнала в инструмент через трубу, и инструмент заботится о вращая лог-файл очень часто. Например, один из моих экземпляров apache регистрируется с

ErrorLog "|/usr/sbin/rotatelogs /www/logs/error_log 604800"

что вызывает много лог-файлов с такими именами, как

-rw-r--r--    1 root     root         4078 Dec 21 01:04 error_log.1292457600
-rw-r--r--    1 root     root         4472 Dec 29 08:41 error_log.1293062400
-rw-r--r--    1 root     root        78630 Jan  4 12:57 error_log.1293667200
-rw-r--r--    1 root     root        15753 Jan 12 01:10 error_log.1294272000

появляться без перезапуска apache; Затем я могу сжать их вручную после свершившегося факта. Обратите внимание, как вращение выполняется каждую неделю, то есть каждые 604800 секунд, то есть передаваемый аргумент rotatelogs.

Если вы не можете остановить и перезапустить приложение, и оно не может войти через канал, я думаю, у вас есть реальная проблема. Возможно, у других будут предложения.


0

было бы здорово, если бы вы могли отправить весь логротейт.

Зачем пытаться использовать kill -HUP? (Классическая перезагрузка без перезапуска ) метод.

Также ... уточните, lsof кто имеет доступ к файлу.


Не может использоваться, так kill -HUPкак это приложение не может быть затронуто каким-либо образом - это чувствительное приложение, которым я не владею (я даже не управляю им - я только управляю стороной ОС), поэтому я должен быть в состоянии сделать это путь.
drewrockshard

1
Извините, исходное сообщение было отправлено раньше, вот и остальная часть моего исходного сообщения: сегодня утром я вошел в систему, и теперь файл вернулся в нормальное состояние после того, как /etc/cron.dailyбыл начат запланированный вход в систему . Вопрос ко всем: Есть ли что-то, что скрипт logrotate делает иначе, чем запуск logrotate вручную? Мой скрипт logrotate выглядит буквально так /usr/sbin/logrotate /etc/logrotate.conf. Это довольно сложно.
drewrockshard

-1

Просто используйте «>>», что означает добавление вместо «>», что означает создание из ваших сценариев, которые пишут в этот файл. У меня была точно такая же проблема, и я исправил ее, используя append в моем скрипте.

SomeScript.sh >> output.txt

Надеюсь, что это понятнее.


Там нет никаких признаков того, что запись в лог - файл выполняется с помощью >из сценария. Более того, этот ответ сбивает с толку, потому что между сценариями >и >( )в них есть существенная разница . Наконец, если код, выполняющий запись, обновляется, было бы гораздо лучше, если бы он просто начал писать в новый лог-файл после того, как logrotateвсе сделано.
Касперд

Я редактирую свой ответ, чтобы он был понятнее.
user578558
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.