рік тому я налаштував собі невеличкий сервер журналів, та й забув про нього. ну як забув — насправді ні, але руки не доходили дивитися ті журнали, та то й добре — значить, не було потреби, все працювало як слід. так? а не зовсім, бо на самому сервері журналів тим часом робилося чорт зна що: logrotate наплодив величезну кількість порожніх файлів у теках деяких (не всіх) хостів… досяг ліміту довжини назви файлу (255 символів для ext4) й почав спамити помилками у власному журналі. виявилося це випадково, коли мені заманулося погратися з переглядачем журналів lnav; довелося ремонтувати.
ось такий срач (server — машина в мережі, старий сервер):
> ls -lh /var/log/hosts/server
...
server.log.1.1.1.1.1.1.1.1.1.2
server.log.1.1.1.1.1.1.1.1.2
server.log.1.1.1.1.1.1.1.2
server.log.1.1.1.1.1.1.2
server.log.1.1.1.1.1.2
server.log.1.1.1.1.2
server.log.1.1.1.2
server.log.1.1.2
server.log.1.2
server.log.2
те саме в теках hosts/roku, router… але не micro, ap2? найцікавіший випадок — vpn (окрема віртуалка з одним сервісом):
ls -lh /var/log/hosts/vpn
total 76M
-rw-r----- 1 root adm 21K Feb 27 2023 debug.log
-rw-r----- 1 root adm 1.1M Dec 11 10:30 ovpn-server.log
-rw-r----- 1 root adm 0 Nov 5 00:00 ovpn-server.log.1
-rw-r----- 1 root adm 0 Nov 6 00:00 ovpn-server.log.1.1
-rw-r----- 1 root adm 0 Nov 7 00:00 ovpn-server.log.1.1.1
-rw-r----- 1 root adm 0 Nov 8 00:00 ovpn-server.log.1.1.1.1
-rw-r----- 1 root adm 0 Nov 9 00:00 ovpn-server.log.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 10 00:00 ovpn-server.log.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 11 00:00 ovpn-server.log.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 12 00:00 ovpn-server.log.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 13 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 14 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 15 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 16 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 17 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 18 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 19 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 20 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 21 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 22 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 23 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 24 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 25 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 26 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 27 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 28 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 29 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Nov 30 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Dec 1 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Dec 2 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Dec 3 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Dec 4 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Dec 5 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Dec 6 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Dec 7 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Dec 8 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Dec 9 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Dec 10 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 0 Dec 11 00:00 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 51M Nov 4 17:57 ovpn-server.log.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
-rw-r----- 1 root adm 24M Dec 11 19:17 vpn.log
4-го листопада журнал ovpn-server.log виріс до 50 мб, і далі logrotate намагався щодня (?) зберегти попередній файл, додавши одиничку до назви. в інших теках це (50 мб?) трапилося раніше, тому файлів наплодилося більше; деякі з них не нульової довжини.
найперше — ідентифікую «проблемні» теки, в кожній створюю один «архівний» файл .old
і скидаю туди всі файли з цифровими суфіксами, а самі файли видаляю:
> sudo -i
> cd /var/log/hosts/server
> touch server.log.old
> for file in *.log.*; do cat "${file}" >> server.log.old && rm "${file}" && echo -n "." || echo -n "x"; done; echo
перебір *.log.*
не дуже коректний і «зламається» на самому server.log.old, але &&
не дасть його видалити, тож для моєї задачі вистачає:
> ls -lh
total 124M
-rw-r----- 1 root adm 23M Dec 11 20:17 server.log
-rw-r--r-- 1 root root 102M Dec 11 20:15 server.log.old
далі треба знайти, яка заковика в конфігурації logrotate спричинила до цього. оскільки «вражено» лише підтеки /val/log/hosts/
, за котру відповідає файл налаштувань /etc/logrotate.d/remote
— причина має бути саме там:
> cat /etc/logrotate.d/remote
/var/log/hosts/* /var/log/hosts/*/* {
size 50M
rotate 3
notifempty
missingok
}
от же ж бовдур! звісно ж, що /var/log/hosts/*/*
намагатиметься процесувати — а отже додати суфікс і збереги, — не лише .log
, але й .log.1
, і .log.1.1
тощо. чому я конфігурував цю маячню? гадаю, мене ввів в оману ось цей приклад з man logrotate
:
/var/log/news/* {
monthly
rotate 2
olddir /var/log/news/old
missingok
postrotate
kill -HUP 'cat /var/run/inn.pid'
endscript
nocompress
}
але ж тут olddir
явно переміщує старі журнали до окремої підтеки, тоді як я не додав цього, та й не хотів би зайве ускладнювати і без того глибоку структуру тек. як би не було, виправляю свою конфігурацію:
/var/log/hosts/*/*.log {
size 50M
rotate 3
notifempty
missingok
наостанок налаштував ще ping на healthcheck.io для logrotate. тепер має бути гаразд. за тиждень перевірю, а тим часом можна «погратися» з lnav, нарешті.
поновлення (2023-12-12). для щоденного пінгу healthcheck, я додав два curl’и до /etc/cron.daily/logrotate
:
/usr/sbin/logrotate /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
# Notify healthcheck.io on failed logrotate
/usr/bin/curl -fsS --retry 3 https://hc-ping.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/fail >/dev/null
else
# Update healthcheck.io with healthy ping
/usr/bin/curl -fsS --retry 3 https://hc-ping.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx >/dev/null
fi
exit $EXITVALUE
але вночі вони не спрацювали. чому? тому що цей скрипт спершу перевіряє, чи присутній systemd:
# skip in favour of systemd timer
if [ -d /run/systemd/system ]; then
exit 0
fi
я забув поглянути, чи є таймер logrotate. а він є:
> systemctl status *timer
> cat /lib/systemd/system/logrotate.timer
...
> cat /lib/systemd/system/logrotate.service
...
[Service]
Type=oneshot
ExecStart=/usr/sbin/logrotate /etc/logrotate.conf
...
трошки вдосконалюю logrotate.service
, додавши ExecStopPost
(документація systemd, healthcheck):
[Service]
Type=oneshot
ExecStart=/usr/sbin/logrotate /etc/logrotate.conf
ExecStopPost=/usr/bin/curl -fsS --retry 3 https://hc-ping.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/${EXIT_STATUS} >/dev/null
можна спробувати:
> sudo systemctl daemon-reload
> sudo systemctl start logrotate.service
дашборд healthcheck.io показує свіжий зелений пінг.