Rien ne dit « vendredi soir » comme un disque qui se remplit parce qu’un fichier de logs a décidé qu’il est en fait une base de données maintenant. Vous vérifiez /etc/logrotate.d/, vous voyez une section pour le service, et pourtant le fichier continue de grossir. Pas de rotations, pas de compression, aucune pitié.
Sur Ubuntu 24.04, la raison la plus courante pour laquelle logrotate « ne tourne pas » n’est pas systemd, pas un bug du noyau, pas les rayons cosmiques. C’est une seule erreur de configuration : vous avez oublié de spécifier un déclencheur de rotation (daily/weekly/monthly/hourly ou size) et vous avez supposé qu’un paramètre global par défaut vous sauverait. Il ne le fera pas. Logrotate lira votre section, haussera les épaules poliment et ne fera rien — pour toujours.
La seule erreur : pas de déclencheur, pas de rotation
Logrotate ne fait pas de rotation « parce qu’un fichier existe » ou « parce que j’ai écrit un fichier de configuration ». Il effectue la rotation quand une section lui dit quand tourner. Ce « quand » est un déclencheur de rotation :
daily,weekly,monthly,yearly, ou (sur beaucoup de distributions)hourlysize(et compagnons commeminsize,maxsize)
Si votre fichier par service dans /etc/logrotate.d/ ne spécifie pas de déclencheur, vous dépendez de l’héritage. Et c’est là que les gens se font piéger : les valeurs globales d’Ubuntu peuvent ne pas fournir un calendrier d’une manière qui s’applique à votre section (ou le fichier n’est pas lu, ou vous le remplacez involontairement). Résultat net : logrotate s’exécute, ne voit aucune raison de tourner, n’actualise rien, et sort avec 0 comme si c’était un service rendu.
À quoi ressemble la configuration cassée
Ceci est la section classique « ça a l’air correct en revue de code, ça échoue en production ». Remarquez ce qui manque :
cr0x@server:~$ sudo sed -n '1,120p' /etc/logrotate.d/myapp
/var/log/myapp/myapp.log {
rotate 7
compress
missingok
notifempty
create 0640 myapp adm
postrotate
systemctl kill -s HUP myapp.service
endscript
}
Cette config contient rotate 7, qui dit seulement « garder sept anciens logs » si une rotation a lieu. Elle ne dit pas quand la rotation doit avoir lieu. Si vous ne spécifiez pas daily (ou similaire) ou size, logrotate ne peut pas prendre de décision de rotation.
À quoi ressemble la configuration corrigée
Ajoutez un déclencheur explicite. Choisissez-en un. Ne laissez pas le lecteur deviner.
cr0x@server:~$ sudo sed -n '1,120p' /etc/logrotate.d/myapp
/var/log/myapp/myapp.log {
daily
rotate 7
compress
missingok
notifempty
create 0640 myapp adm
postrotate
systemctl kill -s HUP myapp.service
endscript
}
Si vous préférez une rotation basée sur la taille (souvent mieux pour les applications bavardes) :
cr0x@server:~$ sudo sed -n '1,120p' /etc/logrotate.d/myapp
/var/log/myapp/myapp.log {
size 200M
rotate 10
compress
delaycompress
missingok
notifempty
create 0640 myapp adm
}
Rendez le déclencheur explicite même si vous pensez qu’il est « évident ». En production, les suppositions évidentes passent à la caisse.
Mode opératoire de diagnostic rapide (premier/deuxième/troisième)
Quand logrotate « ne tourne pas », vous voulez localiser rapidement le goulot : s’agit-il de la planification, de l’analyse, de l’éligibilité, des permissions ou d’un échec postrotate ?
Premier : confirmer que logrotate est bien invoqué
- Vérifiez le statut du timer/service systemd et l’heure du dernier lancement.
- Consultez le journal pour trouver les exécutions et les erreurs de logrotate.
Second : exécuter logrotate en mode debug pour la configuration spécifique
- Utilisez
-d(debug) et-v(verbose) pour voir l’arbre de décision. - Cherchez des lignes comme « log does not need rotating » et pourquoi.
Troisième : vérifier le fichier d’état et la logique du déclencheur
- Inspectez
/var/lib/logrotate/status(ou variante distro) pour voir ce que logrotate pense avoir fait la dernière fois. - Validez que votre section contient un déclencheur (
daily/weekly/size, etc.). - Confirmez que les chemins de fichiers correspondent à la réalité (y compris les jokers) et que les permissions permettent la rotation.
Si vous ne faites qu’une seule chose : exécutez logrotate avec -d -v et lisez-le comme un enregistreur de vol. Il est généralement embarrassant d’honnêteté.
Comment logrotate décide réellement de tourner (réalité Ubuntu 24.04)
Le travail de logrotate est simple : pour chaque fichier de logs, décider si une rotation est nécessaire ; si oui, renommer/tronquer/copier, éventuellement compresser, et exécuter des scripts. Le diable se cache dans le fichier d’état et les déclencheurs.
Planification sur Ubuntu 24.04 : timers systemd, pas cron
Sur les Ubuntu modernes, logrotate est généralement lancé via un timer systemd (et non via un job cron.daily classique). Cela change l’endroit où vous regardez quand vous déboguez un « ça ne s’exécute jamais ». Cela change aussi la façon dont les exécutions « manquées » se comportent : les timers peuvent rattraper selon la configuration.
Le fichier d’état est la mémoire sur laquelle logrotate s’appuie
Logrotate n’est pas un démon en continu. Il s’exécute, prend des décisions et s’arrête. Pour éviter de tout faire tourner à chaque fois, il stocke les horodatages de dernière rotation dans un fichier d’état (souvent /var/lib/logrotate/status). Si ce fichier indique qu’un log a été tourné « aujourd’hui », une section daily ne tournera pas juste parce que vous êtes inquiet.
Les déclencheurs ne sont pas optionnels
Logrotate n’infère pas un calendrier de rotation à partir de rotate N, compress ou create. Ce sont des actions. Les déclencheurs sont séparés. L’absence de déclencheur est le mode d’échec silencieux parce que ce n’est pas une « erreur de syntaxe ». C’est juste « aucune condition satisfaite ».
Idée paraphrasée de Richard Cook : « Le succès cache les arêtes vives du système ; l’échec révèle comment le travail est réellement fait. » Voilà le débogage de logrotate en une phrase.
Blague #1 : Logrotate est comme une rotation de vigile : si vous ne définissez jamais l’horaire, quelqu’un en souffrira toujours — juste pas le logiciel.
Tâches pratiques : commandes, sorties, décisions (12+)
Voici des tâches concrètes que j’utilise en réponse à incident. Chacune inclut : la commande, ce que signifie la sortie, et la décision à en tirer.
Tâche 1 : Confirmer que le timer existe et est activé
cr0x@server:~$ systemctl status logrotate.timer
● logrotate.timer - Daily rotation of log files
Loaded: loaded (/usr/lib/systemd/system/logrotate.timer; enabled; preset: enabled)
Active: active (waiting) since Sat 2025-12-28 07:10:22 UTC; 2h 14min ago
Trigger: Sun 2025-12-29 00:00:00 UTC; 14h left
Triggers: ● logrotate.service
Signification : S’il est activé et « Active (waiting) », la planification est probablement correcte.
Décision : S’il est désactivé/manquant, corrigez la planification d’abord. S’il est activé, passez aux vérifications d’exécution/service et de journal.
Tâche 2 : Confirmer la dernière exécution du service et le code de sortie
cr0x@server:~$ systemctl status logrotate.service
● logrotate.service - Rotate log files
Loaded: loaded (/usr/lib/systemd/system/logrotate.service; static)
Active: inactive (dead) since Sat 2025-12-28 00:00:04 UTC; 9h ago
Process: 1042 ExecStart=/usr/sbin/logrotate /etc/logrotate.conf (code=exited, status=0/SUCCESS)
Signification : Le statut 0 signifie que logrotate n’a pas planté ; il se peut qu’il n’ait tout simplement rien tourné.
Décision : Si le statut est non nul, inspectez les logs ; si succès, passez en mode debug pour comprendre pourquoi il a ignoré la rotation.
Tâche 3 : Inspecter le journal pour les messages de logrotate
cr0x@server:~$ journalctl -u logrotate.service -n 50 --no-pager
Dec 28 00:00:01 server systemd[1]: Starting logrotate.service - Rotate log files...
Dec 28 00:00:04 server systemd[1]: logrotate.service: Deactivated successfully.
Dec 28 00:00:04 server systemd[1]: Finished logrotate.service - Rotate log files.
Signification : Pas d’erreurs ici, mais pas non plus beaucoup de détails. C’est normal ; logrotate n’écrit sur stdout que lorsqu’il est en verbose/debug.
Décision : Lancez un debug manuel ensuite.
Tâche 4 : Simulation (dry-run) de logrotate en verbose + debug
cr0x@server:~$ sudo logrotate -d -v /etc/logrotate.conf
reading config file /etc/logrotate.conf
including /etc/logrotate.d
reading config file /etc/logrotate.d/myapp
Handling 1 logs
rotating pattern: /var/log/myapp/myapp.log after 1 days (7 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/myapp/myapp.log
log does not need rotating (log has been already rotated)
Signification : Cela vous dit ce que logrotate pense être le déclencheur (« after 1 days ») et pourquoi il saute (« already rotated »).
Décision : Si la ligne de déclenchement manque ou semble étrange, inspectez la section. Si « already rotated », vérifiez le fichier d’état.
Tâche 5 : Debug pour un fichier unique (scope réduit)
cr0x@server:~$ sudo logrotate -d -v /etc/logrotate.d/myapp
reading config file /etc/logrotate.d/myapp
error: /etc/logrotate.d/myapp:2 unknown option 'rotato'
Signification : Le debug par fichier attrape rapidement les fautes de frappe et erreurs de parsing.
Décision : Corrigez les erreurs de syntaxe avant de poursuivre le comportement runtime.
Tâche 6 : Valider que la section inclut un déclencheur (le contrôle « une erreur »)
cr0x@server:~$ sudo egrep -n 'daily|weekly|monthly|yearly|hourly|size|minsize|maxsize' /etc/logrotate.d/myapp || echo "NO TRIGGER FOUND"
NO TRIGGER FOUND
Signification : Aucun mot-clé de déclencheur trouvé. C’est le classique « rotate mais ne tourne jamais ».
Décision : Ajoutez daily ou size explicitement et relancez le debug.
Tâche 7 : Inspecter l’entrée du fichier d’état pour votre log
cr0x@server:~$ sudo grep -F '/var/log/myapp/myapp.log' /var/lib/logrotate/status
"/var/log/myapp/myapp.log" 2025-12-28-0:0:0
Signification : Logrotate croit l’avoir tourné à minuit aujourd’hui. Si vous vous attendez à ce qu’il tourne maintenant, votre attente est le bug.
Décision : Si l’horodatage semble faux, investiguez les changements d’heure, la corruption d’état ou les chemins dupliqués. Ne supprimez pas le fichier d’état à la légère en production.
Tâche 8 : Confirmer la taille réelle du fichier et son heure de modification
cr0x@server:~$ ls -lh --time-style=long-iso /var/log/myapp/myapp.log
-rw-r----- 1 myapp adm 12G 2025-12-28 09:19 /var/log/myapp/myapp.log
Signification : Le fichier est énorme et est encore écrit. Si vous utilisez uniquement une rotation basée sur le temps, vous pouvez avoir raison mais vous êtes opérationnellement condamné.
Décision : Envisagez size ou maxsize en plus des déclencheurs temporels.
Tâche 9 : Vérifier le propriétaire du log et les permissions du répertoire
cr0x@server:~$ namei -l /var/log/myapp/myapp.log
f: /var/log/myapp/myapp.log
drwxr-xr-x root root /
drwxr-xr-x root root var
drwxrwxr-x root syslog log
drwxr-x--- myapp adm myapp
-rw-r----- myapp adm myapp.log
Signification : Le répertoire de logs n’est pas lisible par « others » ; logrotate s’exécute en root (habituellement), donc ça va. Mais si vous avez mal configuré su, les permissions peuvent bloquer la rotation.
Décision : Si les permissions empêchent le renommage/la création, corrigez la propriété/le mode ou utilisez la directive su user group appropriée.
Tâche 10 : Détecter les échecs du script postrotate (la raison cachée pour laquelle rien ne change)
cr0x@server:~$ sudo logrotate -v /etc/logrotate.d/myapp
reading config file /etc/logrotate.d/myapp
rotating pattern: /var/log/myapp/myapp.log after 1 days (7 rotations)
considering log /var/log/myapp/myapp.log
log needs rotating
rotating log /var/log/myapp/myapp.log, log->rotateCount is 7
renaming /var/log/myapp/myapp.log to /var/log/myapp/myapp.log.1
creating new /var/log/myapp/myapp.log mode = 0640 uid = 123 gid = 4
running postrotate script
error: error running shared postrotate script for '/var/log/myapp/myapp.log '
Signification : La rotation a peut-être eu lieu, mais votre étape de signal/reload a échoué. Certaines applis continuent d’écrire sur l’ancien inode ; d’autres ont besoin d’un HUP pour rouvrir les logs.
Décision : Corrigez le postrotate ; sinon vous « tournerez » et continuerez de remplir le disque car le processus écrit dans un descripteur de fichier non référencé.
Tâche 11 : Rechercher la situation redoutée « supprimé mais encore ouvert »
cr0x@server:~$ sudo lsof +L1 | head
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME
myapp 2210 myapp 7w REG 252,0 12884901888 0 393502 /var/log/myapp/myapp.log (deleted)
Signification : Le fichier est supprimé/roté, mais le processus écrit encore sur l’ancien descripteur. L’usage disque ne diminuera pas.
Décision : Corrigez votre stratégie de réouverture : HUP, reload, ou utilisez copytruncate en dernier recours (avec prudence).
Tâche 12 : Vérifier que le timer s’est réellement déclenché quand vous le pensez
cr0x@server:~$ systemctl list-timers --all | grep -F logrotate
Sun 2025-12-29 00:00:00 UTC 14h left Sat 2025-12-28 00:00:01 UTC 9h ago logrotate.timer logrotate.service
Signification : La dernière exécution était à minuit ; la prochaine aussi. Si votre log a explosé à 09:00, une rotation quotidienne basée sur le temps ne vous sauvera pas.
Décision : Ajoutez des seuils de taille ou augmentez la fréquence d’exécution (avec prudence).
Tâche 13 : Forcer une rotation ponctuelle (en sécurité) pour valider le mécanisme
cr0x@server:~$ sudo logrotate -f -v /etc/logrotate.d/myapp
reading config file /etc/logrotate.d/myapp
rotating pattern: /var/log/myapp/myapp.log forced from command line (7 rotations)
considering log /var/log/myapp/myapp.log
log needs rotating
renaming /var/log/myapp/myapp.log to /var/log/myapp/myapp.log.1
creating new /var/log/myapp/myapp.log mode = 0640 uid = 123 gid = 4
Signification : Les mécanismes fonctionnent : renommage/création/permissions sont corrects.
Décision : Si la rotation forcée fonctionne mais la planifiée non, c’est un problème de déclencheur/état/planification, pas de permissions.
Tâche 14 : Vérifier l’ordre d’inclusion et si votre fichier est lu
cr0x@server:~$ sudo grep -nE '^(include|#include)|/etc/logrotate\.d' /etc/logrotate.conf
12:include /etc/logrotate.d
Signification : Si l’include manque, rien dans /etc/logrotate.d n’a d’effet.
Décision : Restaurez la ligne d’include si quelqu’un a « simplifié » la configuration globale.
Tâche 15 : Tester le parsing de la config sans exécuter de rotations (sanity check)
cr0x@server:~$ sudo logrotate -d /etc/logrotate.conf | tail -n 20
considering log /var/log/myapp/myapp.log
Now: 2025-12-28 09:24
Last rotated at 2025-12-28 00:00
log does not need rotating
Signification : Le mode debug affiche « Now » et « Last rotated ». Si ceux-ci sont incohérents, suivez la piste temps/état.
Décision : Si « Last rotated » est dans le futur, vous avez probablement un décalage horaire, un snapshot VM restauré, ou un fichier d’état copié.
Erreurs courantes : symptômes → cause → correction
1) « J’ai mis rotate 30 mais ça ne tourne jamais »
Symptôme : Le fichier grossit sans fin ; logrotate rapporte le succès ; aucun fichier tourné n’existe.
Cause : Pas de directive de déclenchement (daily/weekly/size).
Correction : Ajoutez un déclencheur explicitement. Préférez size pour les logs à fort volume ; conservez le temps pour l’alignement de rétention.
2) « Logrotate s’exécute, mais affiche ‘log does not need rotating’ alors que le fichier est énorme »
Symptôme : Un fichier de 20G ; le debug dit qu’il ne faut pas tourner.
Cause : Vous avez configuré uniquement daily et il a déjà tourné aujourd’hui ; ou le fichier d’état indique qu’il a déjà été tourné.
Correction : Ajoutez maxsize ou size. Ou augmentez la fréquence de rotation. Ne combattez pas le fichier d’état ; concevez autour.
3) « Des fichiers tournés existent, mais l’usage disque ne baisse jamais »
Symptôme : Vous voyez myapp.log.1, pourtant df reste mauvais.
Cause : Le processus garde l’ancien inode ouvert ; les logs vont vers un descripteur marqué (deleted).
Correction : Assurez-vous que le processus rouvre les logs (HUP/reload) ou utilisez copytruncate si l’appli ne peut pas rouvrir (en acceptant la perte/le risque de course).
4) « logrotate -f marche manuellement, la rotation planifiée non »
Symptôme : La rotation forcée fonctionne ; le timer quotidien ne fait rien.
Cause : Planification qui ne se déclenche pas, timer désactivé, include manquant, ou fichier d’état disant que c’était déjà fait.
Correction : Vérifiez systemctl list-timers, assurez-vous que /etc/logrotate.conf inclut /etc/logrotate.d, inspectez /var/lib/logrotate/status.
5) « Erreurs de rotation : permission denied »
Symptôme : Le mode debug/verbose montre des échecs de rename/create.
Cause : Propriétaire/mode incorrect ; répertoire de logs non inscriptible ; mauvaise utilisation de su ; ou logs sur un montage aux restrictions spéciales.
Correction : Corrigez les permissions du système de fichiers. Si vous utilisez su, assurez-vous que user/group correspondent au propriétaire du fichier et que le répertoire permet la rotation.
6) « Ça tourne, mais l’appli arrête de logger »
Symptôme : Après rotation, le fichier de logs reste vide et l’application tourne toujours.
Cause : L’appli continue d’écrire sur l’ancien fd ; le nouveau fichier existe mais n’est pas utilisé ; postrotate ne signale pas correctement.
Correction : Utilisez l’action postrotate correcte : HUP, reload, ou commande spécifique au service. Validez avec lsof.
7) « J’ai utilisé des jokers et rien ne se passe »
Symptôme : La section référence /var/log/myapp/*.log ; aucune rotation.
Cause : Le motif ne matche rien ; les permissions empêchent l’expansion du glob ; ou les logs sont dans un chemin différent de celui attendu.
Correction : Confirmez les correspondances avec ls. Utilisez des chemins explicites pour les logs critiques.
8) « Après une restauration d’image, logrotate ne tourne plus pendant des jours »
Symptôme : Le debug dit que la dernière rotation est dans le futur.
Cause : Fichier d’état copié d’une autre machine/temps ; snapshot VM restauré ; changements d’horloge.
Correction : Corrigez d’abord l’heure. Puis ajustez l’entrée d’état avec précaution (éditez seulement la ligne affectée), ou forcez une rotation unique avec -f et vérifiez la mise à jour de l’état.
Trois mini-récits d’entreprise depuis le terrain
Incident #1 : la mauvaise hypothèse (« rotate 14 signifie tous les 14 jours, non ? »)
Une entreprise SaaS de taille moyenne avait un petit service interne qui émettait des logs JSON. Il a tourné des mois sans problème parce que personne ne regardait l’utilisation de l’espace disque racine du nœud sauf en cas d’alerte. Le service a reçu une fonctionnalité qui a doublé le volume des logs — rien de dramatique, juste plus de champs contextuels.
Deux semaines plus tard, un ingénieur on-call a vu l’utilisation disque d’un nœud de production à 97 %. Ils ont trouvé /var/log/internal/worker.log à plusieurs dizaines de gigaoctets. Il y avait une section logrotate avec rotate 14, compress, create, et notifempty. Ça semblait « configuré ». Tout le monde a supposé que « rotate 14 » signifiait « tourner tous les 14 jours ». Ce n’est pas le cas.
Le timer tournait. Logrotate sortait 0. Aucune rotation. La configuration n’avait ni daily, ni weekly, ni size. C’était une politique sans déclencheur — comme écrire « garder 14 sauvegardes » sans jamais exécuter la sauvegarde.
Ils ont ajouté daily et maxsize 500M, forcé une rotation pour respirer, puis corrigé leurs seuils de monitoring pour alerter sur la croissance des logs avant la panique du système de fichiers.
Le postmortem fut poli mais tranchant : « Nous avons supposé que logrotate avait un planning par défaut. Nous n’avons pas testé le comportement de rotation en staging avec un volume réaliste de logs. » C’est toute l’histoire, et elle se répète partout.
Incident #2 : l’optimisation qui s’est retournée contre eux (copytruncate partout)
Une entreprise régulée avait une appli Java legacy qui ne rouvrait pas proprement les logs sur HUP. Quelqu’un « a résolu » ça il y a des années avec copytruncate. Ça a assez bien marché pour devenir le pattern par défaut pour les nouveaux services — copytruncate pour tout, toujours.
Puis la société a migré les charges vers des NVMe plus rapides et augmenté le débit. Leur service le plus chargé écrivait plusieurs gigaoctets par heure. La rotation a commencé à durer assez longtemps pour que la fenêtre de troncature ait de l’impact, et ils ont commencé à perdre des lignes de log. Pas « peut-être » ; prouvé. Leur piste d’audit avait des lacunes précisément aux frontières de rotation.
Pire : la compression s’exécutait immédiatement, écrasant le CPU pendant les heures de pointe. L’« optimisation » a créé une falaise de performance : pendant la rotation, le CPU montait en flèche, augmentant la latence des requêtes, entraînant des retries, produisant davantage de logs, ce qui augmentait encore la rotation. Une jolie boucle de rétroaction auto-infligée.
Ils sont revenus en arrière : passage à la rotation par renommage (pas de copytruncate) et correction de l’appli pour qu’elle rouvre les logs correctement sur signal. Ils ont aussi ajouté delaycompress pour éloigner la compression du moment critique. Ce n’était pas du travail glamour. C’était du travail correct.
Blague #2 : « Nous avons utilisé copytruncate pour éviter de toucher à l’appli » est l’équivalent logging de réparer une fuite en achetant une serpillière plus grande.
Incident #3 : la pratique ennuyeuse qui a sauvé la mise (déclencheurs explicites + tests forcés)
Une petite équipe plateforme gérait des dizaines de services internes, surtout Go et Python, sur Ubuntu. Ils avaient une habitude qu’on trouvait péniblement pointilleuse : chaque section logrotate avait un déclencheur explicite et un commentaire expliquant pourquoi. Pas d’héritage. Pas de dépendance à /etc/logrotate.conf. Chaque section : daily ou size (souvent les deux via maxsize), toujours intentionnel.
Ils avaient aussi dans la checklist de déploiement : après le déploiement d’un nouveau service, exécuter logrotate -d -v sur sa section et coller l’extrait de sortie dans le dossier de changement. Ça ressemblait à de la bureaucratie jusqu’à ce qu’un changement d’image de base modifie quelques valeurs globales et que certains services atterrissent sur de nouveaux nœuds.
Les services avec déclencheurs explicites ont tourné normalement. Ceux qui dépendaient de l’héritage (des configs d’autres équipes) sont devenus étranges : certains tournaient hebdomadairement alors qu’on attendait quotidiennement ; d’autres ne tournaient que quand la taille atteignait un seuil par défaut que personne ne se rappelait avoir défini. L’équipe plateforme n’a pas eu d’incident. Ils ont eu un mardi légèrement pénible.
La différence n’était pas magique. C’était la pratique ennuyeuse de rendre « quand tourner » explicite, puis de tester le comportement une fois, comme vous testeriez une règle de firewall ou une sauvegarde. C’est ça le professionnalisme en ops : prévenir les surprises, pas y réagir héroïquement.
Faits intéressants et contexte (pourquoi ça revient)
- Logrotate date d’avant systemd. Il a grandi dans un monde piloté par cron, et le passage aux timers systemd a changé l’endroit où on cherche quand il échoue.
- Le fichier d’état est le cœur de la « mémoire » de logrotate. Sans lui, la rotation basée sur le temps tournerait soit tout le temps, soit il faudrait des heuristiques sur les métadonnées du système de fichiers.
rotate Nest la rétention, pas la planification. C’est l’erreur conceptuelle la plus courante — parce que le mot « rotate » porte trop de sens.- Beaucoup de distros livrent une config globale qui semble définir des valeurs par défaut. Les gens supposent que ces défauts incluent un déclencheur. Parfois oui ; parfois non ; parfois votre section les remplace ; parfois votre fichier n’est pas inclus du tout.
- Journald a réduit la dépendance aux logs fichiers pour certains services. Mais beaucoup d’applis écrivent encore dans des fichiers (compatibilité, conformité, ou parce que l’image conteneur vient de 2016 et que personne ne veut y toucher).
- Copytruncate s’est popularisé parce que « ça marche » avec des applis réticentes. Il introduit aussi des races et des pertes potentielles sous charge car on peut écrire pendant la copie.
- La compression était autrefois assez coûteuse pour être planifiée. Sur les CPU modernes c’est moins cher, mais ça compte encore quand vous compressez des logs de plusieurs gigaoctets en heure de pointe.
- Renommer des logs est atomique ; la troncature ne l’est pas. L’approche par renommage s’aligne avec le comportement des descripteurs Unix et est généralement plus sûre quand les applis rouvrent correctement les logs.
- Les configurations logrotate sont trompeusement permissives. Beaucoup de mauvaises configurations ne sont pas des erreurs de syntaxe ; ce sont des erreurs de logique qui résultent en « ne rien faire avec succès ».
Listes de contrôle / plan étape par étape
Étape par étape : faire marcher la rotation pour un log problématique
-
Confirmer que la planification existe.
cr0x@server:~$ systemctl status logrotate.timer ● logrotate.timer - Daily rotation of log files Loaded: loaded (/usr/lib/systemd/system/logrotate.timer; enabled; preset: enabled) Active: active (waiting) since Sat 2025-12-28 07:10:22 UTC; 2h 14min ago Trigger: Sun 2025-12-29 00:00:00 UTC; 14h left Triggers: ● logrotate.serviceDécision : Si désactivé, activez-le. Si activé, continuez.
-
Vérifier que votre config est incluse.
cr0x@server:~$ sudo grep -n 'include /etc/logrotate.d' /etc/logrotate.conf 12:include /etc/logrotate.dDécision : Si manquant, restaurez l’include et retestez.
-
Exécuter le debug pour cette section.
cr0x@server:~$ sudo logrotate -d -v /etc/logrotate.d/myapp | sed -n '1,120p' reading config file /etc/logrotate.d/myapp Handling 1 logs considering log /var/log/myapp/myapp.log log does not need rotatingDécision : S’il ne mentionne pas de calendrier/taille, vous n’avez probablement pas de déclencheur.
-
Ajouter un déclencheur explicite.
Choisissez : temporel (
daily) ou basé sur le volume (size/maxsize). Pour les logs à fort volume, la rotation basée sur la taille est souvent le choix mature. -
Forcer une rotation une fois pour valider le mécanisme.
cr0x@server:~$ sudo logrotate -f -v /etc/logrotate.d/myapp | tail -n 30 considering log /var/log/myapp/myapp.log log needs rotating renaming /var/log/myapp/myapp.log to /var/log/myapp/myapp.log.1 creating new /var/log/myapp/myapp.log mode = 0640 uid = 123 gid = 4Décision : Si la rotation forcée échoue, corrigez permissions/chemins avant d’accuser la planification.
-
Vérifier que l’application écrit bien dans le nouveau log.
cr0x@server:~$ sudo lsof /var/log/myapp/myapp.log | head COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME myapp 2210 myapp 7w REG 252,0 123456 401 /var/log/myapp/myapp.logDécision : Si elle écrit toujours dans un inode supprimé, corrigez le postrotate ou le comportement de réouverture de l’appli.
Checklist opérationnelle : ce que j’attends dans une section prête pour la production
- Un déclencheur explicite :
dailyousize/maxsize. - Une rétention explicite :
rotate Npluscompresset généralementdelaycompress. - Création correcte :
create MODE USER GROUPou compter sur l’appli pour créer en connaissance de cause. - Stratégie de réouverture sûre : postrotate signal/reload, validée avec
lsof. - Ne pas dépendre de l’héritage sauf si vous l’avez testé et que vous pouvez l’expliquer à quelqu’un à moitié réveillé.
- Garde-fous de taille pour les services bavards :
maxsizeempêche qu’une rotation quotidienne arrive trop tard.
FAQ
1) Pourquoi logrotate sort-il avec succès même lorsqu’il ne tourne rien ?
Parce que « aucun log nécessitant une rotation » est un résultat valide. Logrotate est un moteur de politique, pas un job « doit tourner quelque chose ». Le problème survient quand vous vous attendiez à une rotation mais que vous n’avez pas fourni de déclencheur ou que votre état/critères disent « pas encore ».
2) L’« une erreur de config » est-ce vraiment juste l’absence de daily ou size ?
Oui, dans le sens pratique : l’absence d’un déclencheur (ou penser que rotate N est un déclencheur) est la cause la plus fréquente de non-rotation silencieuse. Les erreurs de syntaxe crient ; les déclencheurs manquants chuchotent.
3) Devrais-je utiliser une rotation temporelle ou basée sur la taille ?
Pour un volume faible à modéré, daily suffit. Pour un fort volume, utilisez size ou maxsize (souvent en complément de daily) pour ne pas attendre minuit pour arrêter un log qui s’emballe.
4) Quelle est la différence entre size, minsize et maxsize ?
size tourne quand le fichier dépasse cette taille (indépendamment du calendrier). minsize ajoute un seuil minimal de taille à une rotation basée sur le temps. maxsize force la rotation quand la taille dépasse une limite même si les critères temporels ne sont pas encore remplis.
5) Quand devrais-je utiliser copytruncate ?
Lorsque l’application ne peut pas rouvrir les logs et que vous ne pouvez pas la corriger rapidement. C’est un hack de compatibilité avec des compromis : perte possible aux frontières de rotation et IO supplémentaire. Préférez renommage + signal/réouverture pour la justesse.
6) Pourquoi l’usage disque reste-t-il élevé après rotation ?
Parce que le processus peut continuer d’écrire dans un descripteur de fichier supprimé. Le système de fichiers ne libère l’espace que lorsque le dernier handle est fermé. Utilisez lsof +L1 pour le détecter et corrigez la stratégie de réouverture.
7) Puis-je supprimer /var/lib/logrotate/status pour « réinitialiser » les choses ?
Vous pouvez, mais c’est brutal. Cela peut provoquer des rotations inattendues sur de nombreux logs au prochain run. Plus sûr : éditez seulement l’entrée affectée, ou forcez la rotation pour une configuration spécifique avec logrotate -f et vérifiez le comportement.
8) Pourquoi ma section logrotate fonctionne dans un environnement mais pas dans un autre ?
Différents défauts globaux, comportement d’inclusion différent, timers différents, propriété de fichiers différente, et comportement de réouverture d’appli différent. La correction est ennuyeuse : rendre les déclencheurs explicites, tester avec -d -v, et valider avec lsof.
9) J’ai ajouté daily mais ça ne tourne toujours pas. Et maintenant ?
Vérifiez l’entrée du fichier d’état et la sortie debug. Si elle dit « already rotated », vous attendez le prochain jour. Si le timer ne se déclenche pas, corrigez la planification systemd. Si les permissions échouent, corrigez la propriété/le mode ou le su.
10) Devrais-je faire une rotation horaire sur Ubuntu 24.04 ?
Seulement si c’est vraiment nécessaire. Une rotation horaire augmente le churn (plus de fichiers, plus de compression, plus de métadonnées). Si votre problème est que le disque se remplit avant minuit, maxsize est souvent le levier préférable.
Prochaines étapes (quoi changer lundi matin)
Si vous êtes confronté à logrotate qui ne tourne pas sur Ubuntu 24.04, faites ceci dans l’ordre :
- Rendez le déclencheur explicite dans chaque section personnalisée : ajoutez
dailyousize/maxsize. Cessez de compter sur l’héritage. - Exécutez
logrotate -d -vsur le fichier exact qui vous préoccupe et lisez les lignes de justification. Ne devinez pas. - Vérifiez l’entrée du fichier d’état pour le log et confirmez qu’elle correspond à votre attente de « dernière rotation ». Corrigez le décalage horaire avant tout.
- Validez le comportement de réouverture avec
lsof +L1. Si vous voyez(deleted), vos rotations sont cosmétiques. - Ajoutez des garde-fous de taille pour les services bavards. La rotation quotidienne n’est pas un système de sécurité ; c’est un événement calendaire.
L’objectif n’est pas « que les logs tournent ». L’objectif est « que les logs tournent de manière prévisible, sans perte d’événements, sans pics CPU surprises, et sans vous réveiller ». Voilà le standard.