12.7    »systemd« mit »journalctl«

Zusammen mit dem systemd kommt das Kommando journalctl, mit dem Sie die Log-Dateien des systemd auslesen können. Die Informationen, die der systemd sammelt, werden immer binär gespeichert, wobei systemd nicht nur für das Logging verantwortlich ist, sondern auch das alte init-System der Distributionen abgelöst hat. Mehr zum Thema systemd in Bezug auf den Systemstart finden Sie in Kapitel 2, »Bootvorgang«.

Zusammen mit dem systemd wird der journald gestartet, der die Bootmeldung aller Dienste vom systemd entgegennimmt und auf einem laufenden System alle Meldungen von allen Diensten registriert, die über den systemd gestartet wurden. Die Informationen werden alle im Binärformat gespeichert. Der Vorteil dieses binären Formats ist der, dass Sie so in der Lage sind, alle Meldungen nach verschiedensten Kriterien filtern und weiterverarbeiten zu können.

Auch ist es möglich, die Meldungen entweder in der lokalen Zeit oder in der UTC anzeigen zu lassen. Aus diesem Grund ist es wichtig, dass Sie auf Ihren Systemen immer die richtige Zeitzone eingestellt haben. Das können Sie so wie in Listing 12.16 prüfen:

adminbuch:~ # timedatectl status
Local time: Mo 2018-07-04 13:46:09 CEST
Universal time: Mo 2018-07-04 11:46:09 UTC
RTC time: Mo 2018-07-04 11:46:07
Timezone: Europe/Berlin (CEST, +0200)
NTP enabled: yes
NTP synchronized: no
RTC in local TZ: no
DST active: yes
Last DST change: DST began at
So 2018-03-27 01:59:59 CET
So 2018-03-27 03:00:00 CEST
Next DST change: DST ends (the clock jumps one hour backwards) at
So 2018-10-30 02:59:59 CEST
So 2018-10-30 02:00:00 CET

Listing 12.16    Prüfen der Zeitzone

Sollte die Zeitzone nicht stimmen, können Sie sie mit dem Kommando sudo timedatectl set-timezone <zone> setzen. Eine Liste aller Zeitzonen erhalten Sie mit dem Kommando timedatectl list-timezones.

12.7.1    Erste Schritte mit dem »journalctl«-Kommando

In diesem Abschnitt wollen wir Ihnen erst einmal zeigen, wie Sie sich die Meldungen auflisten lassen können. Später folgt dann noch die Verwendung von verschiedenen Filtern und Ausgabeformaten.

Wenn Sie sich den Inhalt des Logs mit dem Kommando journalctl ohne weitere Option auflisten lassen, wird der Inhalt immer über den Pager ausgeben, der standardmäßig in Ihrem System eingerichtet ist. In den meisten Fällen wird das das Kommando less sein. Die Einträge werden immer vom ältesten zum neuesten Eintrag angezeigt.

Wollen Sie sich den Inhalt des Logs ohne die Verwendung von less auflisten lassen, verwenden Sie dazu die Option --no-pager. Dann wird das komplette Log auf einmal ausgegeben. In Tabelle 12.9 sehen Sie eine Liste der verschiedenen Ausgabemöglichkeiten.

Option Bedeutung
journalctl --no-pager komplette Ausgabe
journalctl | tail -n 5 die letzten 5 Zeilen
journalctl | head -n 5 die ersten 5 Zeilen
journalctl --utc UTC anstelle der lokalen Zeit
journalctl -b alle Meldungen seit dem letzten Boot
journalctl -f öffnet das Log und zeigt alle neuen Meldungen
journalctl -k zeigt alle Kernelmeldungen

Tabelle 12.9    Verschiedene Ausgabemöglichkeiten von »journalctl«

Ob Sie sich die Meldungen der verschiedenen Systemstarts auflisten lassen können, ist abhängig davon, ob der journald so konfiguriert ist, dass alle Meldungen von allen Systemstarts gespeichert werden. Sie können nämlich festlegen, ob journald alle Meldungen speichert oder nur die nach dem aktuellen Systemstart. Alle Meldungen von älteren Systemstarts gehen dann verloren. Das Verhalten wird über zwei Parameter bestimmt: zum einen über die Datei /etc/systemd/journald.conf und dort über den Parameter Storage= und zum anderen über das Vorhandensein des Verzeichnisses /var/log/journal. Der Parameter Storage kann die folgenden Werte enthalten:

Wenn Sie wissen wollen, welche Journale auf Ihrem System vorhanden sind, können Sie das so wie in Listing 12.17 machen:

adminbuch:~ # journalctl --list-boots
-3 9a3974eb2114448a9c021bc4d63e639c Mo 2016-06-13 17:13:45 CEST—Mo \
2016-06-13 17:32:46 CEST
-2 d07e1467e145408a9cd8f644e4ff76ea Mo 2016-06-13 17:33:30 CEST—Mo \
2016-06-13 18:41:07 CEST
-1 af3a42da1f794ddc9d0b711b4df75481 Mo 2016-07-04 12:24:05 CEST—Mo \
2016-07-04 12:47:33 CEST
0 4a107f6c677248748aa45aa2e97def5b Mo 2016-07-04 12:48:04 CEST—Mo \
2016-07-04 17:30:01 CEST

Listing 12.17    Auflisten aller Logs

Wenn Sie sich jetzt das Protokoll des Logs -1 ansehen wollen, können Sie das mit dem Kommando journalctl -b -1 erreichen.

12.7.2    Filtern nach Zeit

Bis jetzt haben Sie nur gesehen, wie Sie sich das gesamte Log oder einzelne Logs ansehen können. Aber eine der wichtigsten Filtermöglichkeiten ist das Filtern nach einer bestimmten Zeit oder einem bestimmten Zeitraum.

Dazu sehen Sie in Listing 12.18 einige Beispiele:

adminbuch:~ # journalctl --since "2016-07-04 15:00:00"
-- Logs begin at Mo 2016-06-13 17:13:45 CEST, end at Mo 2016-07-04 18:00:01 CEST. --
Jul 04 15:00:01 adminbuch cron[5340]: pam_unix(crond:session): \
session opened for user root by (uid=0)
Jul 04 15:00:01 adminbuch systemd[1]: Starting Session 11 of user root.
Jul 04 15:00:01 adminbuch systemd[1]: Started Session 11 of user root.

adminbuch:~ # journalctl --until "2016-07-04 15:00:00"
-- Logs begin at Mo 2016-06-13 17:13:45 CEST, end at Mo 2016-07-04 18:00:01 CEST. --
Jun 13 17:13:45 linux-v88t systemd-journal[101]: Runtime journal is using 4.6M
Jun 13 17:13:45 linux-v88t systemd-journal[101]: Runtime journal is using 4.6M

adminbuch:~ # journalctl --since "2016-07-04 15:00:00" --until "2016-07-04 16:00:00"
-- Logs begin at Mo 2016-06-13 17:13:45 CEST, end at Di 2016-07-05 09:30:01 CEST. --
Jul 04 15:00:01 adminbuch cron[5340]: pam_unix(crond:session): \
session opened for user root by (uid=0)
[…]
Jul 04 15:45:01 adminbuch systemd[1]: Starting Session 14 of user root.
Jul 04 15:45:01 adminbuch systemd[1]: Started Session 14 of user root.
Jul 04 15:45:01 adminbuch CRON[5461]: pam_unix(crond:session): \
session closed for user root

Listing 12.18    Filtern nach Zeit

Wie Sie an den drei Beispielen sehen, können Sie sowohl eine Anfangszeit für die Ausgabe des Logs wählen als auch eine Endzeit des Logs. Auch eine Kombination aus beiden ist möglich, wie Sie im dritten Beispiel in Listing 12.18 sehen.

Aber das sind noch nicht alle Möglichkeiten, die Sie haben. Auch intuitive Zeitangaben sind möglich, wie Sie den Beispielen aus Listing 12.19 entnehmen können:

adminbuch:~ # journalctl --since yesterday
-- Logs begin at Mo 2016-06-13 17:13:45 CEST, end at Mo 2016-07-04 18:15:01 CEST. --
Jul 04 12:24:05 adminbuch systemd-journal[99]: Runtime journal is using 4.6M

adminbuch:~ # journalctl --since 09:00 --until "1 hour ago"
-- Logs begin at Mo 2016-06-13 17:13:45 CEST, end at Mo 2016-07-04 18:15:01 CEST. --
Jul 04 12:24:05 adminbuch systemd-journal[99]: Runtime journal is using 4.6M

adminbuch:~ # journalctl --since "2016-07-04 17:15:00" --until now
-- Logs begin at Mo 2016-06-13 17:13:45 CEST, end at Di 2016-07-05 09:30:01 CEST. --
Jul 04 17:15:01 adminbuch cron[5689]: pam_unix(crond:session): session opened fo

Listing 12.19    Weitere Beispiele für die Zeit

So lassen sich Fehler genau eingrenzen. Weitere Schlüsselwörter, die Sie verwenden können, sind today und tomorrow. Bei den Zeiten können Sie auch noch mit + und - arbeiten, wie Sie in Listing 12.20 sehen können:

adminbuch:~ # journalctl --since "2016-07-04 17:15:00" --until "+1 hour"
-- Logs begin at Mo 2016-06-13 17:13:45 CEST, end at Di 2016-07-05 09:30:01 CEST. --
Jul 04 17:15:01 adminbuch cron[5689]: pam_unix(crond:session): session opened for

adminbuch:~ # journalctl --since "2016-07-04 17:15:00" --until "-1 minute"
-- Logs begin at Mo 2016-06-13 17:13:45 CEST, end at Di 2016-07-05 09:30:01 CEST. --
Jul 04 17:15:01 adminbuch cron[5689]: pam_unix(crond:session): \
session opened for user root by (uid=0)

Listing 12.20    Beispiele mit »+« und »-«

12.7.3    Filtern nach Diensten

Natürlich lässt sich das Log auch nach Meldungen von Diensten durchsuchen, die vom systemd verwaltet werden. Wenn Sie auf einem openLDAP-Server alle Meldungen des slapd ausfiltern wollen, dann können Sie die Meldungen wie in Listing 12.21 ausfiltern:

root@adminbuch:~# journalctl -u slapd.service
-- Logs begin at Mo 2016-07-04 14:27:48 CEST, end at Di 2016-07-05 09:09:01 CEST. --
Jul 04 14:27:52 adminbuch-l1 slapd[526]: @(#) $OpenLDAP:
Jul 04 14:27:52 adminbuch-l1 slapd[571]: slapd starting
Jul 04 14:27:52 adminbuch-l1 slapd[500]: Starting OpenLDAP: slapd.

Listing 12.21    Filtern von Servicemeldungen

Gerade wenn der Server schon längere Zeit läuft, kann es sinnvoll sein, den Zeitraum einzugrenzen. Natürlich können Sie die Filterung des Dienstes auch mit der Zeit aus dem vorherigen Abschnitt koppeln. Listing 12.22 zeigt dazu ein Beispiel:

root@adminbuch:~# journalctl -u slapd.service --since  "2016-07-04 17:15:00" \
--until "-1 minute"
-- Logs begin at Mo 2016-07-04 14:27:48 CEST, end at Di 2016-07-05 09:17:01 CEST. --
Jul 04 18:45:17 adminbuch-l1 slapd[571]: daemon: shutdown requested and initiated.
Jul 04 18:45:17 adminbuch-l1 slapd[571]: slapd shutdown: waiting for 0 \
operations/tasks to finish
[…]
Jul 05 08:46:15 adminbuch-l1 slapd[564]: slapd starting
Jul 05 08:46:15 adminbuch-l1 slapd[498]: Starting OpenLDAP: slapd.

Listing 12.22    Koppelung von Service- und Zeitfiltern

Auch ein Auflisten aller Einträge, die zu einer bestimmten PID gehören, ist möglich, wie Listing 12.23 zeigt:

root@adminbuch-l1:~# ps ax | grep slap | awk '{print $1}'
564

root@adminbuch:~# journalctl _PID=564
-- Logs begin at Mo 2016-07-04 14:27:48 CEST, end at Di 2016-07-05 09:39:01 CEST. --
Jul 05 08:46:15 adminbuch-l1 slapd[564]: slapd starting

Listing 12.23    Log-Einträge nach PID

Auch das Auflisten aller Logs zu einem bestimmten Benutzer oder einer Gruppe ist möglich, so wie Sie es in Listing 12.24 sehen:

root@adminbuch:~# id openldap
uid=108(openldap) gid=113(openldap) Gruppen=113(openldap)
root@adminbuch-l1:~# journalctl _UID=108 --since today
-- Logs begin at Mo 2016-07-04 14:27:48 CEST, end at Di 2016-07-05 09:39:01 CEST. --
Jul 05 08:46:15 adminbuch-l1 slapd[564]: slapd starting

Listing 12.24    Auflisten aller Einträge zu einem bestimmten Benutzer oder einer Gruppe

12.7.4    Kernelmeldungen

Zum Abschluss möchten wir hier noch einmal etwas genauer auf die Kernelmeldungen eingehen, da diese Meldungen auch noch auf eine interessante Art gefiltert werden können. Natürlich können Sie die folgenden Filter auch wieder mit allen vorher besprochenen Möglichkeiten kombinieren.

Wie schon in Tabelle 12.9 beschrieben, können Sie sich alle Kernelmeldungen mit dem Kommando journalctl -k anzeigen lassen. Damit werden Ihnen immer alle Meldungen seit dem letzten Bootvorgang angezeigt. Wollen Sie aber die Meldungen eines vorherigen Bootvorgangs sehen, können Sie dafür so vorgehen wie in Listing 12.25:

adminbuch:~ # journalctl --list-boots
-4 9a3974eb2114448a9c021bc4d63e639c Mo 2016-06-13 17:13:45 CEST—Mo \
2016-06-13 17:32:46 CEST
-3 d07e1467e145408a9cd8f644e4ff76ea Mo 2016-06-13 17:33:30 CEST—Mo \
2016-06-13 18:41:07 CEST
-2 af3a42da1f794ddc9d0b711b4df75481 Mo 2016-07-04 12:24:05 CEST—Mo \
2016-07-04 12:47:33 CEST
-1 4a107f6c677248748aa45aa2e97def5b Mo 2016-07-04 12:48:04 CEST—Mo \
2016-07-04 18:45:23 CEST
0 91fe2241d3154ef8a2c5f0ffb072a69e Di 2016-07-05 08:47:05 CEST—Di \
2016-07-05 10:00:01 CEST

adminbuch:~ # journalctl -k -b -2
-- Logs begin at Mo 2016-06-13 17:13:45 CEST, end at Di 2016-07-05 10:00:01 CEST. --
Jul 04 12:24:05 adminbuch kernel: Initializing cgroup subsys cpuset
Jul 04 12:24:05 adminbuch kernel: Initializing cgroup subsys cpu

Listing 12.25    Kernelmeldungen eines bestimmten Bootvorgangs

Auch eine Filterung auf bestimmte Level der Meldungen ist möglich. Ein Beispiel dazu sehen Sie in Listing 12.26:

root@adminbuch:~# journalctl -p err -b
-- Logs begin at Mo 2016-07-04 14:27:48 CEST, end at Di 2016-07-05 10:17:01 CEST. --
Jul 05 08:46:13 adminbuch-l1 kernel: piix4_smbus 0000:00:07.0: \
SMBus base address uninitialized

Listing 12.26    Meldungen eines bestimmten Levels filtern

Die Option -b zeigt nur die Meldungen nach dem letzten Bootvorgang an. Die Meldungen können Sie nach den in Tabelle 12.2 aufgelisteten Leveln filtern.