Thank you for reading this post, don't forget to subscribe!
Что бы избежать заполнения диска старыми логами — необходимо настроить утилиту logrotate
.
Основной файл конфигурации — /etc/logrotate.conf
.
Для создания настроек отдельных логов — используем директорию /etc/logrotate.d
, которая описана как:
# RPM packages drop log rotation information into this directory |
include /etc/logrotate.d |
Добавим наблюдение за логом /var/log/iptables.log
.
Создаём файл /etc/logrotate.d/iptables.conf
с таким содержимым:
/var/log/iptables.log {
rotate 5
missingok
notifempty
compress
size 1M
daily
create 0644 root root
postrotate
service rsyslog restart > /dev/null
endscript
}
Опции тут:
rotate
— количество копий старых логов;missingok
— не писать сообщения вstdout
, если файл отсутствует;notifempty
— не выполнять никаких действий, если файл пустой;compress
— сжиматьgzip
;size
— размер файла, при достижении которого он будет сжат и сохранён как старый;daily
— выполнять проверку каждый день;create
— права доступа и владелец при создании нового файла;
Дополнительные опции:
olddir
— перемещать старые логи в указанную директорию;postrotate/endscript
— действие, выполняемое после ротации логов;mail
— адрес, на который высылать уведомление о ротации;
Для проверки — выполняем:
1 |
# logrotate -f /etc/logrotate.conf |
Учтите — это действие выполнит обязательную ротацию всех логов, указанных в конфигурации logrotate
.
Ротация почтовых логов:
cat /etc/logrotate.d/maillog
/var/log/maillog
{
daily
missingok
sharedscripts
rotate 10
compress
delaycompress
postrotate
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
endscript
}
============================================================
Ротация файлов по размеру в logrotate
Для примера буду описывать ротацию логов 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 для хранения старых логов.