journalctl für Otto-Normal-Linuxer

Hinweis: In dem Thema journalctl für Otto-Normal-Linuxer gibt es 4 Antworten. Der letzte Beitrag () befindet sich ganz unten auf dieser Seite.
  • Kleiner großer Überblick über die Loggingszene
    Seit systemd gibt es auch journald.
    Genauso so, wie man seitdem systemd mit systemctl befehligt, juckt, pardon: guckt, man Systemlogs jetzt mit journalctl an.
    Ein generelles Mistverständnis®™ ist, dass viele glauben, dieses "Journal" wäre tatsächlich ein seit systemd komplett neues Systemlogprogramm. Dem ist nicht so.
    Es gibt schon immer mindestens zwei "Systemlogger" auf einem Linuxsystem. (Also jedenfalls, seit Logger Standard wurden; in ganz grauer Vorzeit kannte man solche Kontrollmechanismen gar nicht.)
    Im Hintergrund arbeiten normalerweise zwei Logger. Einer für den Kernel, eine für das "Userland". Auch heute muss das nicht zwingend journald sein. Tatsächlich war es bei openSUSE in der Einführungszeit von systemd immr noch rsyslogd, der das Logging übernahm und der auch heute noch in vielen Unices und Linuces für das Loggen zuständig ist. Dieses probate ausgereifte Tool kann weit über 1 Millionen Logevents pro Sekunde verarbeiten. Is schon ma ne Hausnummer.
    Bei openSUSE haben wir ja jetzt journald. Beide bedienen sich übrigens eines präzise definierten Protokolls, nämlich des Syslogprotokolls. Und das ist so sauber (mit kleinen Sicherheitschwächen) definiert, dass man auf JEDEM Linuxsystem ALLE Logevents auch über das Netzwerk zu irgendeinem andern Linuxlogger senden kann, statt sie in lokale Dateien zu speichern.
    Egal. Unter openSUSE haben wir es heute im wesentlichen mit zwei Programmen zu tun, wenn wir vom Loggen reden.
    Einmal die Kernel Logmeldungen und dann die "anderen".


    Was ist der Unterschied zwischen Kernel-Logmeldungen und "normalen" Log-Meldungen?
    Jede CPU kann "Betriebsfehler" melden und tut das auch ständig. Diese Meldungen betreffen natürlich die CPU selbst, aber auch ALLE sich direkt auf diesem Board befindlichen Geräte. Dort verbaute USB Teile zählen nur sehr bedingt dazu. Aber USB ist eh eine komplett andere Welt. Es ist nicht einmal sicher, ob ein USB- Hub wirklich zum eigentliche Board gehört. Egal. PCI gehört auf jeden Fall dazu. (Und an einen PCI Hub sind alle virtuellen, oder physisch vorhandenen USB-Hubs angebunden -sei es direkt, oder indirekt.)
    Die Meldungen der CPU -und somit des Kernels- haben einen Namen. Da es Fehlerzustände im Prozessor und auf dem Motherboard sind, tragen sie den einleuchtenden Namen "Machine Check Exception". Das mcelog ist die moderne Art die Kernellogmeldungen in das gesamte Systemlog zu schreiben. Wir erinnern uns: Das Loggen einer Linuxkiste besteht aus zwei Teilen!
    Auf einem modernen openSUSE System läuft IMMER ein mcelog. Ein schlichtes ps ax -o pid,cmd | grep mcelog zeigt das. Und man mcelog erklärt es.
    Wer mit mcelog wirklich arbeiten mag, was man wirklich kann, lese auf der Website von mcelog weiter.


    Natürlich werden alle Logmeldungen zusammengewürfelt. Es würde anders auch wenig Sinn machen - ist es doch das Ziel in egal welcher Konfiguration ein konsistentes, komplettes Log aller Aktivitäten gleich welcher Natur forensisch sicher zu erhalten. Egal auf welcher Kiste.


    Und was sind jetzt die "normalen" Log-Meldungen?
    Ganz einfach: alle anderen.
    Du kannst als normale Userin selbstverständlich auch in das Systemlog schreiben. Jederzeit. Ein schlichtes logger scheiße, das geht ja! schreibt in das Systemlog genau diesen Satz. Prüfe das, indem du als normaler User in eine Konsole diesen Unsinn eingibst. Wenn du damit fertig bist, gib einfach journalctl -r ein. Et voilà!
    -r bewirkt die reverse Ausgabe der Meldungen - wohl die nützlichste und am häufigsten verwendete Option.


    Damals, wie heute unter systemd wurden alle Meldungen in das Verzeichniss /var/log geschrieben. Also fast alle. Und das nicht einmal immer. Dass Meldungen dort gespeichert werden, ist lediglich eine Konvention. Nichts und niemand diktiert eine solche Notwendigkeit. Aber es ist natürlich sinnvoll, sich an an solche Konventionen zu halten.


    Die Wirklichkeit ist natürlich auch beim Linuxloggen wesentlich komplexer. Und alles kann man konfigurieren, wie man lustig ist. Selbstverständlich kann man auch die Logs einer Maschine auf einem anderen via Netzwerk schreiben. (Ab openSUSE 15 gibt es sogar ein Paket namens systemd-journal-remote, das diese Möglichkeit leicht verwaltbar macht. Für ältere Versionen muss man etwas mehr rumbasteln und einen "alten" Logdienst noch zusätzlich einbinden)


    Auch die Rechte sind beim Loggen ein wichtiger Aspekt. Schließlich prallen da Systemdienste, Serverprogramme und Usergeschwätz aufeinander.

  • Teil 2


    Deshalb erst ein grober Überblick über das Loggen bei openSUSE
    Anfangs wurden die Logs nur nach /run gespeichert, mit dem Effekt, dass die Logs nach einem Neustart weg waren. Und tatsächlich wird im Betrieb auch dorthin geloggt.
    Man musste erst in die Konfigurationsdatei /etc/systemd/journald.conf den Eintrag Storage=persistent eintragen, wenn man seine Logs dauerhaft gespeichert sehen wollte. Heute macht der Standard Storage=auto das auch. (Es schadet natürlich nicht, wenn man diesen Eintrag händisch pflegt.)
    Mit man journald.conf kann man sich alle möglichen Einstellungen reinziehen und sich das Systemjounal dann nach Gusto einrichten.


    Und dann gibt es verschiedene Logs. Einmal das Systemlog, in das alle möglichen Systemereignisse protokolliert werden, und dann für jeden User ein persönliches Log. Falls der Defaulteintrag Splitmode=uid in der journald.conf nicht geändert wurde. Bei openSUSE muss man Root-Rechte haben, um wirklich alle Logeinträge lesen zu können. Ruft man als normaler User journalctl auf, so wird man auf diesen Umstand hingewiesen und nur die Logeinträge werden angezeigt, die der User selbst veranlasst hat. Z.B. als User ein logger hallo vorher eingegeben hat.


    Die Logfiles selbst finden sich per Default in /var/log/journal/<Rechner-UUID>. Diese "Rechner-UUID" korrekt "machine-id" ist eine hexadezimal UniversalUniqIDentification Zeichenfolge, also eine universell eindeutige Identifikation. (Wirklich eineindeutig sind diese UUIDs nicht, es können -rein theoretisch- Kollisionen auftreten). Solche ID- Strings finden in jedem Betriegssystem reichlich Verwendung, und selbstverständlich kann jeder User sich mit uuidgen (UUID GENerator) beliebig viele solcher UUIDs erzeugen. (man uuidgen erklärt die 4 Varianten)
    In diesem Verzeichnis liegen -je nach Konfiguration- Dateien, die dem Namesschema <wer><machine-id><id>.journal folgt. Das eigentliche Systemjournal heißt schlicht system.journal und die eines Users user-<uid>.journal (<uid> == Die UserID, wie sie das Standardtool id ausgibt). Die Zeichenkette zwischen user/system und dem abschließenden .journal werden durch die Logrotation und dem Sealing- Mechanismus gebildet. Das ist aber völlig egal, weil diese Dateien sowieso aus Performancegründen keine Textdateien, sondern binäre Dateien sind, womit sie für uns Looser ziemlich unlesbar bleiben.


    Das "Sealing" des Journals ist die Möglichkeit das Journal mit Prüfsummen anzureichern, die bei Standardkonfiguration, falls aktiviert, alle 15 Minuten in das Log geschrieben werden. Man gibt einmal den Befehl journalctl --setup-keys ein und erhält damit zwei Schlüssel. Den privaten speichert man in seiner Hosentasche, den anderen verwendet dann das Syslog zum konfigurierbar 15miütigen "sealen" des Logs. Der wird unter /var/log/journal/<machine-id>/fss (forwardsealingsecrecy ).
    Von da an hätte ein Hacker nur 15 Minuten Zeit seine Schweinereien aus dem Log zu löschen. Alle anderen Lösch- oder Änderungsaktionen fallen dann auf.
    Mit dem Befehl journalctl --verify --verify-key=<der private Schlüssel> prüft man dann gelegentlich das Log auf Inkonsistenzen.


    Weil, wie gesagt, diese Logfiles alle binär sind, nehmen wir das Tool journalctl und disen Dateienwust zu entfleddern und lesbar zu machen.


    Und da sind nur ein paar Optionen ausreichend, um das täglich Interessierende herauszulutschen.
    Die wichtigsten Option von JOURNALCTL sind:


    -r Damit werden die jüngsten Ereignisse zuerst angezeigt. Was ja das ist, was uns meistens interessiert. Was ist gerade passiert?
    -k Was hat der kernel an Meldungen gespuckt?
    -b Was ist seit dem letzten Boot passiert? Diese Option versteht eine BootID und einen Offset. Die BootID ist für uns Otto-Normal-Linuxer uninteressant. Die wird erst nötig, wenn man riesige Netze mit vielen Maschinen und Cluster verwaltet, oder wenn man mit chroot samt Kalt/Warmstart und Kernelreloads experimentiert. Uns genügt der Offset völlig. Ein -b1 zeigt den ältesten Bootvorgang an, der gerade noch im gesamten Journal vorhanden ist. Ein -b-0 den aktuellen, ein -b-1 ab dem vorletzten Boot usw. Ohne irgendetwas zeigt ein -b ebenfalls seit dem aktuellen Bootvorgang an.
    --since --until sind meine Lieblingsoptionen. Damit kann man einfach Zeiträume ganz hervorragend eingrenzen. Es ist ja immer die Menge an Information, die ermüdet. Das Format für beide Optionen, die man natürlich auch einzeln verwenden kann, ist einfach: "YYYY-MM-DD HH:MM:SS". Die Anführungszeichen sind nötig, WENN Leerzeichen in diesem String sind. Ein schlichtes --since 2018-01-01 braucht kein Quoting. Man kann die Angaben verkürzen, solange es eindeutig bleibt. Gebe ich nur --since 12:0 an, so erhalte ich alle Meldungen seit 12Uhr des heutigen Tages. Eine ganz prima Sache.
    --unit Damit beschränkt man die Ausgabe auf einen Teil von Logeinträgen, die von einem Dienst, oder Gerät stammen. Alle Möglichkeiten zeigt ein systemctl -a an. Eine scheinbar unendlich lange Liste solcher "Teile" erscheint.


    Da man alle Optionen beliebig mischen kann, kann man die Ausgabe also sehr leicht ohne grep und dergleichen auf das eingrenzen, was einen wirklich interessiert.
    journalctl --unit sshd --since 14:0 spuckt mir sofort aus, was mein SSH- Server seit heute 14Uhr getrieben hat.


    Man hat also enorme Möglichkeiten sein System anständig zu überwachen. Und auch selbst solche Logeinträge in seinen Scripten zu verwenden.
    Wenn hier noch einmal ein Script ohne UUIDs und Logeinträge auftaucht, wird es nach /dev/null gepiped! Jawohl!!
    Happy Logging!


    Anzumerken bleibt noch, dass ich mit diesem Text wirklich nur sehr oberflächlich das Thema "Linux Systemlog" angekratzt habe.
    Man kann daraus eine Wissenschaft machen. In großen Netzen kümmert sich ein auf das Logging spezialisiertes Team ausschließlich um das Logging.

  • Vielen Dank für deine Arbeit und dem damit verbundenen Zeitaufwand.
    Schon wieder sehr interessant; UND die wichtigsten Punkte sind auch zusammengefasst.
    Macht Spass, dieses zu lesen und sogar bei mir blieb schon das eine oder andere hängen.

    Für den Inhalt des Beitrages 120600 haftet ausdrücklich der jeweilige Autor: sterun

  • Vielen Dank für deine Arbeit und dem damit verbundenen Zeitaufwand.
    Schon wieder sehr interessant; UND die wichtigsten Punkte sind auch zusammengefasst.
    Macht Spass, dieses zu lesen und sogar bei mir blieb schon das eine oder andere hängen.

    kwt

    Für den Inhalt des Beitrages 120603 haftet ausdrücklich der jeweilige Autor: Kanonentux

  • Einen ganzen Monat habe ich gebraucht, um deine beschriebenen Basics zu verstehen.
    Jetzt möchte ich "journalctl" nicht mehr missen!
    Habe es meinen Vorstellungen angepasst und kann jetzt gezielt Einträge / Meldungen finden.
    Die Auswertungen zu verstehen ist jedoch eine neue Baustelle.


    SEHR mächtig - SEHR interessant!


    Wann kommt dein nächstes Howto?

    Für den Inhalt des Beitrages 124643 haftet ausdrücklich der jeweilige Autor: sterun