rsyslog с logrotate: перезагрузить rsyslog против copytruncate

16

Я работаю над Ubuntu 14 с утилитой rsyslog и logrotate по умолчанию.

В /etc/logrotate.d/rsyslogконфигурации rsyslog по умолчанию logrotate я вижу следующее:

/var/log/syslog
{
        rotate 7
        daily
        missingok
        notifempty
        delaycompress
        compress
        postrotate
                reload rsyslog >/dev/null 2>&1 || true
        endscript
}

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

Так почему же конфигурация по умолчанию использует функцию перезагрузки rsyslog?

Маттан
источник

Ответы:

28

Чтобы ответить на ваш вопрос, вам сначала нужно понять разницу между перезагрузкой и копированием:

  • reload : старый файл журнала переименовывается, и процесс записи в этот журнал уведомляется (через сигнал Unix) о необходимости воссоздания своего файла журнала. Это самый быстрый / менее затратный метод: операции переименования / перемещения выполняются очень быстро и имеют постоянное время выполнения. Более того, это почти атомарная операция: это означает, что (почти) ни одна запись журнала не будет потеряна во время перемещения / перезагрузки. С другой стороны, вам нужен процесс, способный перезагрузить и заново открыть свой файл журнала. Rsyslog - такой процесс, поэтому в конфигурации logrotate по умолчанию используется метод перезагрузки. Использование этого режима с rsyslog настоятельно рекомендуется rsyslog upstream.
  • copytruncate : старый файл журнала копируется в файл архива, а затем усекается для «удаления» старых строк журнала. Хотя операция усечения очень быстрая, копия может быть довольно длинной (в зависимости от размера вашего файла журнала). Более того, некоторые записи в журнале могут быть потеряны в течение времени между операцией копирования (помните, что это может быть медленно) и усечением. По этим причинам copytruncate не используется по умолчанию для служб, способных перезагружать и заново создавать свои файлы журналов. С другой стороны, если сервер не способен перезагружать / заново создавать файлы журналов, copytruncate - ваша самая безопасная ставка. Другими словами, он не требует никакой поддержки на уровне обслуживания. Проект rsyslog upstream настоятельно рекомендует не использовать этот режим.
shodanshok
источник
Я ограничиваю свои файлы журналов 500М каждый, поэтому их копирование не составит труда (максимум несколько секунд). Благодарность!
Маттан
15

Говоря как автор rsyslog, copytruncate на самом деле очень, очень, очень плохой выбор. Это по своей природе очень редко, и его использование почти гарантирует, что вы потеряете данные журнала. Чем чаще будет записан файл, тем больше вы потеряете. И это не только часть последней строки, но может быть несколько сотен, в зависимости от точного времени и состояния системы на момент вращения.

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

На "reopenOnTruncate": лично я видел reopenOnTruncate, чтобы быть в ярости и в других отношениях, особенно с NFS и тому подобное. Некоторое время назад я полностью удалил эту функциональность, но позже убедил объединить аналогичную функциональность обратно. Она останется «экспериментальной», скорее всего, навсегда, так как я действительно знаю, что люди сталкиваются с проблемами в очень сильно загруженных системах. «copytruncate» - это просто не приличный режим для работы с файлами журналов.

В настоящее время я работаю над рефакторингом imfile (ETA 8.34 или 8.35). Реорганизованная версия, вероятно, сможет предотвратить случайную повторную отправку из-за гонки API, но также не сможет защитить от потери данных - потому что это концептуально невозможно.

Райнер Герхардс
источник
1

Это полностью зависит от того, как процесс пишет логи.
copytruncateтолько работает, если сообщения журнала добавляются в файл (например whatever >> logfile.
И не тогда , когда он перенаправляет вывод (например whatever > logfile).

обманщик
источник
1

Начиная с версии 8.16, rsyslog имеет опцию imfile, reopenOnTruncateкоторая обрабатывает проблему copytruncte.

Селиванов Павел
источник
0

В частности, для rsyslog имеет смысл оставить все как есть.

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

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

Это может быть copytruncate не причиняет вреда (хотя я был бы обеспокоен укорочением частично написанных строк), но я склонен думать, что копирование / удаление / перезагрузка «безопаснее» с точки зрения целостности.

Как уже упоминалось @ faker , поскольку rsyslog может справиться с ситуацией, когда его файл становится недоступным, нет веских причин использовать copytruncate.

И, как упомянул @ SelivanovPavel , rsyslog на самом деле требует определенной конфигурации, чтобы правильно обрабатывать усечение копирования.

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

iwaseatenbyagrue
источник