Vorige maand crashte een productieserver omdat het /var/log partitie volledig vol was. De oorzaak was simpel: een Laravel-applicatie die dagelijks gigabytes aan logs produceerde zonder enige vorm van rotatie. Het logbestand was inmiddels 47GB groot en nam alle beschikbare ruimte in beslag. Sindsdien configureer ik altijd meteen log rotatie voor elke nieuwe applicatie die ik deploy.
Waarom logrotatie essentieel is
Logbestanden hebben de neiging exponentieel te groeien, vooral in productiefases waar veel activiteit plaatsvindt. Een typische Laravel-applicatie logt niet alleen errors, maar ook queries, requests, en debug-informatie. In mijn ervaring kan een gemiddelde webapplicatie met normale traffic 1-5GB aan logs per maand genereren. Bij high-traffic applicaties ligt dat vaak hoger.
Het probleem ontstaat wanneer deze logs zich opstapelen zonder enige vorm van beheer. Een volledig partitie betekent dat de applicatie niet meer kan schrijven naar logbestanden, maar ook niet naar de database of andere bestanden. Het resultaat is een complete crash van je applicatie. Daarnaast maken grote logbestanden het analyseren van recente problemen onnodig traag.
Linux-servers hebben gelukkig een ingebouwde oplossing: logrotate. Deze service roteert, comprimeert en verwijdert automatisch oude logbestanden volgens regels die je zelf bepaalt. Voor Laravel-applicaties configureer ik logrotate altijd om dagelijks te draaien en oude logs automatisch op te ruimen na een bepaalde periode.
Logrotate configuratie voor Laravel
Het configureren van logrotate voor een Laravel-applicatie begint met het aanmaken van een specifiek configuratiebestand. Ik plaats deze altijd in /etc/logrotate.d/ met de naam van de applicatie. Voor een applicatie genaamd "webshop" ziet de configuratie er zo uit:
/var/www/webshop/storage/logs/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0644 www-data www-data
postrotate
/usr/bin/systemctl reload php8.1-fpm > /dev/null 2>&1 || true
endscript
}
Deze configuratie zorgt ervoor dat alle .log bestanden in de storage directory dagelijks worden geroteerd. De rotate 30 instelling betekent dat er maximaal 30 oude logbestanden bewaard blijven, wat neerkomt op ongeveer een maand aan geschiedenis. De compress optie zorgt ervoor dat oude logbestanden automatisch worden ingepakt met gzip om ruimte te besparen.
De create directive is cruciaal voor Laravel-applicaties. Deze zorgt ervoor dat er een nieuw logbestand wordt aangemaakt met de juiste permissies nadat het oude bestand is geroteerd. Zonder deze instelling kan Laravel niet meer schrijven naar het logbestand na de eerste rotatie.
Geavanceerde configuratie-opties
Voor productieservers met kritieke applicaties configureer ik vaak meer geavanceerde rotatie-instellingen. Size-based rotatie kan handig zijn voor applicaties die zeer intensief loggen. Hiermee kun je instellen dat rotatie plaatsvindt zodra een logbestand een bepaalde grootte bereikt:
/var/www/webshop/storage/logs/*.log {
size 100M
rotate 10
compress
delaycompress
missingok
notifempty
create 0644 www-data www-data
copytruncate
}
De copytruncate optie is nuttig voor applicaties die hun logbestand continu open houden. In plaats van het bestand te hernoemen (wat problemen kan veroorzaken), kopieert logrotate de inhoud naar een nieuw bestand en maakt vervolgens het originele bestand leeg. Laravel handelt file handles meestal goed af, maar voor zekerheid pas ik deze optie vaak toe.
Voor applicaties die in een load-balanced omgeving draaien, voeg ik vaak een sharedscripts directive toe. Deze zorgt ervoor dat post-rotatie scripts slechts één keer worden uitgevoerd, ook al worden meerdere logbestanden tegelijk geroteerd. Dit voorkomt onnodige overhead bij het herladen van services.
Notificatie via email configureer ik voor kritieke productiefases. Met de mail directive stuurt logrotate automatisch een bericht wanneer oude logbestanden worden verwijderd. Dit geeft mij inzicht in de rotatie-activiteit en helpt bij het debuggen van eventuele problemen:
/var/www/webshop/storage/logs/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0644 www-data www-data
mail [email protected]
mailfirst
}
Testen en monitoring van logrotatie
Na het configureren van logrotate test ik altijd of alles correct werkt voordat ik het in productie neem. De eenvoudigste manier is het forceren van een rotatie met het logrotate commando:
sudo logrotate -f /etc/logrotate.d/webshop
Deze commando forceert een rotatie, ongeacht wanneer de laatste rotatie heeft plaatsgevonden. Hiermee controleer ik of de nieuwe logbestanden correct worden aangemaakt en of de permissies kloppen. Ook check ik of eventuele post-rotatie scripts succesvol worden uitgevoerd.
Voor continue monitoring zet ik vaak een simpel script op dat de grootte van logbestanden controleert en waarschuwt bij afwijkingen. Dit script draai ik dagelijks via cron en het stuurt een notificatie als logbestanden onverwacht groot worden:
#!/bin/bash
LOG_DIR="/var/www/webshop/storage/logs"
MAX_SIZE=50 # MB
for logfile in $LOG_DIR/*.log; do
if [ -f "$logfile" ]; then
size=$(du -m "$logfile" | cut -f1)
if [ $size -gt $MAX_SIZE ]; then
echo "Warning: $logfile is ${size}MB" | mail -s "Large log file detected" [email protected]
fi
fi
done
Logrotate houdt zelf ook bij wanneer bestanden voor het laatst zijn geroteerd. Deze informatie staat in /var/lib/logrotate/status en geeft inzicht in eventuele problemen met de rotatie. Regelmatig controleer ik dit bestand om te zien of alle geconfigureerde logs correct worden behandeld.
Het instellen van log rotatie is een van die taken die je één keer goed doet en vervolgens vergeet. Totdat je server crasht omdat je het niet hebt gedaan. In mijn workflow configureer ik logrotate altijd als onderdeel van de deployment-setup, zodat ik nooit meer verrast word door vollopende partities door ongecontroleerde loggroei.