Ротация файлов по размеру в logrotate

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

Онлайн-курс по устройству компьютерных сетей

На углубленном курсе "Архитектура современных компьютерных сетей" вы с нуля научитесь работать с Wireshark и «под микроскопом» изучите работу сетевых протоколов. На протяжении курса надо будет выполнить более пятидесяти лабораторных работ в Wireshark.

Это будет короткая заметка про конкретную настройку. Подробно описывать работу logrotate не буду, так как в интернете и так полно материала на эту тему.

Для примера буду описывать ротацию логов nginx. После установки nginx, вы получите следующий конфиг для ротации логов - /etc/logrotate.d/nginx.

/var/log/nginx/*log {
    create 0644 nginx nginx
    daily
    rotate 10
    missingok
    notifempty
    compress
    sharedscripts
    postrotate
        /bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true
    endscript
}

Все не указанные явно параметры будут браться из дефолтного конфига /etc/logrotate.conf.

Для того, чтобы защитить сервер от заполнения всего свободного пространства диска логами access.log, ротация раз в день не подходит. Тебе за час без напряга смогут забить весь диск логами. Лучше настроить ротацию по достижении определенного размера файла. Для этого вы используете параметр:

size = 10M

И ждете, что по достижении размера файла access.log в десять мегабайт, будет произведена ротация. На самом деле не будет. По-умолчанию, logrotate запускается раз в сутки, поэтому он при всем желании не сможет следить за размером файла и ротировать его чаще, чем раз в сутки.

За его запуск отвечает скрипт в директории /etc/cron.daily/logrotate. Для того, чтобы logrotate мог проверять размер лог файла хотя бы раз в час, скрипт запуска надо перенести в директорию /etc/cron.hourly. А для более частой проверки, добавить его напрямую в cron с нужным интервалом запуска. Например, раз в 5 минут.

*/5 * * * * /etc/cron.daily/logrotate

Допустим вы все это сделали, но логи все равно не будут ротироваться при достижении заданного размера. Понять, в чем же теперь проблема, не так просто. При запуске logrotate вы не увидите никаких ошибок. Он просто ничего не будет делать. Понять, в чем проблема, можно только при запуске в режиме отладки. Там вы увидите ошибку, если в этот день ротация уже была хотя бы раз.

destination /var/log/nginx/access.log.20190826.gz already exists, skipping rotation

Смысл тут в том, что logrotate сегодня уже произвел ротацию и создал архив лога с определенным именем и второй раз такой же файл он сделать не может. А маска имени файла при создании настроена в формате %Y%m%d. За эту маску отвечает параметр в /etc/logrotate.conf:

dateext

Самый простой вариант - это просто закомментировать этот параметр, тогда все архивы логов будут иметь следующую маску в файлах:

access.log.1.gz
access.log.2.gz
access.log.3.gz

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

dateformat -%Y-%m-%d_%H-%s

Формат имени архивного лога будет access.log.2019-08-26_15-1566819154.gz. Имена больше не будут дублироваться и logrotate сможет корректно запускать ротацию при достижении указанного размера файла. Обращаю внимание, что формат тут отличается от привычной конструкции в date, к которой обычно все привыкли. Сделать формат %Y-%m-%d_%H-%M не получится. Logrotate не поймет маску с минутами %M. Так что для уникальности имени в пределах одного часа надо использовать %s.

Таким образом, чтобы настроить ротацию лог файла, например, aceess.log, по достижении определенного размера, вам нужно:

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

Вот пример для ротации конфигов nginx или apache по достижении размера лог файла в 10 мегабайт.

/var/log/nginx/*.log {
	size 10M
	dateext
	dateformat -%Y-%m-%d_%H-%s
	olddir /var/log/nginx/old
	missingok
        rotate 30
        compress
        notifempty
        create 640 nginx adm
        sharedscripts
        postrotate
                if [ -f /var/run/nginx.pid ]; then
                        kill -USR1 `cat /var/run/nginx.pid`
                fi
        endscript
}

Не забудьте создать директорию /var/log/nginx/old для хранения старых логов. На этом у меня все по ротации логов в logrotate с учетом размера файла.

Углубленный онлайн-курс по MikroTik.

Научиться настраивать MikroTik с нуля или систематизировать уже имеющиеся знания можно на углубленном онлайн-курcе по администрированию MikroTik. Автор курcа – сертифицированный тренер MikroTik Дмитрий Скоромнов. Более 40 лабораторных работ по которым дается обратная связь. В три раза больше информации, чем в MTCNA.
Не понравилась статья и хочешь научить меня администрировать? Пожалуйста, я люблю учиться. Комментарии в твоем распоряжении. Расскажи, как сделать правильно!

Помогла статья? Подписывайся на telegram канал автора

Анонсы всех статей, плюс много другой полезной и интересной информации, которая не попадает на сайт.

Автор Zerox

Владимир, системный администратор, автор сайта. Люблю настраивать сервера, изучать что-то новое, делиться знаниями, писать интересные и полезные статьи. Открыт к диалогу и сотрудничеству. Если вам интересно узнать обо мне побольше, то можете послушать интервью. Запись на моем канале - https://t.me/srv_admin/425 или на сайте в контактах.

7 комментариев

  1. Как у вас получилось сделать с расширением .gz access.log.3.gz
    apt install -y rsyslog
    rsyslogd: version 8.2302.0

    Вот с такик настройками

    /var/log/asterisk/queue_log
    /var/log/asterisk/messages.log
    /var/log/asterisk/full.log

    {
    rotate 6
    size 20M
    missingok
    notifempty
    compress
    delaycompress
    sharedscripts
    postrotate
    /usr/lib/rsyslog/rsyslog-rotate
    endscript
    }

    Создаются log.1 без расширения .gz

    messages.log.1

    • У вас указан параметр delaycompress, из-за которого сжатие откладывается на потом, поэтому файлы несжатые и расширение без .gz.

  2. Аноним

    про maxsize почитайте

  3. Александр

    Спасибо, что поделились опытом!

  4. Спасибо Вам, Владимир, за прекрасный материал изложенный в простой и доступной для понимания форме!

  5. Очень полезно. Спасибо!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Нажимая кнопку "Отправить комментарий" Я даю согласие на обработку персональных данных.
Используешь Telegram? Подпишись на канал автора →
This is default text for notification bar