CyberSDF

Reprenez la main sur votre numérique

Logrotate : limiter la taille d’un journal avec size et maxsize

un poste de travail sobre vu de trois quarts, ecran eteint, clavier mecanique, carnet ouvert

Un journal applicatif de 6 Go a rempli /var pendant la nuit, et /etc/logrotate.d/ ne contient encore aucune règle pour lui. logrotate 3.21.0-1 sous Debian 12 bookworm, 3.22.0-1 sous Debian trixie et 3.21.0-2build1 sous Ubuntu 24.04 plafonnent ce fichier, à condition de savoir quand le programme passe. La page de manuel Debian logrotate(8) fixe la limite qui déroute le plus : un journal n’est pas modifié plus d’une fois par jour, sauf si le critère porte sur la taille du fichier et que logrotate tourne plusieurs fois dans la journée.

Sommaire
  1. Sur Debian 12 et Ubuntu 24.04, logrotate ne passe qu’une fois par jour
  2. Quatre directives dans /etc/logrotate.d/ suffisent : size, rotate, compress, missingok
  3. Le message skipping because parent directory has insecure permissions vise le dossier, pas le fichier
  4. Un service qui garde son journal ouvert continue d’écrire dans l’ancien fichier
  5. Le passage en mode debug n’écrit rien, la rotation ne part qu’avec –force ou le déclencheur quotidien
  6. Sources

Sur Debian 12 et Ubuntu 24.04, logrotate ne passe qu’une fois par jour

La rotation quotidienne est le rythme par défaut sur ces deux distributions, et la fiche du paquet Debian pour bookworm l’écrit sans détour : normally, logrotate runs as a daily cron job. Un journal n’est pas modifié plus d’une fois par jour, sauf si le critère porte sur la taille et que logrotate tourne plusieurs fois dans la même journée, précise la page de manuel Debian logrotate(8). Résultat, un plafond de 100 Mo contrôlé toutes les 24 heures laisse passer 100 Go si l’application écrit vite.

Le wiki Arch documente l’autre déclencheur, un service logrotate.service lancé par logrotate.timer, qui remplace la tâche cron. Avant de régler un seuil serré, vérifiez lequel équipe votre machine.

ls -l /etc/cron.daily/logrotate
systemctl list-timers logrotate.timer

Ce que vous devez voir : l’une des deux commandes répond, un fichier de tâche quotidienne ou un minuteur actif. Deux réponses vides signifient qu’aucun déclencheur n’est installé, et la règle ne s’exécutera jamais seule.

Tableau établi d’après la page de manuel Debian logrotate(8) et le dépôt du projet, dont le fichier de configuration fixe les valeurs par défaut à rotate 0, ifempty et nomissingok.

Directive logrotate Condition de rotation Compatibilité avec daily ou weekly Valeur par défaut
size 100M fichier au-dessus de 104 857 600 octets exclue, size remplace le critère de temps aucun seuil, le critère de temps s’applique
maxsize 500M fichier au-dessus de 500 Mo, même avant l’échéance conservée, la rotation peut arriver plus tôt aucune valeur
minsize 10M fichier au-dessus de 10 Mo, mais pas avant l’échéance conservée, la rotation peut être retardée aucune valeur
rotate 5 indépendante de la taille sans effet 0, l’ancienne version est supprimée au lieu d’être conservée
compress indépendante de la taille sans effet gzip au niveau -6, une fois l’option activée

Selon la page de manuel Debian, compressoptions vaut -6 pour gzip, et selon le wiki Arch, ce passage quotidien s’appuie sur logrotate.timer plutôt que sur cron.

Quatre directives dans /etc/logrotate.d/ suffisent : size, rotate, compress, missingok

/etc/logrotate.conf inclut les fichiers de /etc/logrotate.d dans l’ordre alphabétique, et la page de manuel Debian précise que les options locales l’emportent sur les options globales, qu’une définition tardive l’emporte sur une définition antérieure, et qu’une option globale ne s’applique pas aux includes placés avant elle. Réunir les quatre directives dans le fichier de l’application évite de dépendre de cet héritage. Les commandes ci-dessous sont celles de logrotate 3.21.0-1 sous Debian 12 bookworm et de logrotate 3.21.0-2build1 sous Ubuntu 24.04.

  1. Créez le fichier de règle, en remplaçant le chemin du journal par le vôtre.

    sudo tee /etc/logrotate.d/monapp > /dev/null <<'EOF'
    /var/log/monapp.log {
        size 100M
        rotate 5
        compress
        missingok
    }
    EOF
    

    Ce que vous devez voir : la commande rend la main sans rien afficher, le contenu partant vers /dev/null. La vérification, elle, montre le bloc enregistré.

    cat /etc/logrotate.d/monapp
    

    Le seuil s’écrit en mégaoctets, le dépôt du projet multipliant l’unité M par 1024 fois 1024, soit 104 857 600 octets pour size 100M.

  2. Simulez la rotation sans rien modifier. L’option –debug n’applique aucun changement et ne met pas à jour le fichier d’état, comme l’indique la page de manuel Debian.

    sudo logrotate --debug /etc/logrotate.d/monapp
    

    Ce que vous devez voir : la configuration lue, puis, pour le journal concerné, la date du jour, la dernière rotation connue et la décision prise.

    reading config file /etc/logrotate.d/monapp
    Reading state from file: /var/lib/logrotate/status
    
    rotating pattern: /var/log/monapp.log 104857600 bytes empty log files are rotated, (5 rotations), old logs are removed
    considering log /var/log/monapp.log
      Now: 2026-09-19 06:25
      Last rotated at 2026-09-19 06:25
      log needs rotating
    rotating log /var/log/monapp.log, log->rotateCount is 5
    renaming /var/log/monapp.log to /var/log/monapp.log.1
    creating new /var/log/monapp.log mode = 0644 uid = 0 gid = 0
    compressing log with: /bin/gzip
    old log /var/log/monapp.log.5 does not exist
    

    La décision se lit dans la sortie. log needs rotating annonce une rotation au prochain passage réel, tandis que log does not need rotating (log size is below the ‘size’ threshold) signale un fichier encore sous les 100 Mo. Deux autres lignes servent au diagnostic, log /var/log/monapp.log does not exist — skipping quand le fichier manque et que missingok est présent, et old log /var/log/monapp.log.5 does not exist tant qu’aucune archive n’a occupé la cinquième place.

  3. Déclenchez une rotation réelle pour valider la chaîne complète, renommage, recréation et compression. L’option –force fait tourner le journal même sous le seuil.

    sudo logrotate --force /etc/logrotate.d/monapp
    echo $?
    ls -l /var/log/monapp.log*
    

    Ce que vous devez voir : aucune sortie pour les deux premières lignes, un code de retour 0, puis le journal recréé à côté d’une archive compressée. La page de manuel Debian rappelle que logrotate sort avec un code non nul dès qu’une erreur survient, même si le fichier d’état a été mis à jour.

    -rw-r--r-- 1 root root         0 19 sept. 06:26 /var/log/monapp.log
    -rw-r--r-- 1 root root  12114944 19 sept. 06:26 /var/log/monapp.log.1.gz
    
  4. Vérifiez la date retenue par logrotate pour ce journal.

    sudo grep monapp /var/lib/logrotate/status
    

    Ce que vous devez voir : le chemin du journal entre guillemets, puis la date et l’heure du dernier traitement, dans un format dont les zéros de tête sont absents.

    "/var/log/monapp.log" 2026-9-19-6:25:0
    

    Le wiki Arch nomme ce fichier /var/lib/logrotate.status, quand la page de manuel Debian fixe /var/lib/logrotate/status : les deux sources divergent sur ce point, et le chemin Debian est celui qui compte ici. À la sixième rotation, la ligne old log … does not exist fait place à removing old log /var/log/monapp.log.5, qui solde le plafond de cinq archives.

Trop ouvert, un fichier de configuration est rejeté avant même d’être lu. Le dépôt du projet refuse un fichier accessible en écriture au groupe ou aux autres avec le message Ignoring /etc/logrotate.d/monapp because it is writable by group or others, et le propriétaire doit être root.

ls -l /etc/logrotate.d/monapp

Le message skipping because parent directory has insecure permissions vise le dossier, pas le fichier

Un journal rangé dans un dossier inscriptible par un groupe autre que root est refusé par logrotate lancé en root, tant que le bloc ne contient pas de directive su. Le contrôle porte sur le dossier parent, jamais sur le fichier, et il ne s’exécute que lorsque le programme tourne avec les privilèges de root. Le programme l’annonce lui-même, et le message sort tel quel :

error: skipping "/var/www/monapp/logs/app.log" because parent directory has insecure permissions (It's world writable or writable by group which is not "root") Set "su" directive in config file to tell logrotate which user/group should be used for rotation.

La cause tient aux droits du dossier parent, jamais à ceux du journal. Le dépôt du projet montre que le contrôle compare le groupe propriétaire du dossier à root et sa permission d’écriture pour le groupe ou pour tout le monde. La page de manuel Debian recommande la directive su dès qu’un dossier est contrôlé, directement ou indirectement, par un utilisateur non privilégié. Le wiki Arch classe ce message dans son dépannage, avec la même correction.

Cette correction s’écrit dans le bloc, avec l’utilisateur et le groupe qui doivent posséder l’archive et le journal recréé.

/var/www/monapp/logs/app.log {
    su www-data www-data
    size 100M
    rotate 5
    compress
    missingok
}

Le piège prend un second visage quand le dossier parent n’existe pas. nomissingok étant la valeur par défaut, l’absence du répertoire fait échouer la règle avec stat of /var/www/monapp/logs failed: No such file or directory, et seule la directive missingok fait passer ce contrôle.

Un service qui garde son journal ouvert continue d’écrire dans l’ancien fichier

Après un renommage, un programme qui tenait le fichier ouvert écrit toujours dans l’inode renommé, et le nouveau fichier reste à zéro. La page de manuel Debian décrit copytruncate comme la solution pour un programme qui ne peut pas être averti de fermer son journal, avec une réserve explicite : une très courte fraction de temps s’écoule entre la copie et la troncature, et des lignes peuvent disparaître. Cette option implique norenamecopy et rend la directive create sans effet.

Deux réglages évitent cette perte. Le bloc postrotate peut recharger le service après la rotation, et l’option delaycompress reporte la compression au tour suivant pour laisser le programme terminer ses écritures.

postrotate
    systemctl reload monapp
endscript
delaycompress

Une différence entre versions mérite attention si la règle passe par olddir. La page de manuel de Debian 12, logrotate 3.21.0-1, décrit createolddir avec trois arguments, mode, propriétaire et groupe, quand celle de trixie, logrotate 3.22.0-1, rend les deux derniers facultatifs. Une règle recopiée d’un serveur récent vers bookworm gagne donc à être relue avant déploiement.

Le passage en mode debug n’écrit rien, la rotation ne part qu’avec –force ou le déclencheur quotidien

size 100M ou maxsize 500M avec daily, que choisir ?

size remplace le critère de temps, il est donc exclusif avec daily et weekly, comme l’indique la page de manuel Debian logrotate(8). maxsize se combine au contraire avec daily et déclenche la rotation dès le dépassement du seuil, sans attendre l’échéance. Pour un journal qui produit 2 Go par jour, écrivez daily puis maxsize 500M, et faites tourner logrotate plusieurs fois par jour : sans passage supplémentaire, maxsize ne se déclenche jamais.

Comment vérifier qu’une règle se déclenchera sans rien casser ?

sudo logrotate –debug /etc/logrotate.d/monapp affiche les décisions sans modifier les journaux ni le fichier d’état, ce que la page de manuel Debian fixe noir sur blanc. Cherchez la ligne log needs rotating dans la sortie. Pour appliquer tout de suite, remplacez –debug par –force : la rotation a lieu même sous le seuil, et chaque erreur éventuelle s’affiche.

La rotation a-t-elle pu supprimer mon journal au lieu de le conserver ?

Oui, si rotate est absent ou fixé à 0, puisque la page de manuel Debian indique que dans ce cas les anciennes versions sont supprimées plutôt que conservées. Ajoutez rotate 5 dans le bloc pour garder cinq archives. L’ordre compte aussi : une définition tardive l’emporte sur une définition antérieure, et une option globale ne s’applique pas aux include qui la précèdent.

Un journal situé dans /etc ou /usr peut-il tourner ?

Pas avec le service systemd. La page de manuel Debian signale que logrotate.service active ProtectSystem=full, qui interdit à logrotate de modifier un journal dans /etc et /usr. Déplacez le fichier sous /var/log, ou lancez logrotate à la main sur ce fichier précis.

Faut-il copytruncate ou un rechargement du service ?

copytruncate convient à un programme qui ne peut pas être averti, mais la page de manuel Debian prévient qu’une très courte fraction de temps s’écoule entre la copie et la troncature, avec un risque de perte de lignes. Un bloc postrotate qui exécute systemctl reload monapp écarte ce risque et garde des noms de fichiers nets. Réservez donc copytruncate aux logiciels qui n’offrent aucun mécanisme de réouverture.

Combien de place prennent le journal et ses cinq archives ?

Avec size 100M et rotate 5, la règle plafonne le journal courant à 100 Mo et conserve cinq archives d’au plus 100 Mo avant compression, soit un maximum brut de 600 Mo. compress ramène ce total à la taille réelle des fichiers compressés, et logrotate compresse avec gzip au niveau -6 par défaut, selon la page de manuel Debian. L’espace n’est réellement rendu qu’à la sixième rotation, quand la plus ancienne archive est supprimée.

La vérification finale tient en une commande, qui doit afficher un log needs rotating pour un fichier au-dessus du seuil, et rien d’autre pour un fichier encore petit.

sudo logrotate --debug /etc/logrotate.d/monapp | grep -E 'rotating|considering|needs'

Sources