Grundlegendes zur Protokollierung unter Linux

62

Wie ich verstehe, protokolliert der Linux-Kernel in /proc/kmsgDatei (meist hardwarebezogene Meldungen) und /dev/logSocket? Irgendwo anders? Können auch andere Anwendungen Nachrichten an /proc/kmsgoder senden /dev/log? Last but not least, bin ich richtig , dass es der Syslog - Daemon ( rsyslog , syslog-ng ) , die Nachrichten von diesen zwei Stellen überprüft und verteilt dann diejenigen auf verschiedene Dateien wie /var/log/messagesoder /var/log/kern.logoder sogar zentralen syslog - Server?

Martin
quelle

Antworten:

81

Vereinfacht geht es ungefähr so:

Der Kernel protokolliert Nachrichten (unter Verwendung der printk()Funktion) in einem Ringpuffer im Kernelraum. Diese Nachrichten werden User-Space-Anwendungen auf zwei Arten zur Verfügung gestellt: über die /proc/kmsgDatei (sofern diese bereitgestellt /procist) und über den sys_syslogSyscall.

Es gibt zwei Hauptanwendungen, die den Ringpuffer des Kernels lesen (und bis zu einem gewissen Grad steuern können): dmesg(1)und klogd(8). Ersteres soll auf Anforderung von Benutzern ausgeführt werden, um den Inhalt des Ringpuffers zu drucken. Letzterer ist ein Daemon, der die Nachrichten liest /proc/kmsg(oder aufruft sys_syslog, wenn er /procnicht angehängt ist) und sie an syslogd(8)oder an die Konsole sendet . Das deckt die Kernelseite ab.

Im Benutzerraum gibt es syslogd(8). Dies ist ein Daemon, der eine Reihe von UNIX-Domain-Sockets überwacht (hauptsächlich /dev/log, aber auch andere können konfiguriert werden), und optional den UDP-Port 514 für Nachrichten. Es empfängt auch Nachrichten von klogd(8)( syslogd(8)interessiert sich nicht dafür /proc/kmsg). Anschließend schreibt er diese Nachrichten in einige Dateien /logoder in Named Pipes oder sendet sie an einige Remote-Hosts (über das syslogProtokoll auf UDP-Port 514), wie in konfiguriert /etc/syslog.conf.

User-Space-Anwendungen verwenden normalerweise die libcFunktion syslog(3)zum Protokollieren von Nachrichten. libcSendet diese Nachrichten an den UNIX-Domänen-Socket /dev/log(von dem sie gelesen werden syslogd(8)). Wenn jedoch eine Anwendung ausgeführt wird, werden chroot(2)die Nachrichten möglicherweise auf andere Sockets geschrieben, z /var/named/dev/log. Es ist natürlich wichtig, dass die Anwendungen, die diese Protokolle senden, syslogd(8)den Speicherort dieser Sockets festlegen. Aus diesem Grund syslogd(8)kann so konfiguriert werden, dass neben dem Standard weitere Sockets abgehört werden /dev/log.

Schließlich ist das syslogProtokoll nur ein Datagrammprotokoll. Nichts hindert eine Anwendung daran, Syslog-Datagramme an einen UNIX-Domänen-Socket zu senden (vorausgesetzt, seine Anmeldeinformationen ermöglichen das Öffnen des Sockets), wodurch die syslog(3)Funktion libcvollständig umgangen wird . Wenn die Datagramme korrekt formatiert sind, syslogd(8)können Sie sie so verwenden, als ob die Nachrichten durchgeschickt würden syslog(3).

Natürlich deckt das Obige nur die "klassische" Protokollierungstheorie ab. Andere Daemons (wie rsyslogund syslog-ng, wie Sie bereits erwähnt haben) können die Ebene ersetzen syslogd(8)und alle möglichen raffinierten Aufgaben ausführen, z. B. Nachrichten über verschlüsselte TCP-Verbindungen an Remote-Hosts senden, hochauflösende Zeitstempel bereitstellen usw. Und es gibt auch systemdeine langsame Phagozytose des UNIX-Teils von Linux. systemdhat seine eigenen Protokollierungsmechanismen, aber diese Geschichte müsste von jemand anderem erzählt werden. :)

Unterschiede zur * BSD-Welt:

Auf * BSD gibt es keine klogd(8)und /procsie existieren entweder nicht (auf OpenBSD) oder sind größtenteils veraltet (auf FreeBSD und NetBSD). syslogd(8)Kernel liest Nachrichten aus dem Zeichengerät /dev/klogund dmesg(1)verwendet /dev/kmemKernel Namen zu entschlüsseln. Nur OpenBSD hat eine /dev/log. FreeBSD verwendet zwei UNIX-Domain-Sockets /var/run/logund var/rub/logprivstattdessen hat NetBSD einen /var/run/log.

lcd047
quelle
3
nit: rsyslog ist jetzt populärer (Standard für Fedora, Debian) und verwendet kein separates klogd. Sieht so aus, als würde syslog-ng dies auch nicht tun.
Sourcejedi
@sourcejedi Ich habe Linux seit einigen Jahren rsyslognicht mehr so ​​genau verfolgt, aber IIRC wird nicht verwendet, klogd(8)weil seine Wurzeln weit zurückliegen, und nicht, weil es kürzlich eine explizite Entscheidung getroffen hat , es zu beseitigen . Mein Gedächtnis kann zwar ausfallen. Wie gesagt, ich habe nur versucht, die "klassische" Protokollierung zu behandeln.
lcd047
1
@ lcd047, @sourcejedi, Danke für die Antworten! Ich hatte ein Debian 7-System mit dem rsyslogdLaufen und ein Ubuntu 12.04 mit dem syslog-ngLaufen und beide hatten die Datei /proc/kmsgoffen lsof, dh sie klogdwurden nicht verwendet. Eine andere interessante Sache, die mir aufgefallen ist, ist, dass Logmeldungen in einer /proc/kmsgDatei gespeichert werden, wenn kein Syslog-Daemon läuft und man diese zum Beispiel mit einem catTexteditor anzeigen kann . Sie können diese Nachrichten jedoch nur einmal anzeigen, da sie nach dem Anzeigen nicht mehr angezeigt werden. Last but not least löscht dmesgdas Ausführen nicht den Inhalt der /proc/kmsgDatei.
Martin
1
@Martin /proc/kmsgist keine reguläre Datei, da ist nichts "gespeichert", sondern nur eine Ansicht des Ringpuffers des Kernels. Sie können es mit catgenau lesen, weil Sie kein klogd(8)Laufen haben (sollten Sie laufen klogd(8), cat /proc/kmsgwürde blockieren). dmesg(1)Liest Nachrichten von /dev/kmsganstatt /proc/kmsg; und es kann auch den Puffer löschen, wenn Sie es sagen.
lcd047
1
systemd has its own logging mechanisms, but that story would have to be told by somebody else. :)- Bitte sagen Sie, Sie haben Talent :-)
Flavius
51

Die andere Antwort erklärt, wie der Autor sagt, "klassische Protokollierung" unter Linux. So funktioniert das heutzutage in vielen Systemen nicht mehr.

Der Kernel

Die Kernelmechanismen haben sich geändert.

Der Kernel generiert eine Ausgabe in einen In-Memory-Puffer. Anwendungssoftware kann auf zwei Arten darauf zugreifen. Das Protokollierungssubsystem greift normalerweise als benanntes Pseudo-FIFO darauf zu /proc/kmsg. Diese Quelle von Protokollinformationen kann nicht für Protokollleser verwendet werden, da sie nur einmal gelesen werden. Wenn mehrere Prozesse es gemeinsam nutzen, erhält jeder nur einen Teil des Kernel-Protokolldatenstroms. Es ist auch schreibgeschützt.

Die andere Möglichkeit, darauf zuzugreifen, ist das neuere /dev/kmsgZeichengerät. Dies ist eine Lese- / Schreibschnittstelle, die von mehreren Clientprozessen gemeinsam genutzt werden kann. Wenn mehrere Prozesse es gemeinsam nutzen, lesen sie alle denselben vollständigen Datenstrom, ohne voneinander betroffen zu sein. Wenn sie es für den Schreibzugriff öffnen, können sie auch Nachrichten in den Protokolldatenstrom des Kernels einfügen, als wären sie vom Kernel generiert worden.

/proc/kmsgund /dev/kmsggeben Sie Protokolldaten in einer Nicht-RFC-5424-Form an.

Anwendungen

Anwendungen haben sich geändert.

Die syslog()Hauptfunktion der GNU C-Bibliothek versucht, eine Verbindung zu einem AF_LOCALDatagramm-Socket mit dem Namen herzustellen /dev/logund darin Protokolleinträge zu schreiben. (Die Funktion der BSD C-Bibliothek syslog()verwendet heutzutage /var/run/logals Socket-Namen und versucht es /var/run/logprivzuerst.) Anwendungen können natürlich ihren eigenen Code haben, um dies direkt zu tun. Die Bibliotheksfunktion ist nur Code (zum Öffnen, Verbinden, Schreiben und Schließen eines Sockets), der im eigenen Prozesskontext der Anwendung ausgeführt wird.

Anwendungen können RFC 5424-Nachrichten auch über UDP an einen lokalen RFC 5426-Server senden, wenn auf dem Computer ein AF_INET/ AF_INET6datagram-Socket abgehört wird.

Dank des Drucks der daemontools-Welt in den letzten zwei Jahrzehnten unterstützen viele Daemons die Ausführung in einem Modus, in dem sie nicht die GNU syslog()C-Bibliotheksfunktion oder UDP-Sockets verwenden, sondern nur ihre Protokolldaten in den Standardfehler ausspucken gewöhnliche Unix-Mode.

Log-Management mit nosh und der daemontools-Familie im Allgemeinen

Mit der Toolset-Familie von daemontools ist die Protokollierung sehr flexibel. Im Allgemeinen ist die Idee für die ganze Familie, dass jedem "Haupt" -Daemon ein "Protokoll" -Daemon zugeordnet ist. "main" -Dämonen arbeiten genau wie Nicht-Dämonen-Prozesse und schreiben ihre Protokollnachrichten in Standardfehler (oder Standardausgabe), die das Service-Management-Subsystem über eine Pipe verbunden hat (die offengehalten wird, damit Protokolldaten nicht verloren gehen) einen Neustart des Dienstes) an die Standardeingabe des "Logging" -Daemon.

Alle "Protokollierungs" -Dämonen führen ein Programm aus, das sich irgendwo protokolliert . Im Allgemeinen ist dieses Programm etwas wie multilogoder cyclogdass liest aus der Standardeingabe und schreibt (Nanosekunde timestamped) Protokolldateien in einem strengen Größe bedeckte, automatisch gedreht, exklusiver Schreib, Verzeichnis. Im Allgemeinen laufen diese Dæmons auch alle unter der Ägide einzelner dedizierter nichtprivilegierter Benutzerkonten.

Man hat also ein weitgehend verteiltes Protokollierungssystem, bei dem die Protokolldaten jedes Dienstes separat verarbeitet werden.

Man kann so etwas wie laufen klogdoder syslogdoder rsyslogdunter einem daemontools-Familie Service - Management. Aber die daemontools-Welt hat vor vielen Jahren erkannt, dass sich die Service-Management-Struktur mit "Protokollierungs" -Dämonen sehr gut dazu eignet, Dinge auf einfachere Weise zu erledigen. Es ist nicht erforderlich, alle Protokolldatenströme in einen einzigen Mischmasch zu fächern, die Protokolldaten zu analysieren und die Datenströme dann wieder herauszufächern, um die Protokolldateien zu trennen. und dann (in einigen Fällen) einen unzuverlässigen externen Stammdrehmechanismus an der Seite festschrauben. Die daemontools-Familienstruktur als Teil der Standardprotokollverwaltung führt bereits die Protokollrotation, das Schreiben von Protokolldateien und die Datenstromtrennung durch.

Darüber hinaus bedeutet das Kettenmodell des Verwerfens von Berechtigungen mit allen Diensten gemeinsamen Tools, dass die Protokollierungsprogramme keine Superuser-Berechtigungen benötigen. und das UCSPI-Modell bedeutet, dass sie sich nur um Unterschiede wie Stream- und Datagrammtransport kümmern müssen.

Das nosh-Toolset veranschaulicht dies. Während man kann laufen rsyslogdunter ihm, aus dem Kasten heraus und verwalten nur Kernel, /run/logund UDP - log - Eingang in der alten Art und Weise; es auch bietet mehr „daemontools native“ Möglichkeiten, diese Dinge Anmeldung:

  • Ein klogdDienst, /proc/kmsgder diesen Protokolldatenstrom liest und einfach in seinen Standardfehler schreibt. Dies geschieht mit einem einfachen Programm namens klog-read. Das zugehörige Protokollierungs-Daemon füttert den Protokolldatenstrom bei seiner Standardeingabe in ein /var/log/sv/klogdProtokollverzeichnis.
  • Ein local-syslog-readDienst, der Datagramme aus /dev/log( /run/logauf den BSDs) liest und diesen Protokolldatenstrom einfach in seinen Standardfehler schreibt. Dies geschieht durch ein Programm namens syslog-read. Das zugehörige Protokollierungs-Daemon füttert den Protokolldatenstrom bei seiner Standardeingabe in ein /var/log/sv/local-syslog-readProtokollverzeichnis.
  • Ein udp-syslog-readDienst, der den UDP-Syslog-Port überwacht, liest, was an ihn gesendet wird, und diesen Protokolldatenstrom einfach auf seinen Standardfehler schreibt. Wieder ist das Programm syslog-read. Das zugehörige Protokollierungs-Daemon füttert den Protokolldatenstrom bei seiner Standardeingabe in ein /var/log/sv/udp-syslog-readProtokollverzeichnis.
  • (Auf den BSDs) Ein local-priv-syslog-readDienst, der Datagramme ausliest /run/logprivund diesen Protokolldatenstrom einfach in seinen Standardfehler schreibt. Wieder ist das Programm syslog-read. Das zugehörige Protokollierungs-Daemon füttert den Protokolldatenstrom bei seiner Standardeingabe in ein /var/log/sv/local-priv-syslog-readProtokollverzeichnis.

Das Toolset enthält auch ein export-to-rsyslogTool, mit dem ein oder mehrere Protokollverzeichnisse überwacht werden können (mithilfe eines Systems von nicht aufdringlichen Protokollcursorn ) und neue Einträge in RFC 5424-Form über das Netzwerk an einen festgelegten RFC 5426-Server gesendet werden können.

Protokollverwaltung mit systemd

systemd verfügt über ein einziges monolithisches Protokollverwaltungsprogramm systemd-journald. Dies wird als Dienst ausgeführt, der von systemd verwaltet wird.

  • Es liest /dev/kmsgfür Kernel-Protokolldaten.
  • Es liest /dev/log(ein symbolischer Link zu /run/systemd/journal/dev-log) für Anwendungsprotokolldaten aus der syslog()Funktion der GNU C-Bibliothek .
  • Es überwacht den AF_LOCALStream-Socket auf /run/systemd/journal/stdoutProtokolldaten, die von systemd-verwalteten Diensten stammen.
  • Er überwacht den AF_LOCALDatagramm-Socket auf /run/systemd/journal/socketProtokolldaten, die von Programmen stammen, die das systemspezifische Journalprotokoll sprechen (z. B. sd_journal_sendv()et al.).
  • Es mischt diese alle zusammen.
  • Es werden systemweite und benutzerspezifische Journaldateien in /run/log/journal/oder geschrieben /var/log/journal/.
  • Wenn es sich (als Client) mit einem AF_LOCALDatagramm-Socket verbinden /run/systemd/journal/syslogkann, schreibt es dort Journaldaten, wenn die Weiterleitung an Syslog konfiguriert ist.
  • Wenn konfiguriert, werden Journaldaten mithilfe des beschreibbaren /dev/kmsgMechanismus in den Kernel-Puffer geschrieben .
  • Wenn konfiguriert, werden Journaldaten auch auf die Terminals und das Konsolengerät geschrieben.

Systemweit passieren schlimme Dinge, wenn dieses Programm abstürzt oder der Dienst beendet wird.

systemd selbst sorgt dafür, dass die Standardausgaben und Fehler von (einigen) Diensten an den /run/systemd/journal/stdoutSocket angehängt werden. Daher wird die Ausgabe von Dæmons, die auf normale Weise als Standardfehler protokolliert werden, an das Journal gesendet.

Dies ersetzt vollständig klogd, syslogd, syslog-ng und rsyslogd.

Diese müssen nun systemspezifisch sein. Auf einem systemd-System werden sie nicht zum Server-Ende /dev/log. Stattdessen verfolgen sie einen von zwei Ansätzen:

  • Sie werden zum Server-Ende von /run/systemd/journal/syslog, auf dem (wenn Sie sich erinnern) systemd-journaldversucht wird, eine Verbindung herzustellen und Journaldaten zu schreiben. Vor ein paar Jahren hätte man dafür die imuxsockEingabemethode von rsyslogd konfiguriert .
  • Sie lesen direkt aus dem systemd-Journal, wobei sie eine systemd-spezifische Bibliothek verwenden, die das binäre Journalformat versteht und die Journaldateien und das Verzeichnis auf neue Einträge überwachen kann, die hinzugefügt werden. Heutzutage konfiguriert man dazu die imjournalEingabemethode von rsyslogd .
JdeBP
quelle