Comprendre la journalisation sous Linux

62

Si je comprends bien, les journaux du noyau Linux dans le /proc/kmsgfichier (principalement des messages liés au matériel) et /dev/logsocket? N'importe où ailleurs? Est-ce que d'autres applications peuvent également envoyer des messages à /proc/kmsgou /dev/log? Last but not least, Ai - je raison qu'il est le démon syslog ( rsyslog , syslog-ng ) les messages contrôles de ces deux endroits et distribue ensuite les divers fichiers comme /var/log/messagesou /var/log/kern.logou même serveur syslog central?

Martin
la source

Réponses:

81

Simplifié, ça ressemble plus ou moins à ça:

Le noyau enregistre les messages (à l'aide de la printk()fonction) dans un tampon circulaire dans l'espace du noyau. Ces messages sont mis à la disposition des applications utilisateur de deux manières: via le /proc/kmsgfichier (à condition qu'il /procsoit monté) et via l' sys_syslogappel système.

Il y a deux applications principales qui lisent (et, dans une certaine mesure, peuvent contrôler) la mémoire tampon circulaire du noyau: dmesg(1)et klogd(8). Le premier est destiné à être exécuté à la demande des utilisateurs, afin d’imprimer le contenu de la mémoire tampon circulaire. Ce dernier est un démon qui lit les messages de /proc/kmsg(ou les appels sys_syslog, s'il /procn'est pas monté) et les envoie à syslogd(8), ou à la console. Cela couvre le noyau.

Dans l'espace utilisateur, il y a syslogd(8). Il s'agit d'un démon qui écoute un certain nombre de sockets de domaine UNIX (principalement /dev/log, mais d'autres peuvent également être configurés), et éventuellement sur le port UDP 514 pour les messages. Il reçoit également des messages de klogd(8)( syslogd(8)ne s'en soucie pas /proc/kmsg). Il écrit ensuite ces messages dans certains fichiers /logou dans des canaux nommés, ou les envoie à des hôtes distants (via le syslogprotocole, sur le port UDP 514), comme configuré dans /etc/syslog.conf.

Les applications d’espace utilisateur utilisent normalement cette libcfonction syslog(3)pour consigner les messages. libcenvoie ces messages au socket de domaine UNIX /dev/log(où ils sont lus syslogd(8)), mais si une application est chroot(2)-ed, les messages risquent d'être écrits dans d'autres sockets, fi to /var/named/dev/log. Il est bien sûr essentiel pour les applications qui envoient ces journaux et syslogd(8)de s’entendre sur l’emplacement de ces sockets. Pour ces raisons, syslogd(8)peut être configuré pour écouter des sockets supplémentaires en dehors de la norme /dev/log.

Enfin, le syslogprotocole est juste un protocole de datagramme. Rien n'empêche une application d'envoyer des datagrammes Syslog à un socket de domaine UNIX (à condition que ses informations d'identification lui permettent d'ouvrir le socket), en contournant complètement la syslog(3)fonction libc. Si les datagrammes sont correctement formatés, vous syslogd(8)pouvez les utiliser comme si les messages avaient été envoyés syslog(3).

Bien entendu, ce qui précède ne couvre que la théorie "classique" de la journalisation. D'autres démons (tels que rsysloget syslog-ng, comme vous l'avez mentionné) peuvent remplacer la syslogd(8)requête standard et effectuer toutes sortes de choses astucieuses, comme envoyer des messages à des hôtes distants via des connexions TCP chiffrées, fournir des horodatages à haute résolution, etc. Et il y a aussi cela systemd, phagocytose lentement la partie UNIX de Linux. systemda ses propres mécanismes de journalisation, mais cette histoire devrait être racontée par quelqu'un d'autre. :)

Différences avec le monde * BSD:

Sur * BSD, il n’existe pas klogd(8), et /procn’existe pas (sous OpenBSD) ou est obsolète (sous FreeBSD et NetBSD). syslogd(8)lit les messages du noyau à partir du périphérique de caractères /dev/kloget les dmesg(1)utilise /dev/kmempour décoder les noms de noyaux. Seul OpenBSD a un /dev/log. FreeBSD utilise deux sockets de domaine UNIX /var/run/loget, à la var/rub/logprivplace, NetBSD en possède un /var/run/log.

lcd047
la source
3
nit: rsyslog est plus populaire maintenant (par défaut pour Fedora, Debian), et il n’utilise pas de klogd séparé. On dirait que syslog-ng ne le fait pas (de préférence).
sourcejedi
@sourcejedi Je n'ai pas suivi Linux de près depuis plus de quelques années maintenant, mais l'IIRC rsyslogne l'utilise pas klogd(8)parce que ses racines remontent à longtemps , pas parce qu'il a récemment pris la décision explicite de le supprimer. Ma mémoire peut échouer cependant. Quoi qu'il en soit, comme je l'ai dit, je n'essayais que de couvrir la journalisation "classique".
lcd047
1
@ lcd047, @sourcejedi, merci pour les réponses! J'avais un système Debian 7 en rsyslogdcours d' exécution et un système Ubuntu 12.04 en syslog-ngcours d' exécution; tous deux avaient un fichier /proc/kmsgouvert lsof, c'est- à -dire qu'ils klogdn'étaient pas utilisés. Une autre chose intéressante que j'ai remarquée est que les messages de journalisation sont stockés dans un /proc/kmsgfichier si aucun démon syslog n'est en cours d'exécution et que vous pouvez les afficher avec, par exemple, catun éditeur de texte. Cependant, il est uniquement possible de visualiser ces messages une seule fois car ils disparaissent après avoir été visualisés. Dernier point mais non le moindre, l'exécution dmesgn'efface pas le contenu du /proc/kmsgfichier.
Martin
1
@Martin /proc/kmsgn'est pas un fichier normal, il n'y a rien de "stocké" là-dedans, c'est juste une vue du tampon circulaire du noyau. Vous pouvez le lire avec catjustement parce que vous n'avez pas de klogd(8)course (si vous courez klogd(8), vous cat /proc/kmsgbloqueriez). dmesg(1)lit les messages de /dev/kmsgplutôt que de /proc/kmsg; et il peut aussi vider le tampon si vous le lui dites.
lcd047
1
systemd has its own logging mechanisms, but that story would have to be told by somebody else. :)- S'il te plaît, dis, tu as du talent :-)
Flavius ​​Le
51

L’autre réponse explique, comme le dit son auteur, la "journalisation classique" sous Linux. Ce n'est pas comme ça que les choses fonctionnent dans beaucoup de systèmes de nos jours.

Le noyau

Les mécanismes du noyau ont changé.

Le noyau génère une sortie dans une mémoire tampon en mémoire. Les logiciels d’application peuvent y accéder de deux manières. Le sous-système de journalisation y accède généralement sous la forme d'un pseudo-FIFO nommé /proc/kmsg. Cette source d'informations de journal ne peut pas être utilement partagée entre les lecteurs de journal, car elle est en lecture seule. Si plusieurs processus le partagent, ils ne reçoivent chacun qu'une partie du flux de données de journalisation du noyau. Il est également en lecture seule.

L’autre moyen d’y accéder est le plus récent /dev/kmsgdes appareils à caractères. Il s'agit d'une interface en lecture-écriture pouvant être partagée entre plusieurs processus client. Si plusieurs processus le partagent, ils lisent tous le même flux de données complet, non affecté les uns par les autres. S'ils l'ouvrent pour un accès en écriture, ils peuvent également injecter des messages dans le flux de journaux du noyau, comme s'ils étaient générés par le noyau.

/proc/kmsget /dev/kmsgfournir des données de journal sous une forme non-RFC-5424.

Applications

Les applications ont changé.

La syslog()fonction de la bibliothèque GNU C dans les principales tentatives de connexion à un AF_LOCALsocket de datagramme nommé /dev/loget d’écrire des entrées de journal dessus. (La syslog()fonction de la bibliothèque C BSD utilise actuellement le /var/run/lognom du socket et essaie en /var/run/logprivpremier.) Les applications peuvent bien sûr avoir leur propre code pour le faire directement. La fonction de bibliothèque consiste simplement en un code (pour ouvrir, connecter, écrire et fermer un socket) s'exécutant dans le propre contexte de processus de l'application, après tout.

Les applications peuvent également envoyer des messages RFC 5424 via UDP à un serveur RFC 5426 local, si celui-ci écoute sur un socket AF_INET/ AF_INET6datagramme de la machine.

Grâce à la pression exercée par le monde des daemontools au cours des deux dernières décennies, de nombreux démons prennent en charge le fonctionnement dans un mode dans lequel ils n’utilisent pas la syslog()fonction de bibliothèque GNU C, ni les sockets UDP, mais sèment simplement leurs données de journal en erreurs standard. mode Unix ordinaire.

la gestion des journaux avec nosh et la famille daemontools en général

Avec la famille de jeux d'outils daemontools, la journalisation offre une grande flexibilité. Mais en général, dans toute la famille, l’idée est que chaque démon "principal" est associé à un démon de "journalisation". Les démons "principaux" fonctionnent comme des processus non démons et écrivent leurs messages de consignation sur une erreur standard (ou une sortie standard), que le sous-système de gestion de services s’assure pour être connecté via un canal (qu’il maintient ouvert afin que les données de consignation ne soient pas perdues). redémarrage du service) à l’entrée standard du démon "enregistrement".

Tous les démons de "journalisation" exécutent un programme qui enregistre quelque part . Généralement, ce programme ressemble à quelque chose du genre multilogou cycloglit à partir de son entrée standard et écrit des fichiers journaux (horodatés à la nanoseconde) dans un répertoire strictement limité en taille, en rotation automatique, en écriture exclusive. De manière générale, ces démons sont tous gérés par des comptes d’utilisateur individuels non privilégiés.

On se retrouve donc avec un système de journalisation largement distribué, les données de journalisation de chaque service étant traitées séparément.

Un peut exécuter quelque chose comme klogdou syslogdou rsyslogdsous gestion des services daemontools familiale. Mais le monde daemontools s’est rendu compte, il y a de nombreuses années, que la structure de gestion des services avec "journalisation" de dmons se prête très bien à la simplification des choses. Il n'est pas nécessaire de regrouper tous les flux de journaux en un seul mish-mash géant, d'analyser les données du journal, puis de réanimer les flux afin de séparer les fichiers journaux. et puis (dans certains cas) boulonnez un mécanisme de rotation des billes externe non fiable sur le côté. La structure daemontools-family dans le cadre de la gestion standard des journaux effectue déjà la rotation des journaux, l'écriture du fichier journal et la séparation des flux.

De plus: le modèle de chargement en chaîne consistant à supprimer des privilèges avec des outils communs à tous les services signifie que les programmes de journalisation n'ont pas besoin de privilèges de superutilisateur; et le modèle UCSPI signifie qu’ils ne doivent s’occuper que des différences telles que le transport de flux par rapport au datagramme.

Nosh Tools en est un exemple. Bien que l’on puisse s’exécuter rsyslogdsous la boîte, et ne gérer que le noyau /run/loget les entrées de journal UDP de la manière habituelle; il fournit également plus de moyens "natifs daemontools" de journaliser ces choses:

  • un klogdservice qui lit /proc/kmsget écrit simplement ce flux de journal sur son erreur standard. Ceci est fait par un programme simple nommé klog-read. Le démon de journalisation associé alimente le flux de journalisation sur son entrée standard dans un /var/log/sv/klogdrépertoire de journalisation.
  • un local-syslog-readservice qui lit les datagrammes depuis /dev/log( /run/logsur les BSD) et écrit simplement ce flux de consignation dans son erreur standard. Ceci est fait par un programme nommé syslog-read. Le démon de journalisation associé alimente le flux de journalisation sur son entrée standard dans un /var/log/sv/local-syslog-readrépertoire de journalisation.
  • un udp-syslog-readservice qui écoute sur le port UDP Syslog, lit ce qui lui est envoyé et écrit simplement ce flux de consignation dans son erreur standard. Encore une fois, le programme est syslog-read. Le démon de journalisation associé alimente le flux de journalisation sur son entrée standard dans un /var/log/sv/udp-syslog-readrépertoire de journalisation.
  • (sur les BSD) un local-priv-syslog-readservice qui lit les datagrammes /run/logprivet écrit simplement ce flux de consignation dans son erreur standard. Encore une fois, le programme est syslog-read. Le démon de journalisation associé alimente le flux de journalisation sur son entrée standard dans un /var/log/sv/local-priv-syslog-readrépertoire de journalisation.

Le jeu d'outils est également fourni avec un export-to-rsyslogoutil qui peut surveiller un ou plusieurs répertoires de journal (à l'aide d'un système de curseurs de journal non intrusifs ) et envoyer de nouvelles entrées au format RFC 5424 sur le réseau à un serveur désigné RFC 5426.

gestion des journaux avec systemd

systemd a un seul programme de gestion des journaux monolithique systemd-journald. Cela fonctionne comme un service géré par systemd.

  • Il lit /dev/kmsgles données du journal du noyau.
  • Il lit /dev/log(un lien symbolique vers /run/systemd/journal/dev-log) les données du journal de l'application à partir de la syslog()fonction de la bibliothèque GNU C.
  • Il écoute sur le AF_LOCALsocket de flux /run/systemd/journal/stdoutles données de journal provenant de services gérés par systemd.
  • Il écoute sur le AF_LOCALsocket de datagramme /run/systemd/journal/socketles données de journal provenant de programmes qui parlent le protocole de journal spécifique à systemd (c.-à-d. sd_journal_sendv()Et al.).
  • Il les mélange tous ensemble.
  • Il écrit dans un ensemble de fichiers de journaux système et par utilisateur, dans /run/log/journal/ou /var/log/journal/.
  • S'il peut se connecter (en tant que client) à un AF_LOCALsocket de datagramme, /run/systemd/journal/syslogil y écrit les données du journal, si la transmission à syslog est configurée.
  • S'il est configuré, il écrit les données du journal dans la mémoire tampon du noyau à l'aide du /dev/kmsgmécanisme d' écriture .
  • S'il est configuré, il écrit également les données du journal sur les terminaux et la console.

De mauvaises choses se produisent au niveau du système si ce programme se bloque ou si le service est arrêté.

systemd lui-même fait en sorte que les sorties standard et les erreurs de (certains) services soient attachées au /run/systemd/journal/stdoutsocket. Ainsi, les démons qui se connectent à l’erreur standard de manière normale voient leur sortie envoyée au journal.

Cela supplante complètement klogd, syslogd, syslog-ng et rsyslogd.

Celles-ci doivent maintenant être spécifiques à systemd. Sur un système, ils ne deviennent pas le serveur /dev/log. Au lieu de cela, ils adoptent l'une des deux approches suivantes:

  • Ils deviennent la fin du serveur /run/systemd/journal/syslog, à laquelle (si vous vous en souvenez) systemd-journaldtente de se connecter et d’écrire des données de journal. Il y a quelques années, on aurait configuré la imuxsockméthode d'entrée de rsyslogd pour le faire.
  • Ils lisent directement à partir du journal systemd, en utilisant une bibliothèque spécifique à systemd qui comprend le format du journal binaire et qui peut surveiller les fichiers journal et le répertoire des nouvelles entrées ajoutées. De nos jours, on configure la imjournalméthode d'entrée de rsyslogd pour le faire.
JdeBP
la source