Rotation d'un fichier de log Tomcat : catalina.out
Voici un problème sur lequel je suis tombé il y a peu de temps. La rotation d'un fichier de log Tomcat, à savoir le fichier catalina.out.
Pour ceux qui ne connaissent pas le principe de la rotation des fichiers journaux, elle consiste simplement à segmenter, des fichiers de logs qui grossissent très vite sur des serveurs à grande activité, en une multitude de petits fichiers.
Cette action est souvent essentielle car elle améliore les performances ainsi que la maintenance des serveurs.
Pour cela, on doit fermer le fichier en cours d'utilisation par le serveur, le renommer sous un nouveau nom, et créer un nouveau fichier de log vide pour que le serveur puisse continuer d'y enregistrer les logs.
Bien que cette opération puisse sembler impossible, il existe une multitude de logiciel capable de s'acquitter de cette tache, comme logrotate, logresolve, cronlog ...
Ces derniers fonctionnent à merveille sur différents serveurs. Cependant, pour les serveurs d'applications Java comme Tomcat, çà ne marche pas du tout pour le fichier de log nommé catalina.out (pour des raisons techniques que je ne développerais pas ici).
Faisant face à des fichiers de plus de 700 mo, il me fallait donc trouver une solution pour segmenter ces derniers.
Après plusieurs secondes de Google acharnés (vu le nombre de site qui traite de ce genre de problème), je me suis aperçu que personne n'avait vraiment de solution.
Néanmoins, une mixture de plusieurs suggestions intéressantes, laissées sur des forums, j'ai finis par trouver la solution qui peut paraître si simple :
cp -f catalina.out catalina.out.1 && cat /dev/null > catalina.out
Comme l'auront bien compris tous ceux qui n'auront pas décroché cette réflexion, il suffit simplement de mettre cette ligne dans un script en crontab, /etc/cron.daily/ par exemple, afin de bénéficier d'une rotation de log sur catalina.out tous les jours sans avoir à éteindre et redémarrer son serveur.
Ayant plusieurs Tomcat à gérer, j'utilise le script suivant que vous pourrez adapter à vos besoins :
#!/bin/csh # On stocke la date du jour au format yyyy-mm-dd DATE=`date "+%Y-%m-%d"` # Répertoire contenant toutes les applications Tomcat $REP=/serveur_java/ # On se positionne dans ce répertoire cd $REP # On parcours l'ensemble des sous-répertoires foreach SITE (`ls`) if (-f $SITE/tomcat/logs/catalina.out) then # On fait la rotation cp -f $SITE/tomcat/logs/catalina.out $SITE/tomcat/logs/catalina.out.$DATE cat /dev/null > $SITE/tomcat/logs/catalina.out # On compresse le fichier qui vient de subir une rotation gzip $SITE/tomcat/logs/catalina.out.$DATE endif end
P.S : j'ai testé ce script sur un serveur Tomcat, écrivant plusieurs milliers de lignes de logs à la seconde, avec succès puisque qu'il n'y a eu aucune perte pendant la rotation !
7 Commentaires pour "Rotation d'un fichier de log Tomcat : catalina.out"
Flux des commentaires de cet article Ajouter un commentairePourquoi ne pas utiliser un paramètrage de "logrotate" (par défaut sous FC) utilisant les options "copytruncate" (cp au lieu de mv) et compress (gzip) qui aurait le même effet.
Pour info, le RPM standard de tomcat 5 fournit le fichier suivant :
/var/log/tomcat5/*.txt {
copytruncate
weekly
rotate 52
compress
missingok
}
/var/log/tomcat5/catalina.out {
copytruncate
weekly
rotate 52
compress
missingok
}
Je ne connaissait pas du tout le paramètre copytruncate de logrotate. En effet si ça fonctionne, se serait plus simple à mettre en oeuvre.
Je vais faire des tests la dessus ...
Merci pour l'info !
Oui, mais avec logrotate il restera le problème des fichiers datés. Il est possible de demander à tomcat de ne plus faire de rotation de logs (si on peut appeler ça rotation, car il ne semble pas y avoir d'effacement réguliers!), par contre il faut bien penser à configurer le logrotate derrière
tomcat.apache.org
Pour les "fichiers datés" du type localhost_log.yyyy-mm-dd.txt, j'ai fais ce petit script qui garde deux jours de logs dans le répertoire "/logs" et 15 jours de logs dans le répertoire "/logs/old" (qu'il faut créer). J'ai plusieurs installations de tomcat donc je fais une boucle pour tous les parcourir mais sinon avec une seule installation, deux "find" suffisent.
#!/bin/bash
# Pour toutes les instances de tomcat installées
# dans /usr/local ("tomcat-un", "tomcat-deux", etc.)
for TOMCAT_INST in /usr/local/tomcat-*; do
# On recherche les fichiers de log plus vieux de 2 jours
# et on les déplace dans le répertoire "logs/old"
find $TOMCAT_INST/logs -maxdepth 1 -type f -name "localhost_log.*" -mtime +2 -exec mv {} $TOMCAT_INST/logs/old \;
# On supprime les fichiers plus vieux de 15 jours
# du répertoire "logs/old"
find $TOMCAT_INST/logs/old -maxdepth 1 -type f -name "localhost_log.*" -mtime +15 | xargs rm -f
done
Le problème du "mv" (pour l'avoir expérimenté), c'est le descripteur de fichier... Pour recréer un nouveau fichier de log tout frais, il faut redémarrer l'application sinon le descripteur reste sur l'ancien fichier ...
Effectivement sans ça, tu te retrouves avec un fichier dans le répertoire old/ qui est encore "feedé" par tomcat :S
Alors pour l'instant je vais me passer des "mv" et faire juste des suppressions
Pour ma part, j'ai créé le fichier /etc/logrotate.d/tomcat_5.5.23
/exploit/tomcat/5.5.23-*/instances/*/logs/catalina.out {
copytruncate
daily
rotate 31
compress
missingok
notifempty
}
et j'ai rajouté une ligne dans la crontab de root
59 23 * * * /usr/sbin/logrotate /etc/logrotate.d/tomcat_5.5.23
Ca à l'air de fonctionner nickel. (tout du moins avec les tests réalisés avec l'option size 150k)
Je vais juste attendre de voir comment les fichiers vont être renommés (demain) et ce qui se passera lorsqu'il y a moins de 31 jours dans le mois.
Merci pour le coup de pouce
Le seul probleme avec ton script c'est que la commande cat /dev/null ne fait que cacher les logs du coup il n'ya pas moyen pour une application qui tourne depuis des annees de supprimer ses anciens logs??????
cp /dev/null