Par défaut, une application Rails ne prévoit aucun mécanisme pour archiver ses logs au fil du temps, c’est à l’administrateur système de mettre en place un système pour gérer cet archivage comme il l’entend.
Aujourd’hui très peu d’administrateurs prennent le temps de mettre en place un tel système. C’est pourtant un aspect critique de la gestion de l’application et de son bon fonctionnement à long terme sur le serveur.
En effet, si vous ne mettez pas en place un système d’archivage des logs, le fichier production.log
va grossir au fil des jours et finir par atteindre une taille de plusieurs Go. Votre serveur peut donc à terme manquer d’espace ce qui vous causera toute sorte de soucis et notamment l’indisponibilité de votre application Rails.
Nous allons voir comment utiliser un outil système standard sous Linux pour gérer cet archivage. C’est l’outil logrotate que nous allons utiliser pour effectuer cette tâche de manière automatique.
Logrotate permet de limiter la taille des fichiers de log en réalisant deux opérations :
Logrotate va garder un certain nombre de fichiers de logs accessibles pour consultation sous forme compressée. On ne gâche donc plus d’espace disque avec de très vieux logs et ceux conservées consomment un espace disque restreint.
Il y a de très fortes chances que logrotate soit déjà installé sur votre système. Si ce n’est pas le cas, vous le trouverez à coup sûr via votre outil de gestion de paquets.
Configurer un archivage des logs avec logrotate est très simple. C’est un outil qui existe depuis longtemps et qui est très utilisé notamment grâce à sa simplicité de mise en œuvre.
Si vous regardez votre répertoire /var/log
vous noterez que vos fichiers de logs sont archivés et compressés. C’est logrotate qui se charge de ça. Ajoutons donc notre configuration pour que l’outil gère les logs de notre application.
La configuration principal de logrotate se trouve dans le fichier /etc/logrotate.conf
. Il est possible d’ajouter votre configuration directement dedans mais la bonne pratique veut qu’une directive include /etc/logrotate.d
soit utilisée dans ce fichier ce qui va permettre de créer un fichier de configuration par service dans le répertoire /etc/logrotate.d
.
Nous allons donc suivre cette bonne pratique est créer un fichier /etc/logrotate.d/mon_app_rails
:
/var/www/mon_app_rails/current/log/*.log {
monthly
size 1G
missingok
rotate 7
compress
delaycompress
notifempty
copytruncate
}
Cette syntaxe me semble particulièrement facile à comprendre et à mettre en œuvre mais je vais tout de même vous expliquer à quoi sert chaque ligne :
.log
de notre répertoire /var/www/mon_app_rails/current/log
monthly
archive le fichier chaque mois, on peut demander à ce que ce soit chaque jour, chaque semaine ou encore chaque annéesize 1G
permet de lancer l’archivage si le fichier de log a atteint la taille de 1Go, cette condition a une précédence plus forte que monthly
. On peut utiliser d’autres unités telles que k
, M
missingok
ne génère pas d’erreur si l’un des fichiers mentionné n’existe pasrotate 7
permet de garder les sept derniers fichiers archivés, donc ici sept moiscompress
demande la compression via GZip des archivesdelaycompress
ne compresse pas la toute dernière archive mais uniquement les plus anciennes pour faciliter l’analyse des logs de la période passéenotifempty
ne crée pas d’archive si le fichier de log est videcopytruncate
copie le fichier de log vers son nom d’archive puis le vide ce qui permet d’éviter les problèmes avec un processus qui requière que le fichier existe avant de pouvoir écrire dedansDe nombreuses autres options existent et permettent d’avoir un contrôle très fin sur la gestion de vos logs, je vous encourage à lire le manuel de logrotate pour les découvrir.
On peut maintenant tester notre configuration fraîchement ajoutée en lançant manuellement la commande logrotate. Elle requiert les droits root :
$ sudo /usr/sbin/logrotate -f /etc/logrotate.conf
Vous pouvez maintenant vérifier que votre archive a bien été crée dans le répertoire des logs de votre application.
Dans un mois, logrotate créera une nouvelle archive et compressera les anciennes.
Un ls
dans le répertoire donnera alors quelque chose comme :
$ ls log/
production.log production.log.1 production.log.2.gz
production.log
est votre fichier de log courant, utilisé par votre application Rails. production.log.1
est une copie des anciens logs (entre la première et la deuxième rotation) et production.log.2.gz
est la version compressée d’une archive plus ancienne.
Quand logrotate aura créé sept archives, il commencera à supprimer les plus anciennes à chaque rotation pour ne garder que les sept plus récentes. Pour mémoire ce comportement est dû à la directive rotate 7
dans notre configuration.
Vous pouvez maintenant vérifier que le répertoire /etc/cron.daily
contient bien un fichier logrotate
ce qui assurera que la commande logrotate
sera exécutée chaque jour :
#!/bin/sh
test -x /usr/sbin/logrotate || exit 0
/usr/sbin/logrotate /etc/logrotate.conf
Si c’est le cas, vous avez l’assurance que logrotate prendra maintenant soin d’archiver automatiquement vos fichiers de logs pour vous.
Nous avons donc vu qu’il est extrêmement simple de mettre en œuvre une rotation de log en passant par l’outil logrotate. Cette tâche dans le contexte des applications Rails passe souvent à la trappe et c’est une vrai erreur selon moi.
Vous risquez des soucis avec votre serveur et de plus vous vous mettez des bâtons dans les roues pour le jour où vous voudrez consulter vos logs. Essayez d’ouvrir un fichier texte de 2Go et de le parcourir… Il est tout de même plus simple d’ouvrir celui correspondant au mois voulu et de faire sa recherche dans un fichier d’une centaine de Mo.
Vous n’avez plus qu’à écrire vos petits fichier de configuration logrotate maintenant !
L’équipe Synbioz.
Libres d’être ensemble.