Purge log

De wiki.nexiat.fr
Aller à la navigation Aller à la recherche
Fiche express
Domaine Purge manuelle de gros fichiers de log
Outils find, sed
Solution standard équivalente Logrotate
Voir aussi Logrotate · Find

Script de dépannage qui tronque les fichiers de log volumineux d'une arborescence en ne conservant que leurs 500 dernières lignes — utile pour des applications (typiquement Oracle) dont les logs ne sont pas couverts par logrotate et qui grossissent sans limite.

Script

#!/bin/sh

REP="/log/oracle/"
LISTE=$(mktemp)

find "$REP" -type f -size +3000k > "$LISTE"

while IFS= read -r fichier; do
    nb_lignes=$(wc -l < "$fichier")
    a_supprimer=$(( nb_lignes - 500 ))

    if [ "$a_supprimer" -gt 0 ]; then
        sed -i "1,${a_supprimer}d" "$fichier"
    fi
done < "$LISTE"

rm -f "$LISTE"

Le script d'origine contenait un bug qui l'empêchait de fonctionner : la commande sed -i '1,$ligne_log d' $fichier_log était entre guillemets simples, donc $ligne_log n'était jamais substitué par le shell — sed recevait littéralement la chaîne 1,$ligne_log, une adresse invalide. Corrigé ici avec des guillemets doubles et la variable directement collée au d ("1,${a_supprimer}d"), forme attendue par sed.

Autres corrections :

  • find ... -size +3000 sans unité est ambigu (l'unité par défaut varie selon les implémentations, généralement des blocs de 512 octets) — précisé ici en kilo-octets (+3000k).
  • extraction du nombre de lignes via wc -l fichier | cut -d' ' -f8 — fragile, car la position du champ dépend du nombre d'espaces de padding inséré par wc (variable selon la largeur du nombre). Remplacé par wc -l < fichier, qui retourne directement le compte sans nom de fichier ni padding.
  • boucle numérique manuelle (ligne/ligne_total, head/tail pour extraire une ligne du fichier liste) remplacée par une simple boucle while read, plus directe et sans relire le fichier liste à chaque itération.

Alternative recommandée

Ce script reste un pansement pour des logs non couverts par la rotation standard. Deux pistes plus robustes :

  • configurer une règle logrotate dédiée pour ces logs (avec copytruncate si l'application ne peut pas rouvrir son fichier après renommage) — la solution normale pour ce besoin ;
  • à défaut, une purge en place plus simple et sans risque d'erreur d'adressage sed :
tail -n 500 "$fichier" > "${fichier}.tmp" && mv "${fichier}.tmp" "$fichier"

Voir aussi

  • Logrotate — outil standard de rotation/purge de logs, à préférer pour un besoin récurrent
  • Find — sélection de fichiers par critère de taille/âge