0Pricing
DevOps Bootcamp · Lektion

Skripte für Systemprüfungen und Warnmeldungen erstellen

Erfassen Sie Last-, Speicher- und Festplattenmetriken und lösen Sie aus geplanten Skripten schwellenwertbasierte Warnmeldungen aus.

Skripte für Systemprüfungen und Warnmeldungen erstellen ist eine kostenlose DevOps Bootcamp-Lektion auf CoddyKit. Dies ist Lektion 4 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 Systemzustandsprüfungen wichtig sind

Produktionsserver können sich unbemerkt verschlechtern. CPU-Spitzen, Speicherlecks und volle Datenträger verursachen Ausfälle — allerdings nur, wenn sie nicht rechtzeitig bemerkt werden. Skripte zur Prüfung des Systemzustands automatisieren den Überwachungszyklus: Sie erfassen Metriken, vergleichen sie mit Schwellenwerten und lösen Alarme aus, bevor Benutzer die Auswirkungen bemerken.

  • Über cron geplant, laufen sie alle paar Minuten ohne menschliches Eingreifen
  • Sie erzeugen eine einheitliche Ausgabe mit Zeitstempeln, die sich für die Protokollaggregation eignet
  • Schwellenwertbasierte Logik hält Alarme aussagekräftig — nicht jede kurze Störung benachrichtigt das Bereitschaftsteam

In dieser Lektion erstellen Sie von Grund auf ein produktionsreifes Skript zur Prüfung des Systemzustands. Dabei behandeln Sie schrittweise Load Average, Speicherdruck und Datenträgerauslastung.

Load Average erfassen

Linux stellt die Load Averages für 1, 5 und 15 Minuten über /proc/loadavg und den Befehl uptime bereit. Für Skripte ist /proc/loadavg die sauberste Quelle — ohne Probleme durch die Locale und ohne unterschiedliche Parsing-Formate zwischen Distributionen.

Das folgende Snippet liest die Load Average für eine Minute aus und speichert sie in einer Variable, um sie mit einem Schwellenwert zu vergleichen. cut extrahiert das erste Feld; awk entfernt die Nachkommastellen für den Ganzzahlenvergleich mit bc zur Gleitkommaarithmetik.

#!/usr/bin/env bash
# Read 1-minute load average from /proc/loadavg
LOAD_RAW=$(cut -d' ' -f1 /proc/loadavg)
echo "Raw load average: $LOAD_RAW"

# Number of CPU cores — used to normalise load
CPU_CORES=$(nproc)
echo "CPU cores: $CPU_CORES"

# Compute load percentage (load / cores * 100) using bc
LOAD_PCT=$(echo "scale=2; $LOAD_RAW / $CPU_CORES * 100" | bc)
echo "Load %: $LOAD_PCT"

Schwellenwertvergleich mit Gleitkommazahlen

Bash kann Gleitkommazahlen nicht nativ vergleichen — [ 1.5 -gt 1.2 ] erzeugt einen Fehler. Die zwei idiomatischen Lösungen sind:

  • bc — gibt für einen Vergleichsausdruck 1 (wahr) oder 0 (falsch) aus
  • awk — kann Gleitkomma-Bedingungen innerhalb einer Pipeline auswerten

Mit bc bleibt die Logik übersichtlich und lässt sich leicht testen. Das Muster $(echo "$A > $B" | bc) gibt 1 zurück, wenn die Bedingung erfüllt ist; dies prüfen Sie mit [ ... -eq 1 ].

#!/usr/bin/env bash
LOAD_RAW=$(cut -d' ' -f1 /proc/loadavg)
CPU_CORES=$(nproc)
THRESHOLD=80  # alert when load % exceeds 80%

LOAD_PCT=$(echo "scale=2; $LOAD_RAW / $CPU_CORES * 100" | bc)

# bc returns 1 if the expression is true
if [ "$(echo "$LOAD_PCT > $THRESHOLD" | bc)" -eq 1 ]; then
    echo "ALERT: Load is ${LOAD_PCT}% (threshold ${THRESHOLD}%)"
else
    echo "OK: Load is ${LOAD_PCT}%"
fi

Speichermetriken erfassen

/proc/meminfo ist die maßgebliche Quelle für Speicherstatistiken unter Linux. Wichtige Felder:

  • MemTotal — gesamter physischer RAM in kB
  • MemAvailable — geschätzter, für neue Zuweisungen verfügbarer Speicher in kB, ohne auf Swapping zurückgreifen zu müssen (besser als MemFree)

Mit awk und einer Musterübereinstimmung lassen sich diese Werte am saubersten extrahieren. Wenn Sie MemAvailable durch MemTotal teilen und das Ergebnis von 100 abziehen, erhalten Sie den Prozentsatz des belegten Speichers, der als Grundlage für den Alarmschwellenwert dient.

#!/usr/bin/env bash
# Extract memory figures from /proc/meminfo (values in kB)
MEM_TOTAL=$(awk '/^MemTotal:/ {print $2}' /proc/meminfo)
MEM_AVAIL=$(awk '/^MemAvailable:/ {print $2}' /proc/meminfo)

# Used memory percentage
MEM_USED_PCT=$(echo "scale=2; (1 - $MEM_AVAIL / $MEM_TOTAL) * 100" | bc)

echo "Total RAM : ${MEM_TOTAL} kB"
echo "Available : ${MEM_AVAIL} kB"
echo "Used      : ${MEM_USED_PCT}%"

Metriken zur Datenträgerauslastung erfassen

Der Befehl df gibt die Auslastung von Dateisystemen aus. Für Skripte sind zwei Optionen besonders wichtig:

  • -h — menschenlesbare Größen (nur für die Anzeige; vermeiden Sie diese bei Berechnungen)
  • --output=pcent,target — maschinenlesbare Spalten (GNU coreutils)

Wenn Sie alle eingehängten Dateisysteme durchlaufen, kann das Skript jede kritisch volle Partition melden, nicht nur /. Das Zeichen % wird vor dem Ganzzahlenvergleich mit tr -d '%' entfernt.

#!/usr/bin/env bash
DISK_THRESHOLD=85

# Skip header line with tail -n +2
# --output=pcent,target gives "85% /var" style lines
df --output=pcent,target | tail -n +2 | while read -r USED_PCT MOUNT; do
    # Remove the % sign for arithmetic
    USED_INT=${USED_PCT//%/}

    if [ "$USED_INT" -ge "$DISK_THRESHOLD" ]; then
        echo "ALERT: Disk $MOUNT is ${USED_PCT} full"
    else
        echo "OK   : Disk $MOUNT is ${USED_PCT} full"
    fi
done

Strukturierte Alarmausgabe mit Zeitstempeln

Alarmmeldungen ohne Zeitstempel sind in Protokolldateien oder E-Mail-Berichten nahezu nutzlos. Ein einheitliches Präfix vereinfacht die Protokollauswertung mit grep oder Log-Shipping-Agents erheblich.

Definieren Sie am Anfang Ihres Skripts eine kleine Alarmfunktion. Sie fügt einen ISO-8601-Zeitstempel, eine Schweregradstufe und den Namen der Prüfung voran. Alle Alarme werden über tee sowohl nach stdout als auch in eine Protokolldatei geschrieben.

  • date -u +"%Y-%m-%dT%H:%M:%SZ" — UTC-Zeitstempel, unabhängig von der Locale
  • Wenn Sie ALERT nach stderr und OK nach stdout schreiben, trennen Sie in Pipelines wichtige Meldungen vom übrigen Ausgabeaufkommen
#!/usr/bin/env bash
LOG_FILE="/var/log/healthcheck.log"

alert() {
    local LEVEL="$1"   # OK | WARN | ALERT
    local CHECK="$2"
    local MSG="$3"
    local TS
    TS=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
    local LINE="[$TS] [$LEVEL] [$CHECK] $MSG"

    if [ "$LEVEL" = "ALERT" ]; then
        echo "$LINE" | tee -a "$LOG_FILE" >&2
    else
        echo "$LINE" | tee -a "$LOG_FILE"
    fi
}

# Usage examples
alert "OK"    "DISK"  "/ is 42% full"
alert "ALERT" "DISK"  "/var is 91% full"

E-Mail-Alarme mit mail und sendmail senden

Der einfachste Alarmierungsmechanismus auf dem Server ist E-Mail über den lokalen MTA (postfix, sendmail oder msmtp). Der Befehl mail (aus mailutils oder bsd-mailx) erstellt und versendet eine Nachricht in einer einzigen Zeile.

  • -s — Betreffzeile
  • Leiten Sie den Nachrichtentext über stdin weiter
  • Ersetzen Sie auf Servern ohne lokalen MTA mail durch einen curl-Aufruf an eine transaktionale E-Mail-API

Sichern Sie den Versand mit einer Sperre zur Duplikatvermeidung ab, damit eine einzelne störende Bedingung den Posteingang nicht überflutet.

#!/usr/bin/env bash
ALERT_EMAIL="ops@example.com"
LOCK_DIR="/tmp/healthcheck_locks"
mkdir -p "$LOCK_DIR"

send_alert() {
    local CHECK="$1"
    local MSG="$2"
    local LOCK="$LOCK_DIR/${CHECK}.lock"

    # Only send if no lock exists (prevents repeated emails within the hour)
    if [ ! -f "$LOCK" ]; then
        echo "$MSG" | mail -s "[ALERT] $CHECK on $(hostname)" "$ALERT_EMAIL"
        touch "$LOCK"
        # Lock expires after 1 hour via cron or find+delete
        echo "Alert sent for $CHECK"
    else
        echo "Alert suppressed for $CHECK (lock active)"
    fi
}

send_alert "HIGH_LOAD" "Load average exceeded 80% on $(hostname) at $(date)"

Das vollständige Health-Check-Skript zusammenstellen

Führen Sie nun alle drei Prüfungen – Auslastung, Arbeitsspeicher und Festplatte – in einem einzigen, zusammenhängenden Skript mit konfigurierbaren Schwellenwerten am Anfang zusammen. Dieses Muster wird in der Automatisierung von Produktionssystemen verwendet:

  • Konstanten werden am Anfang deklariert, damit sie einfach angepasst werden können, ohne die Logik zu ändern
  • Jede Prüfung ist zur besseren Lesbarkeit und für Unit-Tests in einer eigenen Funktion gekapselt
  • Eine main-Funktion steuert die Aufrufe
  • Wenn ein Alarm ausgelöst wurde, wird der Exit-Code 1 zurückgegeben, andernfalls 0 – so lässt sich das Skript in Monitoring-Frameworks wie Nagios/Icinga integrieren
#!/usr/bin/env bash
set -euo pipefail

# ── Thresholds ───────────────────────────────────────────
LOAD_THRESHOLD=80   # percent of CPU capacity
MEM_THRESHOLD=90    # percent used
DISK_THRESHOLD=85   # percent used
ALERT_EMAIL="ops@example.com"
LOG_FILE="/var/log/healthcheck.log"
ALERT_FIRED=0

# ── Helpers ──────────────────────────────────────────────
ts()    { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
log()   { echo "[$(ts)] $*" | tee -a "$LOG_FILE"; }
alert() { log "ALERT: $*"; echo "$*" | mail -s "[ALERT] $(hostname)" "$ALERT_EMAIL" 2>/dev/null; ALERT_FIRED=1; }

# ── Checks ───────────────────────────────────────────────
check_load() {
    local raw cores pct
    raw=$(cut -d' ' -f1 /proc/loadavg)
    cores=$(nproc)
    pct=$(echo "scale=2; $raw / $cores * 100" | bc)
    if [ "$(echo "$pct > $LOAD_THRESHOLD" | bc)" -eq 1 ]; then
        alert "Load ${pct}% exceeds ${LOAD_THRESHOLD}%"
    else
        log "OK load=${pct}%"
    fi
}

check_memory() {
    local total avail pct
    total=$(awk '/^MemTotal:/    {print $2}' /proc/meminfo)
    avail=$(awk '/^MemAvailable:/{print $2}' /proc/meminfo)
    pct=$(echo "scale=2; (1 - $avail / $total) * 100" | bc)
    if [ "$(echo "$pct > $MEM_THRESHOLD" | bc)" -eq 1 ]; then
        alert "Memory ${pct}% used (threshold ${MEM_THRESHOLD}%)"
    else
        log "OK memory=${pct}%"
    fi
}

check_disk() {
    df --output=pcent,target | tail -n +2 | while read -r used mnt; do
        local pct_int=${used//%/}
        if [ "$pct_int" -ge "$DISK_THRESHOLD" ]; then
            alert "Disk $mnt at ${used}"
        else
            log "OK disk $mnt=${used}"
        fi
    done
}

main() {
    log "=== Health check START ==="
    check_load
    check_memory
    check_disk
    log "=== Health check END (alerts=$ALERT_FIRED) ==="
    exit "$ALERT_FIRED"
}

main

Ausführen mit Cron planen

Ein Health-Check-Skript ist nur dann nützlich, wenn es automatisch ausgeführt wird. cron ist der Standard-Scheduler unter Unix. Bearbeiten Sie die systemweite Crontab oder eine eigene Datei in /etc/cron.d/, um die Ausführung Ihres Skripts zu planen.

  • Alle 5 Minuten ausführen: */5 * * * *
  • Verwenden Sie in Cron immer absolute Pfade – $PATH ist in der Cron-Umgebung minimal
  • Leiten Sie die Ausgabe um, damit Cron nicht bei jeder Ausführung eine E-Mail sendet: >> /var/log/healthcheck.log 2>&1
  • Setzen Sie am Anfang der Crontab MAILTO="", um die eigenen E-Mails von Cron zu unterdrücken
# /etc/cron.d/healthcheck
# Run the health check every 5 minutes as root
MAILTO=""
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

*/5 * * * * root /usr/local/sbin/healthcheck.sh >> /var/log/healthcheck.log 2>&1

Alarmfluten mit Cooldown-Sperren verhindern

Wenn ein Schwellenwert dauerhaft überschritten wird, löst ein naives Skript alle 5 Minuten einen Alarm aus – Dutzende E-Mails, bevor eine zuständige Person reagieren kann. Eine Cooldown-Sperre unterdrückt wiederholte Alarme für einen konfigurierbaren Zeitraum.

Das Muster: Beim ersten Alarm wird eine Sperrdatei angelegt. Nachfolgende Alarme werden übersprungen, solange die Datei neuer als der Cooldown-Zeitraum ist. Mit find und -mmin lässt sich das Dateialter atomar prüfen, ohne Datumsberechnungen durchführen zu müssen.

#!/usr/bin/env bash
LOCK_DIR="/tmp/hc_locks"
COOLDOWN_MIN=60  # suppress repeat alerts for 60 minutes
mkdir -p "$LOCK_DIR"

should_alert() {
    local check="$1"
    local lock="$LOCK_DIR/${check}.lock"

    if [ ! -f "$lock" ]; then
        # No lock — allow alert and create lock
        touch "$lock"
        return 0  # true: send alert
    fi

    # Lock exists — check if it is older than the cooldown
    # find returns the filename only if it's OLDER than COOLDOWN_MIN
    local expired
    expired=$(find "$lock" -mmin +"$COOLDOWN_MIN" 2>/dev/null)

    if [ -n "$expired" ]; then
        touch "$lock"  # refresh lock timestamp
        return 0       # cooldown expired — allow alert
    fi

    return 1  # still within cooldown — suppress
}

# Usage
if should_alert "HIGH_LOAD"; then
    echo "Sending load alert..."
    # mail -s "..." ops@example.com <<< "Load too high"
else
    echo "Load alert suppressed (cooldown active)"
fi

Ihr Health-Check-Skript testen und validieren

Validieren Sie das Skript vor der Bereitstellung auf drei Arten:

  • Syntaxprüfung: bash -n healthcheck.sh erkennt Parse-Fehler, ohne das Skript auszuführen
  • Trace-Modus: bash -x healthcheck.sh gibt jeden Befehl bei seiner Ausführung aus – äußerst hilfreich beim Debugging
  • Schwellenwertüberschreibung: Senken Sie die Schwellenwerte vorübergehend auf nahezu null, damit das Skript auf einem gesunden Host Alarme auslöst. So bestätigen Sie, dass der Alarmweg von Anfang bis Ende funktioniert

Für den E-Mail-Weg leiten Sie mail während des Tests mithilfe eines MOCK_MAIL-Flags in eine Logdatei um:

#!/usr/bin/env bash
# Smoke-test the alert path without sending real email
MOCK_MAIL=true
ALERT_EMAIL="ops@example.com"

send_mail() {
    local subject="$1"
    local body="$2"
    if [ "$MOCK_MAIL" = true ]; then
        echo "[MOCK MAIL] To: $ALERT_EMAIL | Subject: $subject"
        echo "[MOCK MAIL] Body: $body"
    else
        echo "$body" | mail -s "$subject" "$ALERT_EMAIL"
    fi
}

# Override threshold to guarantee an alert fires
LOAD_THRESHOLD=0   # Any load will exceed 0%
LOAD_RAW=$(cut -d' ' -f1 /proc/loadavg)
CPU_CORES=$(nproc)
PCT=$(echo "scale=2; $LOAD_RAW / $CPU_CORES * 100" | bc)

if [ "$(echo "$PCT > $LOAD_THRESHOLD" | bc)" -eq 1 ]; then
    send_mail "[ALERT] Load on $(hostname)" "Load is ${PCT}%"
fi

Wissensüberprüfung: Cooldown-Strategie

Betrachten Sie folgendes Szenario: Ihr Health-Check-Cronjob wird alle 5 Minuten ausgeführt. Die Festplattennutzung auf /var überschreitet 85 % und bleibt 3 Stunden lang darüber. Die für Bereitschaftsdienste zuständige Person soll einmal pro Stunde einen Alarm erhalten, nicht alle 5 Minuten. Welche Implementierungsstrategie ist am geeignetsten?

Lektionsrückblick: Skripte zur Systemzustandsprüfung

In dieser Lektion haben Sie eine vollständige, produktionsreife Pipeline zur Prüfung des Systemzustands und zur Alarmierung erstellt. Die wichtigsten Prinzipien, die Sie mitnehmen sollten:

  • Verlässliche Datenquelle: Lesen Sie Metriken aus /proc/loadavg und /proc/meminfo – diese Dateien sind stabil, unabhängig von der Spracheinstellung und auf jedem Linux-Host verfügbar
  • Gleitkommaarithmetik: Verwenden Sie bc für Vergleiche mit Gleitkomma-Schwellenwerten. Der ganzzahlige Bash-Vergleich (-gt) funktioniert nur mit ganzen Zahlen
  • Festplatteniteration: Verwenden Sie df --output=pcent,target, um jedes eingehängte Dateisystem zu prüfen, nicht nur /
  • Strukturiertes Logging: Stellen Sie jeder Zeile einen UTC-Zeitstempel und eine Schweregradstufe voran, damit Logs sich einfach mit grep durchsuchen und zuverlässig an zentrale Logging-Systeme übertragen lassen
  • Cooldown-Sperren: Mit find -mmin geprüfte Sperrdateien verhindern Alarmfluten, ohne den Cron-Zeitplan zu ändern
  • Zusammensetzbarkeit: Geben Sie den Code 1 zurück, wenn ein Alarm ausgelöst wurde, damit sich das Skript in Nagios, Icinga oder andere Monitoring-Frameworks integrieren lässt
  • Tests: Verwenden Sie bash -n für Syntaxprüfungen, bash -x für die Ablaufverfolgung beim Debugging und ein MOCK_MAIL-Flag, um den Alarmweg auf gesunden Hosts zu validieren

Planen Sie das fertige Skript über /etc/cron.d/. Ihre Infrastruktur überwacht sich dann kontinuierlich selbst und löst nur Alarme aus, wenn Schwellenwerte tatsächlich überschritten werden.

Häufig gestellte Fragen

Ist die Lektion „Skripte für Systemprüfungen und Warnmeldungen erstellen“ kostenlos?

Ja — der vollständige Text von „Skripte für Systemprüfungen und Warnmeldungen erstellen“ 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 „Skripte für Systemprüfungen und Warnmeldungen erstellen“?

Erfassen Sie Last-, Speicher- und Festplattenmetriken und lösen Sie aus geplanten Skripten schwellenwertbasierte Warnmeldungen aus. 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 4 von 4.

Wie lange dauert die Lektion „Skripte für Systemprüfungen und Warnmeldungen erstellen“?

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

  1. Bereitstellung von Benutzern und Gruppen automatisieren
  2. systemd-Dienste steuern und Unit-Dateien schreiben
  3. Datenträger-, Dateisystem- und Mount-Automatisierung
  4. Skripte für Systemprüfungen und Warnmeldungen erstellen
← Zurück zu DevOps Bootcamp