Почему вращаются только некоторые из моих журналов?

Я использую Ubuntu 14.04. У меня есть следующее в моем файле /etc/logrotate.conf...

/home/rails/myproject/log {
        daily
        rotate 3
        compress
        delaycompress
        missingok
        notifempty
        create 644 rails rails
}

/var/log/postgresql {
        daily
        rotate 3
        compress
        delaycompress
        missingok
        notifempty
        create 644 root root
}

Каждую ночь я смотрел на свои журналы рельсов, и они всегда были больше - то есть, казалось, что журналы не вращались...

myuser@myproject:~$ ls -al /home/rails/myproject/log
total 4574368
drwxr-xr-x  2 rails rails       4096 May 30 12:04 .
drwxr-xr-x 15 rails rails       4096 May 30 12:03 ..
-rw-rw-r--  1 rails rails      14960 Jun  1 22:39 development.log
-rw-rw-r--  1 rails rails          0 Oct 22  2016 .keep
-rw-r--r--  1 rails rails 4523480004 Jun 22 10:19 production.log
-rw-rw-r--  1 rails rails  156358087 Jun 22 10:19 sidekiq.log
-rw-rw-r--  1 rails rails      54246 Apr 10 14:34 test.log

Когда я запускаю команду вручную, я вижу, что некоторые журналы вращаются...

myuser@myproject:~$ sudo logrotate /etc/logrotate.conf
myuser@myproject:~$ ls -al /home/rails/myproject/log
total 4570288
drwxr-xr-x  2 rails rails       4096 Jun 22 10:22 .
drwxr-xr-x 15 rails rails       4096 May 30 12:03 ..
-rw-rw-r--  1 rails rails          0 Jun 22 10:22 development.log
-rw-rw-r--  1 rails rails      14960 Jun  1 22:39 development.log.1
-rw-rw-r--  1 rails rails          0 Oct 22  2016 .keep
-rw-r--r--  1 rails rails          0 Jun 22 10:22 production.log
-rw-r--r--  1 rails rails 4523505906 Jun 22 10:23 production.log.1
-rw-rw-r--  1 rails rails  156369048 Jun 22 10:23 sidekiq.log
-rw-rw-r--  1 rails rails      54246 Apr 10 14:34 test.log

Как я могу выяснить, почему мои рельсовые бревна не вращаются ночью? Обратите внимание, что другие журналы в системе кажутся. Выше я включил свою конфигурацию postgres, и когда я смотрю там логи, кажется, что они вращаются нормально...

myuser@myproject:~$ ls -al /var/log/postgresql
total 1832
drwxrwxr-t  2 root     postgres    4096 May  2 20:42 .
drwxr-xr-x 13 root     root        4096 Jun 22 10:22 ..
-rw-r-----  1 postgres adm      1861361 Jun 22 10:14 postgresql-9.6-main.log

Спасибо, Дэйв

Редактировать: помещение конфигурации в отдельный файл, похоже, ничего не делает. Ниже моя конфигурация, а также журналы, которые, кажется, не вращаются...

myuser@myapp:~$ sudo cat /etc/logrotate.d/myapp
[sudo] password for myuser:
/home/rails/myapp/log/*.log {
   daily
   missingok
   compress
   notifempty
   rotate 12
   create
   delaycompress
   missingok
   su rails rails
}

Вот журналы. Похоже, ничего не случилось...

myuser@myapp:~$ ls -al /home/rails/myapp/log
total 4635956
drwxr-xr-x  2 rails rails       4096 Jun 22 10:22 .
drwxr-xr-x 15 rails rails       4096 May 30 12:03 ..
-rw-rw-r--  1 rails rails          0 Jun 22 10:22 development.log
-rw-rw-r--  1 rails rails      14960 Jun  1 22:39 development.log.1
-rw-rw-r--  1 rails rails          0 Oct 22  2016 .keep
-rw-r--r--  1 rails rails          0 Jun 22 10:22 production.log
-rw-r--r--  1 rails rails 4546785231 Jun 24 12:12 production.log.1
-rw-rw-r--  1 rails rails  200336693 Jun 24 12:51 sidekiq.log
-rw-rw-r--  1 rails rails      54246 Apr 10 14:34 test.log

3 ответа

Решение

Задача Logrotate - перемещать (переименовывать) и сжимать файлы. В этом случае вы настроили его так, чтобы переименовывать и сжимать файлы журналов Rails, а затем создавать новые с исходными именами.

Имена файлов - это способ найти файл, но реальный файл - это просто место на диске. Файл может иметь несколько имен (жесткие ссылки) или не иметь имен (вы можете rm файл, который открыт, но он все еще занимает место на диске, пока файл открыт в каком-либо процессе).

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

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

Если вы посмотрите в /etc/logrotate.d вы увидите много примеров этого, в зависимости от того, что у вас установлено.

Например, rsyslog имеет:

postrotate
    invoke-rc.d rsyslog rotate > /dev/null
endscript

Stunnel имеет:

postrotate
    /etc/init.d/stunnel4 reopen-logs > /dev/null
endscript

Это сценарии, которые сообщают соответствующему процессу о необходимости повторного открытия файла. Конкретный механизм зависит от программы, но, как правило, он отправляет HUP (или иногда USR1) (увидеть man 7 signal), которые длительно выполняющиеся процессы принимают в качестве инструкции для закрытия и повторного открытия файлов журнала.

В случае с Rails способ сделать это зависит от того, какой регистратор вы используете. Я только что видел несколько советов, предлагающих вам использовать copytruncate что в основном является "чит-опцией" в logrotate, говорящей о том, чтобы вручную копировать содержимое и очищать файл, а не перемещать его и создавать новый. (увидеть man logrotate.conf). Это используется вместо create вот так:

/home/rails/myapp/log/*.log {
    daily
    missingok
    compress
    notifempty
    rotate 12
    copytruncate
    delaycompress
    missingok
    su rails rails
}

Это не очень хорошее решение, так как оно буквально копирует весь файл (чтобы создать его моментальный снимок) перед удалением его содержимого, что довольно неэффективно.

Однако, если вы используете Unicorn для запуска своего приложения (которое мультиплексирует запросы через несколько идентичных рабочих процессов Rails), оно поддерживает сигнал USR1 в обычном режиме (убивает и заменяет всех рабочих, эффективно заставляя их заново открывать файлы) и вы можете просто отправить его в постротации, используя pkill или похожий, возможно, такой:

/home/rails/myapp/log/*.log {
    daily
    missingok
    compress
    notifempty
    rotate 12
    create
    delaycompress
    missingok
    su rails rails
    postrotate
        pkill -USR1 -u rails unicorn
    endscript
}

pkill это инструмент для поиска запущенных процессов и отправки им сигналов, поэтому он найдет все с именем unicorn работает как rails пользователь и отправить его USR1 сигнал, который говорит ему, чтобы заново открыть файлы журнала. (Примеры, которые я привел из пакетов Ubuntu ' /etc/logrotate.d файлы на самом деле делают то же самое, но в этих службах поиск скрыт в функциях /etc/init.d скрипты.)

Я уверен, что будет какой-то способ настроить разумный postrotate для любых настроек Rails, которые у вас есть (в худшем и простом случае, просто перезапустите его), но, надеюсь, это все равно объясняет сторону Ubuntu...

Похоже, проблема сводится к тому, что вы указываете каталог для ротации файлов, а не фактические имена файлов. Файлы конфигурации для logrotate принимают подстановочные знаки для подстановки (сопоставления с образцом).

Чтобы повернуть все файлы с .log расширение в вашем /home/rails/myproject/log В каталоге вы можете использовать следующую строку вместо первой строки вашей конфигурации:

/home/rails/myproject/log/*.log {

и аналогично в конфигурации каталога postgres

/var/log/postgresql/*.log {

Можно использовать * подстановочный знак без .log расширение, чтобы вращать все файлы (кроме скрытых, начинающихся с .) в вашем каталоге postgresql, но я предпочитаю добавить контроль над указанием .log только файлы:

/var/log/postgresql/* {

Обратите внимание, как вы создаете новые версии файла журнала с помощью logrotate. Если вы создаете новый журнал postgresql с 644 восьмеричными разрешениями, принадлежащим пользователю root, то пользователь postgres не сможет писать в новый файл журнала.

Проверьте статус в /var/lib/logrotate/status если показывает какие-либо проблемы

Пожалуйста, проверьте права доступа и владение файлами в /etc/logrotate.d владелец корня и режим доступа 644. Фрагмент кода для logrotate:

/home/rails/myapp/log/*.log {
   rotate 12
   daily
   missingok
   compress
   notifempty
   create 640 rails rails
   delaycompress
   missingok
}

проверьте вывод logrotate путем ручного выполнения с --verbose Если вам требуется логротация для более чем определенного размера, вы можете поэкспериментировать с maxsize а также size параметры в файле конфигурации logrotate

Другие вопросы по тегам