logrotate — ротация логов

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.

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

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

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

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

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

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

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

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

Фор­мат име­ни архив­но­го лога будет 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/old для хра­не­ния ста­рых логов.