J'ai un fichier journal qui devient énorme. Les informations que je peux en tirer sont négligeables.
Je veux le lier à /dev/null
. Cependant, même s'il est "supprimé" (voir ci-dessous la sortie de lsof), il consomme tout mon espace disque.
Je peux le tronquer en utilisant :
: > "/proc/$pid/fd/$fd"
# for instance:
: > "/proc/2456/fd/2"
Malheureusement, certains processus du système sont mis en pause lorsque le disque dur est plein et doivent être redémarrés manuellement (et je veux éviter que les processus ne soient mis en pause).
Existe-t-il un moyen de tronquer automatiquement le fichier lorsqu'il devient trop volumineux (par exemple lorsqu'il consomme plus de 1G ?)
lsof
sortie :
program 2456 user 2w REG 8,5 441433300992 0 21365598 /home/user/file (deleted)
Réponse acceptée :
Le contenu d'un fichier n'est supprimé que lorsqu'il n'y a plus de référence à celui-ci. Une référence à un fichier peut être une entrée de répertoire ou un descripteur de fichier ouvert. Lorsque vous supprimez un fichier (par exemple avec le rm
commande) qu'un processus est toujours ouvert (ici, le processus qui s'y connecte), le contenu du fichier reste jusqu'à ce que le processus ferme le fichier.
Le moyen le plus simple de se débarrasser des anciens journaux est de
- Déplacez le fichier vers un autre nom, par ex.
mv foo.log foo.log.old
- Demandez au processus de rouvrir son fichier journal. Si le processus n'a aucun moyen de le faire, redémarrez-le.
- Supprimez l'ancien fichier journal maintenant fermé (
rm foo.log.old
).
Le programme logrotate automatise ce mécanisme et peut être configuré quant au nombre de jours d'anciens journaux à conserver. Il peut également compresser les anciens journaux.
Pour l'étape 2, si vous ne pouvez pas redémarrer le programme et qu'il n'a aucun moyen de rouvrir son fichier journal, vous pouvez essayer de le forcer à rouvrir le fichier journal avec un débogueur. Cependant, sachez que cela peut faire planter le programme s'il conserve des informations sur le fichier journal qui sont devenues incohérentes. Preuve de concept (attention, beaucoup de choses peuvent mal tourner ; en cas de doute, ne le faites pas) :
gdb -n $pid -batch -x /dev/stdin <<EOF
call close(2)
call open("/path/to/foo.log", 1)
EOF
Une autre méthode grossière pour libérer de l'espace disque si vous ne vous souciez d'aucun des journaux consiste à tronquer le fichier. Le processus de journalisation continuera à écrire à la même position dans le fichier, mais le fichier deviendra un fichier fragmenté. Si vous lisez le fichier depuis le début, vous obtiendrez des octets nuls, mais ces octets nuls n'occupent que quelques Ko sur le disque.
dd if=/dev/null of=/path/to/foo.log