Il vous est sans doute déjà arrivé d'avoir à consulter les fichiers situés dans le répertoire /var/log pour retrouver la trace d'un événement ou d'une erreur (cause d'un plantage, raison d'échec de la connexion PPP, etc) et de constater que ce répertoire contient beaucoup de fichiers et qu'il est un peu difficile de s'y retrouver. D'autre part, les mêmes événements ne sont pas forcément mentionnés dans le même fichier selon la distribution que vous utilisez. Nous allons explorer dans cet article le fonctionnement et le paramétrage du daemon système syslogd, ce qui devrait vous permettre de reconfigurer la gestion de l'historique de votre machine en fonction de vos besoins.
syslogd et klogd
L'enregistrement des événements systèmes est géré par deux programmes : klogd et syslogd. Vous devriez pouvoir vous en persuader en exécutant la commande ps auwx | grep log. Ces deux programmes peuvent être lancés soit par les scripts d'initialisation en mode daemon, soit directement par /etc/inittab. La plupart des distributions utilisent la première solution.
klogd est simplement à l'écoute des messages en provenance du noyau. C'est syslogd qui exécute la plus grosse partie du travail. Lors de son lancement, syslogd lit le fichier /etc/syslog.conf, et en déduit dans quel fichier doit être enregistré chaque message. Chacun d'eux est composé de trois parties distinctes : la priorité, le service et le texte qui devra être enregistré dans l'historique. C'est en fonction de la priorité du message et du service qui l'a généré que syslog déterminera dans quel fichier enregistrer le message.
Attardons-nous un instant sur le fonctionnement de klogd avant de nous étendre sur syslogd. Comme nous venons de le dire, klogd intercepte les messages que le noyau génère grâce à la fonction printk et les envoie au programme syslog, à moins que klogd n'ait été lancé avec le paramètre -f nom-de-fichier auquel cas les messages seront enregistrés dans le fichier mentionné. Parmi les paramètres intéressants de klogd, notons également l'existence de -o qui demande à klogd de lire tous les messages disponibles dans le tampon de messages du noyau et de se terminer. Cette fonctionnalité peut par exemple être utilisée pour enregistrer dans un fichier les messages du processus de boot juste après le démarrage. Il suffit pour cela d'ajouter la commande klogd -o -f /var/log/boot.messages dans un fichier d'initialisation avant que klogd soit définitivement lancé comme tâche de fond qui transmettra ses messages à syslogd.
Fichier syslog.conf
Examinons le fichier /etc/syslog.conf. Chaque ligne contient une règle comportant deux champs. Le premier est le sélecteur qui déterminera quels seront les messages concernés. Le deuxième champ concerne l'action à effectuer lorsqu'un message correspondant doit être traité. Ces deux champs doivent être séparés par un ou plusieurs espaces. Notons également que (tout comme pour la plupart des fichiers de configuration) les lignes vides, ainsi que tout ce qui suit un caractère # jusqu'à la fin de la ligne ne sont pas pris en compte.
Le champ de sélection lui-même est séparé en deux parties (service et priorité) séparées par un point. Les noms symboliques des services et priorités ne sont pas sensibles à la casse (bien qu'il soit d'usage de les écrire en minuscule). Il est également possible d'utiliser des nombres à la place des noms symboliques, mais cette pratique est vigoureusement déconseillée. D'autre part, une règle peut être répartie sur plusieurs lignes à condition qu'elles soient terminées par le caractère '\'. L'étoile '*' peut quand à elle être utilisée comme joker pour désigner l'ensemble des priorités ou services : le sélecteur mail.* désigne donc tous les messages provenant des programmes de gestion du mail et *.debug tous les messages de débogage. Une virgule peut être utilisée pour séparer deux noms de services, et un point-virgule pour assembler deux sélecteurs. Concrètement, l'expression mail,news.err correspondra aux messages d'erreurs venant des programmes gérant le mail ou les news. On aurait également pu écrire mail.err;news.err. Enfin, la priorité none signifie qu'aucun message ne doit être loggé pour le service correspondant. Par exemple, *.debug;mail,news.none indique que l'on logge tous les messages de débogage, sauf ceux venant des services mail et news.
Service |
Utilisation |
|
auth | Messages relatifs à la sécurité du système et à l'authentification des utilisateurs. | |
cron | Messages générés par les daemons cron et at. | |
daemo | daemon | Messages générés par les autres daemons systèmes. |
kern | Messages générés par le noyau (en provenance de klogd). | |
local0 à local7 | Services définis localement par l'administrateur système. | |
lpr | Messages relatifs au service d'impression. | |
Messages provenant du système de mail. | ||
news | Messages générés par la gestion des news USENET. | |
syslog | Messages générés en interne par syslog. | |
user | (C'est le service par défaut). Messages en provenance des utilisateurs. | |
uucp | Messages générés par le système UUCP (Unix-to-Unix Copy). |
Priorité |
Signification |
|
emerg | (emergency) : Message urgent. Le système est inutilisable ou risque de le devenir à très cours terme. | |
alert | (alerte) : Message alertant l> | (alerte) : Message alertant l'administrateur système qu'une action de sa part est requise. |
crit | (critique) : Message critique. | |
err | (erreur) : Message d'erreur. | |
warning | (ou warn)(avertissement) : Message d'avertissement. | |
notice | (note) : Message de fonctionnement normal, sans gravité particulière. | |
info | (information) : Message à titre informatif. | |
debug | (debogage) : Message de débogage. |
Le programme syslogd disponible sur votre distribution Linux a le même comportement par défaut que le syslogd des systèmes BSD dans le sens où tous les messages pour le même service avec une priorité plus haute seront loggés avec la même action. Maintenant que nous savons définir les classes de messages qui nous intéressent, il est temps de nous intéresser à ce que l'on peut faire des messages interceptés.
Fichiers
L'action la plus courante consiste simplement à ajouter le message à la fin d'un fichier. Pour cela, il suffit de mentionner le nom de fichier (le chemin complet, commençant par le caractère / doit impérativement être utilisé) comme seconde partie de la règle.
kern.* /var/log/kernel.log
La règle précédent enregistre tous les massages venant du noyau dans le fichier /var/log/kernel.log.
Par défaut, le fichier est écrit immédiatement sur disque après l'ajout de chaque message. Il est possible de délayer cette écriture en préfixant le nom du ficher d'un caractère `-'. Dans ce cas, on pourra obtenir de meilleures performances, mais l'on risque de perdre des informations en cas d'arrêt brutal du système.
Console
Dans le cas où le fichier mentionné serait une console virtuelle (/dev/tty0, /dev/tty1, etc), les messages seront écris à l'écran directement.
Machine distante
syslogd permet d'envoyer les messages sur une autre machine qui utilise également syslogd. Il suffit pour cela de donner le nom de la machine distante prefixée par un caractère @. Cette fonctionnalité est très pratique lorsqu'il y a plusieurs machines Linux sur le même réseau local et permet de diminuer le temps nécessaire à l'administration système. Notez cependant que pour que syslog accepte de recevoir des messages d'une machine distante, on doit le lancer avec le paramètre -r. D'autre part, syslog n'enverra pas sur une autre machine un message qu'il a déjà reçu d'une machine distante dans le but d'éviter une boucle infinie en cas de problème dans la configuration. Pour autoriser la transmission d'un message déjà reçu d'une autre machine, syslogd doit avoir été lancé avec le paramètre -h. Les paramètres -l et -s peuvent également être utilisés pour spécifier (respectivement) une liste de noms de machines ou de noms de domaines pour lesquels on accepte les messages.
auth.* @serveur
La règle précédente envoie tous les messages relatifs à l'authentification et à la sécurité sur la machine serveur.
Liste d'utilisateurs
Dans le cas où un message critique est émis, il est important que l'administrateur ou les autres utilisateurs soient avertis immédiatement. syslogd permet d'avertir une liste d'utilisateurs s'ils sont connectés sur la machine via la commande write (1). Pour cela, il suffit de donner la liste des logins des utilisateurs concernés.
*.crit;*.alert root,vincent
Si le message est vraiment extrêmement important (priorité: emerg), il est crucial de prévenir tous les utilisateurs connectés pour les avertir que quelque chose d'anormal est en train ou vient d'arriver au système. Si l'on spécifie une étoile comme action, le message sera envoyé à tous les utilisateurs via la commande wall (1) :
*.emerg
Tubes nommés
Il existe enfin une dernière possibilité qui consiste à envoyer les messages dans un tube nommé (en anglais : fifo). Ceux-ci peuvent être utilisés comme destination à condition de préfixer leur nom par le caractère `|'.
Cette méthode est principalement utilisée en conjonction avec l'utilitaire xconsole. Pour l'essayer, vous devez d'abord créer le tube nommé /dev/xconsole s'il n'existe pas déjà sur votre système. Ensuite, modifiez votre fichier /etc/syslog.conf pour que certains messages soient envoyés dans ce tube. Pour tester, la ligne suivante fera l'affaire (ajoutez-la tout simplement à la fin de votre fichier /etc/syslog.conf) :
*.* | /dev/xconsole
Maintenant, il ne vous reste plus qu'à relancer syslogd (killall -HUP syslogd), puis à lancer l'application xconsole : xconsole -file /dev/xconsole. A partir de là, vous devriez voir tous les messages systèmes s'afficher dans la fenêtre au fur et à mesure qu'ils surviennent.
Revenons un instant sur la syntaxe utilisée pour décrire le type de message.
Alors que mail.info désigne les messages issus du système de mail ayant une priorité supérieure ou égale à info, mail.=info désigne seulement les messages dont la priorité est exactement info. Inversement, mail.!=info désigne tous les messages venant du système du mail à l'exception de ceux ayant la priorité info. Enfin, mail.!info désigne les messages dont la priorité est strictement inférieure à info. Voici un exemple plus concret.
Les lignes suivantes représentent un bon compromis pour stocker les messages du noyau : tous les messages sont stockés dans le fichier /var/log/kernel. Les messages de priorité critique sont envoyés sur la console ainsi que sur la machine `serveur'. D'autre part, les messages d'information sont stockés à part dans le fichier /var/log/kernel-info.
kern.* /var/log/kernel kern.crit @serveur kern.crit /dev/console kern.info;kern.!err /var/log/kernel-info
La ligne qui suit permet de stocker des messages d'information à l'exception de ceux venant du mail et des news dans le fichier /var/log/messages :
*.=info;mail,news.none /var/log/messages
Pour tester votre configuration, l'utilitaire logger pourra vous être utile. Celui-ci permet d'envoyer à syslog une chaîne de caractères. Dans le cas de figure classique, on l'utilise de la manière suivante :
logger -t mon-programme -p mail.debug 'mon message'
syslog pour le programmeur
Pour les programmeurs, le service syslog est très utile pour, par exemple, aider au débogage d'un programme qui tourne en tâche de fond.
En C, seules trois fonctions suffisent à utiliser le service syslog : openlog et closelog, qui servent respectivement à commencer et terminer l'utilisation du service, et la fonction syslog, qui permet d'envoyer des messages. Voyons cela avec un petit exemple :
#include <syslog.h> char *log="mon-programme"; int main(int argc, char **argv) { openlog(log, LOG_CONS|LOG_PID, LOG_LOCAL7); syslog(LOG_DEBUG, "Hello, world!"); closelog(); return 0; }
Lorsqu'il sera exécuté, ce programme ajoutera un message de la forme suivante à l'endroit indiqué par la configuration de syslogd.
Lun 25 12:04:35 vince mon-programme: Hello, world!
Examinons plus en détail le mode de fonctionnement des trois fonctions mises en oeuvre.
La fonction openlog s'utilise avec 3 paramètres. Le premier est une chaîne de caractères qui sera ajoutée après le nom de la machine pour identifier le programme générant les messages. Le deuxième est une liste d'options modifiant le comportement des écritures. Plusieurs options peuvent être assemblées grâce à l'opérateur `|'. Les 4 options disponibles sont :
LOG_CONS : Si une erreur survient lors de l'envoi du message à syslogd, le message est écrit sur la console.
LOG_NDELAY : La connexion avec le programme syslog est faite dès l'appel de openlog au lieu d'être délayée au premier appel
de syslog.
LOG_PERROR : Les messages seront également écrits sur stderr.
LOG_PID : Le numéro du processus produisant le message est ajouté au message (juste après le nom du programme).
Le troisième paramètre indique le service à utiliser. Celui-ci est écrit en majuscules et préfixé par la chaîne `LOG_'.
`mail' devient ainsi `LOG_MAIL', etc.
La fonction syslog ne comporte quant à elle que deux paramètres. Le premier est la priorité du message (notée en majuscule, préfixée par `LOG_' tout comme pour les services) et le deuxième est le message lui-même. La fonction closelog termine simplement la liaison avec le programme syslogd, et n'utilise aucun paramètre.
Il existe également une interface Perl pour le service syslog, via le module Sys::Syslog. Utilisez la commande `perldoc Sys::Syslog' pour obtenir plus d'informations à ce sujet.
A ce stade, le service syslog ne devrait plus avoir aucun secret pour vous. N'hésitez pas à en profiter pour personnaliser la configuration de votre /etc/syslog.conf en fonction de vos besoins.