Назад | Перейти на главную страницу

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

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

В rsyslog по умолчанию logrotate /etc/logrotate.d/rsyslog config вижу следующее:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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