Solution 1 :
C'est probablement parce que même si vous tronquez le fichier, le processus d'écriture dans le fichier continuera d'écrire au dernier décalage où il se trouvait. Donc, ce qui se passe, c'est que logrotate tronque le fichier, la taille est nulle, le processus écrit à nouveau dans le fichier, continue au décalage qu'il a laissé, et vous avez maintenant un fichier avec des octets NULL jusqu'au point où vous l'avez tronqué plus le nouveau entrées écrites dans le journal.
od -c après tronquer + croissance soudaine, a généré une sortie du type :
0000000 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
*
33255657600 \0 C K B - s e r v e r [ h t t
33255657620 <more log output>
Ce que cela dit est du décalage 0 à 33255657600, votre fichier se compose d'octets nuls, puis de données lisibles. Atteindre cet état ne prend pas le même temps qu'il faudrait pour écrire tous ces octets nuls. Les systèmes de fichiers ext{2,3,4} prennent en charge quelque chose appelé fichiers fragmentés, donc si vous cherchez au-delà d'une région d'un fichier qui ne contient rien, cette région sera supposée contenir des octets nuls et ne prendra pas d'espace sur disque. Ces octets nuls ne seront pas réellement écrits, mais supposés être là, d'où le temps qu'il faut pour passer de 0 à 3,5 Go ne prend pas beaucoup de temps. (Vous pouvez tester le temps que cela prend en faisant quelque chose comme dd if=${HOME}/.bashrc of=largefile.bin seek=3432343264 bs=1
, cela devrait générer un fichier de plus de 3 Go en quelques millisecondes).
Si vous exécutez ls -ls
sur vos fichiers journaux après qu'ils ont été tronqués et qu'ils ont de nouveau subi une croissance soudaine, il devrait maintenant signaler un nombre au début de la ligne qui représente la taille réelle (en blocs occupés sur le disque), qui est probablement des ordres de grandeur plus petits que le taille signalée par seulement ls -l
.
Solution 2 :
Je suis extrêmement confiant que Kjetil l'a frappé. Drew, vous n'êtes peut-être pas encore convaincu par son explication, mais je vous invite à lire attentivement ce qu'il a dit.
Si vous l'acceptez, le correctif consiste soit à arrêter et redémarrer votre application lorsque les journaux sont tournés, soit à utiliser un outil comme les "rotatelogs" d'Apache, où vous envoyez la sortie du journal à l'outil via un tuyau, et l'outil s'occupe de faire tourner le fichier journal de temps en temps. Par exemple, une de mes instances apache se connecte avec
ErrorLog "|/usr/sbin/rotatelogs /www/logs/error_log 604800"
ce qui provoque beaucoup de fichiers journaux avec des noms comme
-rw-r--r-- 1 root root 4078 Dec 21 01:04 error_log.1292457600
-rw-r--r-- 1 root root 4472 Dec 29 08:41 error_log.1293062400
-rw-r--r-- 1 root root 78630 Jan 4 12:57 error_log.1293667200
-rw-r--r-- 1 root root 15753 Jan 12 01:10 error_log.1294272000
apparaître sans redémarrer apache ; Je peux ensuite les compresser manuellement après coup. Notez comment la rotation est effectuée chaque semaine, c'est-à-dire toutes les 604800 secondes, c'est-à-dire l'argument passé à rotatelogs
.
Si vous ne pouvez pas arrêter et redémarrer l'application, et qu'elle ne peut pas se connecter via un canal, alors je pense que vous avez un vrai problème. Peut-être que d'autres auront des suggestions.