journald mit journalctl in Skripten abfragen
Filtern Sie systemd-Journaleinträge nach Unit, Priorität und Zeit, um die automatisierte Analyse von Vorfällen zu unterstützen.
journald mit journalctl in Skripten abfragen ist eine kostenlose DevOps Bootcamp-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des DevOps Bootcamp-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der DevOps Bootcamp-Kurs umfasst insgesamt 4 Lektionen.
Warum journald bei der Untersuchung von Vorfällen?
Moderne Linux-Systeme mit systemd zentralisieren sämtliche Protokollausgaben im Journal — einem strukturierten binären Protokollspeicher, der von systemd-journald verwaltet wird. Anders als einfache Textdateien in /var/log enthält jeder Journaleintrag umfangreiche Metadaten: Unit-Name, Prioritätsstufe, PID, UID, Zeitstempel und mehr.
In automatisierten Skripten zur Untersuchung von Vorfällen können Sie diese Metadaten nutzen, um:
- Protokolle ohne verkettete
grep-Befehle auf einen einzelnen Dienst zu begrenzen - Abfragen auf exakte Zeitfenster zu beschränken (letzte 15 Minuten, seit einem Deployment)
- nur kritische bzw. fehlerhafte Nachrichten auszugeben und irrelevante Meldungen zu ignorieren
- strukturierte Ausgaben direkt in Alarmierungspipelines einzuspeisen
Das Werkzeug, das all dies bereitstellt, ist journalctl. In dieser Lektion lernen Sie, es programmgesteuert in Bash-Skripten zu verwenden.
Grundlegender Aufruf von journalctl
Die einfachste Form von journalctl gibt das gesamte Journal aus. In Skripten ist das fast nie erwünscht — fügen Sie immer mindestens einen Filter hinzu. Hier sind die gängigsten Optionen, die Sie miteinander kombinieren werden:
-u <unit>— nach einer systemd-Unit filtern (z. B.nginx.service)-p <priority>— nach Syslog-Priorität filtern (0=emerg … 7=debug)--since/--until— Zeitfenster-n <N>— die letzten N Zeilen--no-pager— interaktive Seitennavigation deaktivieren (in Skripten unerlässlich)-o <format>— Ausgabeformat (short,json,catusw.)
Übergeben Sie in nicht interaktiven Skripten immer --no-pager, damit journalctl nicht versucht, less aufzurufen und hängen bleibt.
#!/usr/bin/env bash
# Print the last 20 lines of the nginx service journal
journalctl --no-pager -u nginx.service -n 20Nach einer systemd-Unit filtern
Die Option -u akzeptiert jeden gültigen Unit-Namen. Sie können sie mehrfach angeben, um mehrere Units zu kombinieren. Das ist nützlich, wenn sich eine einzelne Anwendung über mehrere Dienste erstreckt (z. B. eine API und ihren Datenbank-Sidecar).
Unit-Namen folgen dem Muster <name>.service, <name>.socket, <name>.timer usw. Globbing wird unterstützt: -u 'myapp*' erfasst myapp-api.service, myapp-worker.service und weitere passende Namen.
In einem Untersuchungsskript erhalten Sie den Unit-Namen typischerweise als Argument, wodurch der Filter dynamisch wird.
#!/usr/bin/env bash
# Usage: ./unit_logs.sh nginx.service
UNIT="${1:?Usage: $0 <unit>}"
echo "=== Journal for ${UNIT} (last 50 lines) ==="
journalctl --no-pager -u "${UNIT}" -n 50
# Combine two related units
echo "=== Combined: api + worker ==="
journalctl --no-pager -u myapp-api.service -u myapp-worker.service -n 30Prioritätsstufen und das Flag -p
Das Flag -p entspricht den standardmäßigen Syslog-Prioritätsstufen:
0— emerg1— alert2— crit3— err4— warning5— notice6— info7— debug
Sie können eine einzelne Stufe (-p err) angeben, um nur diese Stufe anzuzeigen, oder einen Bereich (-p emerg..err), um alle Einträge von Notfällen bis hin zu Fehlern zu erfassen — die häufigste Wahl für automatisierte Benachrichtigungen.
Benannte Aliase (err, warning, crit) werden neben numerischen Werten akzeptiert.
#!/usr/bin/env bash
# Extract only error-level and above entries for sshd
journalctl --no-pager \
-u sshd.service \
-p emerg..err \
--since "1 hour ago"
# Exit non-zero if any errors were found (useful in CI health checks)
ERROR_COUNT=$(journalctl --no-pager -u sshd.service -p emerg..err \
--since "1 hour ago" --output=cat | wc -l)
if [[ "${ERROR_COUNT}" -gt 0 ]]; then
echo "[ALERT] ${ERROR_COUNT} error(s) detected in sshd" >&2
exit 1
fiZeitfensterfilterung mit --since und --until
Zeitfilter bilden die Grundlage für Abfragen zu Zeiträumen von Vorfällen. journalctl akzeptiert flexible, für Menschen lesbare Zeitstempel:
- Relativ:
"10 minutes ago","2 hours ago","yesterday" - Absolut:
"2026-06-11 14:00:00" - Spezielle Schlüsselwörter:
today,yesterday,-1h(Kurzform)
In Deploy-Skripten wird häufig unmittelbar vor einem Deployment der Zeitstempel erfasst und anschließend das Journal ab diesem Zeitpunkt abgefragt, um durch das Release verursachte Regressionen zu erkennen.
#!/usr/bin/env bash
# Record deploy start time, then check logs afterwards
DEPLOY_START=$(date +"%Y-%m-%d %H:%M:%S")
echo "Deploying at ${DEPLOY_START}..."
# ... your deploy steps here ...
sleep 2 # simulate deploy
echo "=== Journal since deploy start ==="
journalctl --no-pager \
-u myapp.service \
--since "${DEPLOY_START}" \
-p emerg..warningStrukturierte Ausgabe im JSON-Format
Für maschinenlesbare Pipelines verwenden Sie -o json (ein JSON-Objekt pro Zeile, NDJSON) oder -o json-pretty (formatiert). Jedes Objekt enthält alle Journalfelder:
MESSAGE— der LogtextPRIORITY— numerische Priorität (0–7)_SYSTEMD_UNIT— die Ursprungseinheit__REALTIME_TIMESTAMP— Mikrosekunden seit der Unix-Epoche_PID,_UID,_HOSTNAME— Prozessmetadaten
Sie können diesen NDJSON-Datenstrom an jq weiterleiten, um Felder für nachgelagerte Benachrichtigungssysteme wie PagerDuty, Slack-Webhooks oder SIEM-Importer zu extrahieren, zu filtern oder neu zu formatieren.
#!/usr/bin/env bash
# Extract error messages as a clean list for a Slack notification
MESSAGES=$(journalctl --no-pager \
-u nginx.service \
-p emerg..err \
--since "30 minutes ago" \
-o json \
| jq -r '.MESSAGE' \
| sort -u)
if [[ -n "${MESSAGES}" ]]; then
echo "Errors detected:"
echo "${MESSAGES}"
fiDas Journal in Echtzeit verfolgen
Das Flag -f lässt journalctl das Journal live verfolgen — vergleichbar mit tail -f für eine Logdatei. Zusammen mit Filtern für Einheiten und Prioritäten wird daraus ein gezielter Echtzeitmonitor.
In Skript-Pipelines ist cursorbasiertes Polling meist sinnvoller: Speichern Sie den aktuellen Journal-Cursor und übergeben Sie bei jeder Abfrage --after-cursor=<cursor>, um nur neue Einträge seit der letzten Prüfung zu lesen. So vermeiden Sie, alte Zeilen erneut zu verarbeiten.
Rufen Sie den neuesten Cursor mit --show-cursor -n 0 ab und analysieren Sie die Zeile -- cursor: aus der Ausgabe.
#!/usr/bin/env bash
# Cursor-based polling: read only new journal entries each run
CURSOR_FILE="/tmp/triage_cursor"
if [[ -f "${CURSOR_FILE}" ]]; then
CURSOR=$(cat "${CURSOR_FILE}")
NEW_ENTRIES=$(journalctl --no-pager \
-u myapp.service \
-p emerg..err \
--after-cursor="${CURSOR}" \
-o json)
else
# First run: look back 5 minutes
NEW_ENTRIES=$(journalctl --no-pager \
-u myapp.service \
-p emerg..err \
--since "5 minutes ago" \
-o json)
fi
# Save updated cursor for next poll
journalctl --no-pager -n 0 --show-cursor 2>&1 \
| grep '^-- cursor:' \
| sed 's/-- cursor: //' \
> "${CURSOR_FILE}"
echo "${NEW_ENTRIES}" | jq -r '.MESSAGE // empty'Abfragen auf einen Bootvorgang beschränken mit -b
Das Flag -b beschränkt eine Abfrage auf eine bestimmte Boot-Sitzung. Nach einem Absturz oder unerwarteten Neustart ist dies unverzichtbar, um die Logs des vorherigen Bootvorgangs statt der aktuellen Sitzung abzurufen.
-b 0— aktueller Bootvorgang (Standard)-b -1— vorheriger Bootvorgang-b -2— vorletzter Bootvorgang--list-boots— alle aufgezeichneten Boot-Sitzungen mit Zeitstempeln anzeigen
Post-mortem-Skripte geben häufig kritische Logs des vorherigen Bootvorgangs (-b -1) aus, um zu ermitteln, warum das System abgestürzt ist oder ein Dienst beim Start fehlgeschlagen ist.
#!/usr/bin/env bash
# Post-mortem: collect critical logs from the previous boot
echo "=== Previous boot sessions ==="
journalctl --list-boots
echo ""
echo "=== Critical entries from previous boot ==="
journalctl --no-pager \
-b -1 \
-p emerg..crit \
-o short-isoSuche in journalctl: grep im Vergleich zu nativen Übereinstimmungen
Sie können nach allen Flags ein unverarbeitetes grep-Muster übergeben. journalctl unterstützt jedoch auch native Feldübereinstimmungen mit der Syntax FIELD=value. Native Übereinstimmungen werden anhand strukturierter Metadaten ausgewertet — deutlich schneller als die nachträgliche Textverarbeitung mit grep.
Häufig nützliche Übereinstimmungen:
_PID=1234— Logs eines bestimmten Prozesses_COMM=python3— Logs aller Prozesse mit dem Namenpython3SYSLOG_IDENTIFIER=myapp— Logs mit einem benutzerdefinierten Bezeichner
Mehrere Argumente im Format FIELD=value werden mit UND verknüpft; ein + dazwischen erzeugt eine ODER-Verknüpfung. Verwenden Sie -g <regex> für eine Volltextsuche mit grep, wenn strukturierte Metadaten nicht ausreichen.
#!/usr/bin/env bash
# Native field match: errors from the postgres process only
journalctl --no-pager \
_COMM=postgres \
-p emerg..err \
--since "1 hour ago"
# Full-text grep for a specific error string
journalctl --no-pager \
-u postgresql.service \
--since "1 hour ago" \
-g "FATAL|PANIC" \
--output=catEine wiederverwendbare Triage-Funktion erstellen
Wenn Sie die einzelnen Flags beherrschen, können Sie sie zu einer wiederverwendbaren Bash-Funktion kombinieren. So bleiben Ihre Triage-Skripte übersichtlich und konsistent. Eine gut konzipierte Funktion sollte:
- Einheit, Prioritätsbereich und Zeitfenster als Parameter akzeptieren
- Wenn Argumente fehlen, sichere Werte mit möglichst wenig Rauschen verwenden
- Einen Exit-Code ungleich null zurückgeben, wenn Fehler gefunden wurden (zur Integration in CI-Pipelines)
- Ergebnisse sowohl auf stdout als auch in eine Protokolldatei mit Zeitstempel schreiben, um eine Audit-Spur zu erstellen
#!/usr/bin/env bash
# triage.sh — reusable journal triage function
triage_unit() {
local unit="${1:?unit required}"
local priority="${2:-emerg..err}"
local since="${3:-1 hour ago}"
local logfile="/tmp/triage_${unit//[^a-zA-Z0-9]/_}_$(date +%s).log"
echo "[$(date -Iseconds)] Triaging ${unit} | prio=${priority} | since='${since}'" | tee "${logfile}"
journalctl --no-pager \
-u "${unit}" \
-p "${priority}" \
--since "${since}" \
-o short-iso \
| tee -a "${logfile}"
local count
count=$(wc -l < "${logfile}")
# Subtract 1 for the header line
(( count-- ))
if [[ "${count}" -gt 0 ]]; then
echo "[ALERT] ${count} line(s) logged to ${logfile}" >&2
return 1
fi
return 0
}
# Example: triage nginx errors in the last 30 minutes
triage_unit nginx.service "emerg..err" "30 minutes ago"Automatisiertes Skript zur Incident-Triage
Das folgende vollständige Skript verbindet alle Konzepte zu einem praktischen automatisierten Triage-Tool. Es liest eine Liste kritischer Dienste ein, fragt für jeden Dienst das Journal über ein konfigurierbares Rückblickfenster ab, fasst die Ergebnisse zusammen und beendet sich mit einem Fehlercode, wenn Fehler erkannt wurden — dadurch eignet es sich als Cronjob oder CI-Schritt zur Zustandsprüfung.
#!/usr/bin/env bash
# incident_triage.sh — automated multi-service journal triage
set -euo pipefail
LOOKBACK="${1:-15 minutes ago}"
PRIORITY="emerg..err"
SERVICES=(nginx.service postgresql.service myapp-api.service myapp-worker.service)
REPORT="/tmp/incident_report_$(date +%Y%m%d_%H%M%S).txt"
FAILED=0
{
echo "Incident Triage Report"
echo "Generated : $(date -Iseconds)"
echo "Lookback : ${LOOKBACK}"
echo "Priority : ${PRIORITY}"
echo "-----------------------------------"
} > "${REPORT}"
for svc in "${SERVICES[@]}"; do
ENTRIES=$(journalctl --no-pager \
-u "${svc}" \
-p "${PRIORITY}" \
--since "${LOOKBACK}" \
--output=cat 2>/dev/null || true)
COUNT=$(echo "${ENTRIES}" | grep -c . || true)
if [[ "${COUNT}" -gt 0 ]]; then
echo "[FAIL] ${svc}: ${COUNT} error(s)" | tee -a "${REPORT}"
echo "${ENTRIES}" >> "${REPORT}"
echo "-----------------------------------" >> "${REPORT}"
FAILED=1
else
echo "[OK] ${svc}"
fi
done
echo ""
echo "Full report: ${REPORT}"
exit "${FAILED}"Wissenscheck: Filtern nach Prioritätsbereichen
Sie schreiben ein Skript, das Bereitschaftstechniker nur dann benachrichtigen soll, wenn ein Dienst Meldungen mit der Fehlerstufe oder einer höheren Dringlichkeit protokolliert (also error, critical, alert oder emergency). Welche Kombination von journalctl-Flags erfasst genau diesen Bereich?
Zusammenfassung der Lektion: journalctl in Skripten
In dieser Lektion haben Sie gelernt, wie Sie das systemd-Journal programmgesteuert für eine automatisierte Incident-Triage abfragen:
- Verwenden Sie in Skripten immer
--no-pager, um eine interaktive Blockierung zu verhindern. - Einheitenfilterung (
-u) beschränkt Abfragen auf einen oder mehrere Dienste; Glob-Muster und mehrere-u-Flags werden unterstützt. - Prioritätsfilterung (
-p emerg..err) erfasst nur die für Sie relevanten Schweregrade — beachten Sie, dass kleinere Zahlen schwerwiegendere Stufen darstellen. - Zeitfenster (
--since/--until) beschränken die Logausgabe mithilfe lesbarer Zeitstempel auf ein Deployment-Zeitfenster oder einen Rückblickzeitraum. - Beschränkung auf einen Bootvorgang (
-b -1) ermöglicht es Post-mortem-Skripten, Logs einer vorherigen Absturzsitzung zu lesen. - JSON-Ausgabe (
-o json) undjqermöglichen strukturierte Pipelines für Benachrichtigungs- oder SIEM-Systeme. - Cursorbasiertes Polling mit
--after-cursorverhindert, dass bei wiederholten Ausführungen alte Einträge erneut verarbeitet werden. - Native Feldübereinstimmungen (
_COMM=,SYSLOG_IDENTIFIER=) sind schneller als die Weiterleitung angrep.
Wenn Sie diese Flags in einer wiederverwendbaren Bash-Funktion kombinieren, erhalten Sie ein produktionsreifes Triage-Tool, das sich problemlos in Cron, CI-Pipelines und Bereitschaftsbenachrichtigungen integrieren lässt.
Häufig gestellte Fragen
Ist die Lektion „journald mit journalctl in Skripten abfragen“ kostenlos?
Ja — der vollständige Text von „journald mit journalctl in Skripten abfragen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des DevOps Bootcamp-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der DevOps Bootcamp-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „journald mit journalctl in Skripten abfragen“?
Filtern Sie systemd-Journaleinträge nach Unit, Priorität und Zeit, um die automatisierte Analyse von Vorfällen zu unterstützen. Du übst DevOps Bootcamp mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um DevOps Bootcamp zu starten?
Keine Vorkenntnisse erforderlich. DevOps Bootcamp auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „journald mit journalctl in Skripten abfragen“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser DevOps Bootcamp-Lektion Code schreiben und ausführen?
Ja. Jede DevOps Bootcamp-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Web- und Anwendungsprotokolle in großem Maßstab auswerten
- Echtzeit-Überwachung von Protokollen und Streaming-Warnmeldungen
- journald mit journalctl in Skripten abfragen
- Metriken und Histogramme aus Protokollströmen berechnen