Для примера буду описывать ротацию логов nginx. После установки nginx, вы получите следующий конфиг для ротации логов — /etc/logrotate.d/nginx.
1 2 3 4 5 6 7 8 9 10 11 12 |
/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.
Для того, чтобы защитить сервер от заполнения всего свободного пространства диска логами aceess.log, ротация раз в день не подходит. Тебе за час без напряга смогут забить весь диск логами. Лучше настроить ротацию по достижении определенного размера файла. Для этого вы используете параметр:
1 |
size = 10M |
И ждете, что по достижении размера файла access.log в десять мегабайт, будет произведена ротация. На самом деле не будет. По-умолчанию, logrotate запускается раз в сутки, поэтому он при всем желании не сможет следить за размером файла и ротировать его чаще, чем раз в сутки.
За его запуск отвечает скрипт в директории /etc/cron.daily/logrotate. Для того, чтобы logrotate мог проверять размер лог файла хотя бы раз в час, скрипт запуска надо перенести в директорию /etc/cron.hourly. А для более частой проверки, добавить его напрямую в cron с нужным интервалом запуска. Например, раз в 5 минут.
1 |
*/5 * * * * /etc/cron.daily/logrotate |
Допустим вы все это сделали, но логи все равно не будут ротироваться при достижении заданного размера. Понять, в чем же теперь проблема, не так просто. При запуске logrotate вы не увидите никаких ошибок. Он просто ничего не будет делать. Понять, в чем проблема, можно только при запуске в режиме отладки. Там вы увидите ошибку, если в этот день ротация уже была хотя бы раз.
1 |
destination /var/log/nginx/access.log.20190826.gz already exists, skipping rotation |
Смысл тут в том, что logrotate сегодня уже произвел ротацию и создал архив лога с определенным именем и второй раз такой же файл он сделать не может. А маска имени файла при создании настроена в формате %Y%m%d. За эту маску отвечает параметр в /etc/logrotate.conf:
1 |
dateext |
Самый простой вариант — это просто закомментировать этот параметр, тогда все архивы логов будут иметь следующую маску в файлах:
1 2 3 |
access.log.1.gz access.log.2.gz access.log.3.gz |
И так далее. Если же вам хочется сохранить исходный формат лога для всех файлов, а для тех, что ротируются по размеру, настроить другую маску имени, используйте дополнительный параметр:
1 |
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, по достижении определенного размера, вам нужно:
Запускать через cron logrotate с достаточно высокой периодичностью, например раз в час или чаще.
Настроить маску файла для архива лога, чтобы она была уникальной в каждый момент запуска logrotate.
Вот пример для ротации конфигов nginx или apache по достижении размера лог файла в 10 мегабайт.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/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 с учетом размера файла.