Beheer van logbestanden onder Linux

Standaard: logrotate
De standaard oplossing om logbestanden (log files) te onderhouden in Linux heet logrotate.

Logrotate is ontworpen om het beheer te vergemakkelijken van systemen die grote aantallen logbestanden genereren. Het maakt automatische rotatie, compressie, verwijdering en mailing van logbestanden mogelijk. Elk logbestand kan dagelijks, wekelijks, maandelijks worden verwerkt of wanneer het te groot wordt.

Alternatief: script en opdrachtregels via cron
Dit artikel gaat niet over logrotate maar over een alternatieve manier om logbestanden te beheren.

De aanleiding is dat ik soms mailboxen moet synchroniseren. Iedere sync resulteert in een logbestand. Wanneer ik bijvoorbeeld ieder half uur (of iedere vijf minuten) een sync uitvoer, dan neemt het aantal logbestanden snel toe. Voor het synchroniseren van mailboxen gebruik ik imapsync (zie ook imapsync.lamiral.info).

Vaak monitor ik dit soort dingen niet live maar voer ik syncs uit via een geplande taak. Onder Linux kun je dat doen met cron. Uiteraard test ik een sync, voordat deze d.m.v. cron wordt uitgevoerd. Ik doe dat door de optie --dry toe te voegen. Wanneer blijkt dat een sync goed zal lopen, dan haal ik de toevoeging --dry weer weg uit de opdrachtregel.

Omdat ik wil weten of deze syncs goed gaan, sla ik de logbestanden op. Omdat die logbestanden groot kunnen worden - en omdat er veel van gemaakt worden, comprimeer ik deze logbestanden regelmatig. Daarnaast verwijder ik oude logbestanden, zodat mijn server niet vol loopt met oude logs. Vaak is het zo dat ik 30 dagen terug wil kunnen kijken. Daarnaast kopieer ik een logbestand van de eerste succesvolle sync, zodat ik aan kan tonen dat deze initiële sync goed is verlopen.

Mailbox synchroniseren (bash script)
Ik heb op mijn server imapsync geïnstalleerd in de map /opt/imapsync. Hierin staan de bestanden i3, imapsync en webserver. Op de directories en bestanden heb ik de juiste rechten ingesteld, zodat een gewone gebruiker deze commando's uit mag voeren (chown voor de gebruiker en chmod voor de rechten). Vervolgens heb ik de map imapsync onder /var/log/ aangemaakt. Het eigenaarschap heb ik ingesteld op de gebruiker waarmee ik imapsync uitvoer. De bedoeling is namelijk om imapsync niet als root user uit te voeren.

Tot slot heb ik een bash script gemaakt waarmee ik de sync uitvoer. Dit script heb ik in mijn home folder geplaatst. Vervolgens heb ik er voor gezorgd dat alleen deze user bij die map mag (chmod 0700). De locatie is: ~/scripts/imap en het script heet sync_domeinnaam.sh. Ook de rechten op dit script zijn beperkt tot alleen uitvoeren door de gebruiker (chmod 0700). De reden hiervoor is dat in zo'n script de benodigde wachtwoorden in leesbaar tekst zijn opgeslagen. Dat is gevoelige informatie die zo goed als mogelijk afgeschermd moeten worden.

Het script ziet er als volgt uit (zie hieronder).

#!/bin/sh

### HEADER ###

LOCKFILE="/var/lock/`basename $0`"
LOCKFD=99

# PRIVATE
_lock()             { flock -$1 $LOCKFD; }
_no_more_locking()  { _lock u; _lock xn && rm -f $LOCKFILE; }
_prepare_locking()  { eval "exec $LOCKFD>\"$LOCKFILE\""; trap _no_more_locking EXIT; }

# ON START
_prepare_locking

# PUBLIC
exlock_now()        { _lock xn; }  # obtain an exclusive lock immediately or fail
exlock()            { _lock x; }   # obtain an exclusive lock
shlock()            { _lock s; }   # obtain a shared lock
unlock()            { _lock u; }   # drop a lock

### BEGIN OF SCRIPT ###

# Simplest example is avoiding running multiple instances of script.
exlock_now || exit 1

/opt/imapsync/imapsync \
--logdir /var/log/imapsync/LOG_imapsync \
--nossl1 --notls1 \
--host1 srv12345.host1.nl --user1  --password1 'SuperGeheim123' \
--host2 server67890.host2.nl --user2  --password2 'GeheimSuper321'

Wanneer ik ./sync_domeinnaam.sh uitvoer, dan wordt er in de directory /var/log/imapsync/LOG_imapsync een logbestand neergezet.

  • Opmerking: test een script altijd d.m.v. een dry-run (test run). Dat kan door achter de laatste regel een backslash \ neer te zetten. onder die laatste regel voeg je dan --dry toe. De backslash en de regel --dry kunnen weg gehaald worden zodra duidelijk is dat alles goed verloopt. Voer het script vervolgens nog eens uit, zodat je kunt zien dat alles goed gaat. Gaat er iets mis, dan kun je onderbreken d.m.v. de toetsencombinatie CTRL + C.
  • Tip: installeer/gebruik het commando screen wanneer je een script lang(ere tijd) uitvoert. Mocht bijvoorbeeld de SSH verbinding verbreken, dan kun je het scherm gewoon weer openen (reattach). Op HowToForge staat een uitgebreide uitleg (Engels): How to Use Linux's screen Command.

Doelen:

  • automatisch sync uitvoeren - om het half uur;
  • log files die minimaal 180 minuten (drie uren) oud zijn comprimeren;
  • log files die minimaal 30 dagen oud zijn verwijderen.

Ik open hiervoor - met de gebruiker waarmee ik imapsync uitvoer - de crontab d.m.v. het commando crontab -e. Nogmaals: ik voer dit soort acties liever niet als root user uit. Ik gebruik nano om de crontab te wijzigen (dat vind ik het gemakkelijkst).

De regels die ik heb toegevoegd zien er als volgt uit.

# imapsync: scheduled syncs
  */30  *     *        *        *        /home/main/scripts/imap/sync_domeinnaam.sh > /dev/null 2>&1
# imapsync: cleanup log files
  0     */3   *        *        *        find /var/log/imapsync/LOG_imapsync/ -maxdepth 1 -cmin +180 -type f ! -name '*.gz' -exec gzip --best "{}" \; > /dev/null 2>&1
  10    23    *        *        *        find /var/log/imapsync/LOG_imapsync/ -maxdepth 1 -mtime +30 -type f -exec rm {} \; > /dev/null 2>&1

Met de 2e regel (dat is na de commentaarregel) wordt imapsync uitgevoerd. Met de 4e regel worden logbestanden gecomprimeerd. Met de 5e regel worden oude logbestanden verwijderd.

Resultaat:
Het resultaat is dat de omvang van de logbestanden binnen de perken blijft. Met het commando `du -h /var/log/imapsync' kan ik controleren wat de totale omvang is.