Aller au contenu
Administration Linux medium

Configurer logrotate pour gérer la rotation des logs sous Linux

30 min de lecture

logrotate archive, compresse et supprime automatiquement les anciens fichiers de log (/var/log/*.log). Tandis que journald gère le journal binaire de systemd, logrotate s'occupe des fichiers texte produits par les services qui écrivent directement dans /var/log/ (Nginx, Apache, MySQL, applications métier). Sans rotation, ces fichiers grossissent jusqu'à remplir le disque.

  • Comprendre l'architecture de logrotate (logrotate.conf + /etc/logrotate.d/)
  • Lire et écrire une politique de rotation pour un service
  • Utiliser les directives de compression, rétention et permissions
  • Exécuter des scripts post-rotation (redémarrage de service)
  • Tester une configuration sans risque et forcer une rotation manuelle
  • Connaître la différence entre logrotate et journald

logrotate est indispensable dès qu'un service écrit dans des fichiers texte :

  • Nginx ou Apache produisent des access.log et error.log qui peuvent atteindre plusieurs Go par jour sur un site actif
  • Une application métier écrit ses logs dans /var/log/monapp/ sans aucune rotation intégrée
  • Le disque /var se remplit et déclenche des alertes, il faut compresser et purger les anciens logs
  • La conformité exige de conserver les logs 90 jours mais pas indéfiniment

logrotate et journald, deux rôles complémentaires

Section intitulée « logrotate et journald, deux rôles complémentaires »
OutilGèreStockageConfiguration
journaldJournal binaire systemd/var/log/journal/journald.conf
logrotateFichiers texte classiques/var/log/*.loglogrotate.conf + /etc/logrotate.d/

Les deux coexistent sur un système moderne. journald capture les flux stdout/stderr des services systemd, les messages syslog et les logs du noyau. logrotate gère les fichiers texte que les services écrivent directement sur le disque.

logrotate est préinstallé sur la plupart des distributions. Sinon :

Fenêtre de terminal
sudo apt update && sudo apt install logrotate

Vérifiez ensuite la version installée. Elle a son importance : des directives comme maxsize ou hourly n'existent pas sur les versions anciennes. Une directive inconnue ne bloque pas le reste de la configuration, logrotate affiche unknown option '...' -- ignoring line et poursuit, ce qui est pire qu'une erreur franche puisque la politique s'applique alors sans l'option que vous croyiez avoir posée.

Fenêtre de terminal
# Vérifier la version
logrotate --version
logrotate 3.21.0

La configuration de logrotate repose sur deux niveaux :

FichierRôle
/etc/logrotate.confRègles globales par défaut (fréquence, rétention)
/etc/logrotate.d/Un fichier par service qui surcharge les règles globales

Ce fichier ne décrit aucun log en particulier : il pose les valeurs par défaut dont héritent tous les fichiers de /etc/logrotate.d/. Regardez d'abord les lignes commentées, elles vous disent ce qui n'est pas actif. Sur Ubuntu 24.04, dateext et compress sont livrés désactivés : croire le contraire fait chercher pendant longtemps pourquoi les archives sortent en .1 non compressé.

Fenêtre de terminal
cat /etc/logrotate.conf
# rotate log files weekly
weekly
# use the adm group by default, since this is the owning group
# of /var/log/.
su root adm
# keep 4 weeks worth of backlogs
rotate 4
# create new (empty) log files after rotating old ones
create
# use date as a suffix of the rotated file
#dateext
# uncomment this if you want your log files compressed
#compress
# packages drop log rotation information into this directory
include /etc/logrotate.d
DirectiveEffet
weeklyRotation hebdomadaire par défaut
rotate 4Conserver 4 fichiers archivés
createCréer un nouveau fichier après rotation
dateextSuffixer les archives avec la date (-20260628)
compressCompresser les archives (gzip)
include /etc/logrotate.dCharger les configurations par service

La ligne include /etc/logrotate.d doit rester en dernier : les options globales déclarées après elle ne s'appliquent pas aux fichiers déjà inclus. Le fichier livré par la distribution le rappelle d'ailleurs en commentaire.

Chaque service place son fichier dans /etc/logrotate.d/, et ce fichier appartient au paquet : une modification à la main sera signalée comme conflit à la prochaine mise à jour. Voici le fichier réellement livré par le paquet nginx sur Debian et Ubuntu.

Fenêtre de terminal
cat /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
run-parts /etc/logrotate.d/httpd-prerotate; \
fi \
endscript
postrotate
invoke-rc.d nginx rotate >/dev/null 2>&1
endscript
}

Deux détails valent le détour. Le bloc prerotate exécute les scripts déposés par d'autres paquets dans httpd-prerotate, ce qui permet par exemple à un outil de statistiques d'analyser le log avant qu'il ne soit archivé. Et invoke-rc.d nginx rotate déclenche l'action rotate du script d'init, laquelle envoie le signal USR1 à Nginx : ce n'est pas un reload complet, juste une réouverture des fichiers de log.

Ces directives ne déclenchent rien par elles-mêmes : elles décrivent une condition évaluée quand logrotate s'exécute, c'est-à-dire une fois par jour via le timer systemd. Écrire daily ne signifie donc pas « à minuit pile », mais « au plus une fois par jour, lors du passage ». La ligne size est à part : la page de manuel précise qu'elle est mutuellement exclusive avec les critères de temps, et que c'est la dernière directive écrite qui gagne.

DirectiveRotation
dailyChaque jour
weeklyChaque semaine
monthlyChaque mois
size 100MQuand le fichier dépasse 100 Mo

Les deux directives ci-dessous répondent à des questions différentes et se combinent très bien. rotate limite le nombre d'archives, ce qui borne l'espace disque ; maxage limite leur âge, ce qui répond à une exigence de conformité (« ne pas conserver les journaux au-delà de N jours »). Sans maxage, un service qui n'écrit plus garde ses archives indéfiniment, puisque la rotation ne se déclenche plus.

DirectiveEffet
rotate NGarder N archives
maxage NSupprimer les archives de plus de N jours

La compression est le levier le plus rentable sur des logs texte : un access.log se réduit couramment d'un facteur 10 ou plus. La directive à comprendre est delaycompress, qui repousse la compression d'un cycle : la page de manuel précise qu'elle sert quand un programme ne peut pas être averti de fermer son fichier et continue donc d'écrire quelques instants dans l'ancien. Elle n'a d'effet qu'associée à compress.

DirectiveEffet
compressCompresser les archives (gzip)
delaycompressReporter la compression d'un cycle (utile si un service écrit encore)
compresscmd bzip2Utiliser bzip2 au lieu de gzip
nocompressDésactiver la compression

Attention à compresscmd : changer la commande ne change pas l'extension. La page de manuel renvoie explicitement à compressext, à déclarer en plus (compressext .bz2), sinon vous obtenez des archives compressées en bzip2 mais nommées .gz, que les outils suivants ouvriront de travers.

create 0640 root adm

Crée le nouveau fichier avec les permissions 0640, propriétaire root, groupe adm. Le service peut continuer à écrire immédiatement.

Ces trois directives évitent les deux échecs les plus fréquents en production : un fichier absent qui fait sortir logrotate en erreur, et un répertoire dont le propriétaire n'est pas root. su user group répond au second cas et son absence est la cause exacte du message skipping ... because parent directory has insecure permissions. Traitez-la comme obligatoire dès que les logs vivent hors de /var/log.

DirectiveEffet
missingokNe pas signaler d'erreur si le fichier n'existe pas
notifemptyNe pas tourner un fichier vide
su root admExécuter la rotation avec cet utilisateur/groupe (requis si le dossier a des permissions spéciales)

Les blocs prerotate et postrotate permettent d'exécuter des commandes avant et après la rotation :

/var/log/myapp/*.log {
daily
rotate 7
compress
missingok
notifempty
create 0640 myapp myapp
sharedscripts
postrotate
systemctl reload myapp > /dev/null 2>&1 || true
endscript
}
BlocQuand
prerotate ... endscriptAvant la rotation
postrotate ... endscriptAprès la rotation
firstaction ... endscriptAvant la première rotation (une seule fois)
lastaction ... endscriptAprès la dernière rotation (une seule fois)

sharedscripts garantit que le script ne s'exécute qu'une seule fois, même si plusieurs fichiers correspondent au pattern.

Fenêtre de terminal
sudo logrotate -d /etc/logrotate.d/nginx

Le flag -d simule la rotation et affiche ce qui serait fait, sans modifier aucun fichier ; logrotate --help le décrit comme « Don't do anything, just test and print debug messages ». Utilisez-le systématiquement avant de mettre en production une nouvelle configuration.

Dans la sortie, cherchez trois choses : la ligne error: <fichier>:<n> unknown option qui signale une directive mal orthographiée, la ligne rotating pattern: qui confirme que votre glob correspond bien à des fichiers, et la conclusion par fichier (log needs rotating ou log does not need rotating). Une sortie sans aucune ligne considering log signifie que le motif ne correspond à rien.

-f ignore les conditions de fréquence et de taille, et fait tourner immédiatement tout ce qui correspond au fichier de configuration passé en argument. C'est la commande de validation d'une nouvelle politique, pas une commande d'exploitation : chaque exécution consomme un cran du compteur rotate, donc l'enchaîner cinq fois efface vos cinq archives les plus anciennes.

Fenêtre de terminal
# Forcer la rotation de tous les fichiers
sudo logrotate -f /etc/logrotate.conf
# Forcer la rotation d'un seul service
sudo logrotate -f /etc/logrotate.d/nginx
Fenêtre de terminal
sudo logrotate -v /etc/logrotate.conf

Le flag -v affiche les détails de chaque rotation effectuée.

Sur les distributions modernes, logrotate est déclenché par un timer systemd (et non plus par cron) :

Fenêtre de terminal
systemctl cat logrotate.timer
[Unit]
Description=Daily rotation of log files
Documentation=man:logrotate(8) man:logrotate.conf(5)
[Timer]
OnCalendar=daily
AccuracySec=1h
Persistent=true
[Install]
WantedBy=timers.target

Deux directives expliquent le comportement observé sur un serveur. AccuracySec=1h autorise systemd à décaler le déclenchement d'une heure pour éviter que toutes les machines ne rotationnent à la même seconde : l'heure exacte varie donc d'un serveur à l'autre, c'est normal. Persistent=true rattrape l'exécution manquée si la machine était éteinte au moment prévu, ce qui évite qu'un serveur allumé par intermittence n'accumule des logs jamais tournés.

Fenêtre de terminal
# Vérifier que le timer est actif
systemctl status logrotate.timer
# Voir la prochaine échéance et la dernière exécution
systemctl list-timers logrotate.timer

Voici un exemple de politique pour une application métier :

  1. Créer le fichier de configuration

    Fenêtre de terminal
    sudo nano /etc/logrotate.d/monapp
  2. Écrire la politique

    /var/log/monapp/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    create 0640 monapp monapp
    su monapp monapp
    sharedscripts
    postrotate
    systemctl reload monapp > /dev/null 2>&1 || true
    endscript
    }
  3. Tester la configuration

    Fenêtre de terminal
    sudo logrotate -d /etc/logrotate.d/monapp

    Vérification : la sortie doit afficher les fichiers qui seraient tournés, sans erreur de syntaxe.

  4. Forcer une première rotation pour valider

    Fenêtre de terminal
    sudo logrotate -f /etc/logrotate.d/monapp
    ls -la /var/log/monapp/

    Vérification : un fichier .1.gz ou daté doit apparaître.

Les six symptômes ci-dessous se distinguent par un critère simple : la rotation n'a pas eu lieu du tout (deux premières lignes) ou elle a eu lieu mais son résultat surprend (quatre suivantes). Commencez toujours par vérifier l'état du timer, car une rotation qui ne s'exécute jamais produit exactement les mêmes symptômes qu'une configuration invalide.

SymptômeCause probableSolution
Logs jamais tournésTimer désactivésystemctl enable --now logrotate.timer
error: skipping ... not readablePermissions insuffisantesAjouter su root adm ou su root root
Logs tournés mais service écrit dans l'ancienPas de postrotateAjouter un bloc postrotate avec systemctl reload
error: ... duplicate log entryMême fichier dans 2 configsVérifier /etc/logrotate.d/ pour les doublons
Archives non compresséescompress absentAjouter compress dans la configuration
Fichier .1 mais pas .1.gzdelaycompress actifNormal, la compression s'applique au cycle suivant
Fenêtre de terminal
# Diagnostic rapide
systemctl status logrotate.timer # Timer actif ?
sudo logrotate -d /etc/logrotate.conf # Erreurs de config ?
ls -la /var/log/nginx/ # Rotation effective ?
journalctl -u logrotate.service # Dernière exécution ?

Les deux premières lignes vous éviteront les incidents, les suivantes vous éviteront de refaire le travail. Si vous n'en retenez qu'une, gardez la dernière : logrotate borne la rétention, pas le débit. Un service qui écrit 20 Go par jour remplira /var bien avant le passage quotidien du timer, et seul un plafonnement côté application ou un size agressif y changera quelque chose.

  • Toujours tester avec -d avant de modifier une politique en production
  • Utiliser delaycompress pour les services qui peuvent encore écrire dans l'ancien fichier pendant quelques secondes
  • Ajouter sharedscripts + postrotate pour recharger le service après rotation
  • Définir des permissions restrictives avec create, les logs contiennent souvent des informations sensibles (IP, erreurs, chemins)
  • Configurer maxage en complément de rotate, supprimer les archives trop anciennes même si le compteur n'est pas atteint
  • Séparer les configurations dans /etc/logrotate.d/, un fichier par service, jamais tout dans logrotate.conf
  • Surveiller l'espace disque, logrotate ne résout pas le problème si les logs croissent plus vite que la rotation

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  • logrotate gère les fichiers de log texte, journald gère le journal binaire de systemd. Les deux sont complémentaires
  • La configuration globale est dans /etc/logrotate.conf, les configurations par service dans /etc/logrotate.d/
  • Les directives clés : daily/weekly, rotate N, compress, delaycompress, create, postrotate
  • logrotate -d simule la rotation sans rien modifier, à utiliser avant chaque changement
  • logrotate -f force la rotation, utile pour valider une nouvelle configuration
  • Le bloc postrotate recharge le service pour qu'il écrive dans le nouveau fichier
  • Sur les systèmes modernes, logrotate est déclenché par un timer systemd (logrotate.timer), plus par cron

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn