logrotate для своих демонов
Логи демона разрастаются, а ротации нет — файл достигает десятков гигабайт, диск забивается, мониторинг ругается. systemd-journald и syslog-ng умеют вращать сами, но если у тебя свой демон пишет напрямую в файл, ротацию несёт logrotate. Вот как его настроить под конкретный сервис.
Зачем писать свой конфиг logrotate
Пакеты из репозитория обычно ставят конфиг в /etc/logrotate.d/, но для自建 демонов или собранных из исходников его нет. Без конфига файл растёт бесконтрольно. logrotate запускается через systemd-таймер (logrotate.timer) или cron и читает все файлы из /etc/logrotate.d/. Достаточно создать один файл — и цикл ротации заработает.
Проверь, установлен ли пакет logrotate и активен ли таймер: systemctl status logrotate.timer. В большинстве дистрибутивов он включён по умолчанию.
copytruncate vs create — когда что использовать
Это два принципиально разных подхода к переименованию и созданию нового файла.
copytruncate | create | |
|---|---|---|
| Механизм | Копирует текущий файл, обрезает оригинал на месте | Переименовывает старый, создаёт новый с нужными правами |
| Приложение | Не нужно перезапускать | Нужно уметь открывать новый файл (обычно через SIGHUP или copytruncate не нужен) |
| Риск потери строк | Да — между копированием и обрезкой новые записи могут попасть в «дыру» | Минимальный — атомарное переименование |
| Когда использовать | Демон не умеет переоткрывать файл (например, написан на Go без сигналов) | Демон поддерживает SIGHUP или systemd-notify |
copytruncate — это компромисс. Строки, записанные между cp и truncate, теряются. Для высоконагруженных сервисов это может означать сотни потерянных строк в секунду.
Если демон умеет получать сигнал — используй create и перезапускай через postrotate.
delaycompress и как он влияет на цепочку архивов
По умолчанию logrotate сжимает ротированный файл сразу в тот же цикл. Проблема: если демон ещё пишет в старый файл (или ещё не переоткрыл новый), сжатие ломает всё.
delaycompress откладывает сжатие на один цикл. Цепочка выглядит так:
Без delaycompress переход выглядит жёстче: app.log сразу становится app.log.1.gz, и если демон ещё пишет в app.log через дескриптор, данные идут в сжатый архив — или теряются.
delaycompress имеет смысл только вместе с create и compress. С copytruncate он работает, но теряет смысл — ведь файл обрезается на месте, и сжатие можно делать сразу.
Интеграция с systemd notify
Если демон поддерживает sd_notify(3), можно не полагаться на postrotate с ручным перезапуском. systemd умеет перезапускать сервис по сигналу от logrotate.
В конфиге logrotate указываешь:
Или, если демон слушает NOTIFY_SOCKET:
systemctl notify-reload доступен начиная с systemd 231. Отправляет RELOADING=1, а затем READY=1 — это стандартный механизм уведомления о перезагрузке конфигурации.
Для copytruncate postrotate обычно не нужен — обрезка файла на месте не требует участия демона.
Пример рабочего конфига
Допустим, демон my-app пишет в /var/log/my-app/app.log, поддерживает SIGHUP и sd_notify.
Ключи:
| Флаг | Что делает |
|---|---|
daily | Ротация каждый день |
rotate 14 | Хранить 14 архивов |
compress | gzip-сжатие |
delaycompress | Сжатие с задержкой на один цикл |
missingok | Не ругаться, если файла нет |
notifempty | Не ротировать пустой файл |
create 0640 myapp myapp | Создать новый файл с нужными правами и владельцем |
postrotate | Уведомить systemd о перезагрузке |
Для теста без реального вращения:
Флаг -d запускает в debug-режиме — покажет, что будет сделано, без изменений файлов.
После создания конфига первый запуск происходит только на следующий запуск таймера. Чтобы принудительно проверить — logrotate -f /etc/logrotate.d/my-app. Это немедленно ротирует файл, так что используй осторожно на проде.