DevOps-bootcamp · Les

Scripts voor systeemcontroles en waarschuwingen bouwen

Verzamel statistieken over belasting, geheugen en schijfruimte en activeer vanuit geplande scripts waarschuwingen op basis van drempelwaarden.

Les 4 van 413 stappen

Scripts voor systeemcontroles en waarschuwingen bouwen is een gratis DevOps-bootcamp-les op CoddyKit. Dit is les 4 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject DevOps-bootcamp. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus DevOps-bootcamp bevat in totaal 4 lessen.

Waarom controles van de systeemstatus belangrijk zijn

Productieservers kunnen ongemerkt slechter gaan functioneren. Piekbelasting van de CPU, geheugenlekken en volle schijven veroorzaken storingen — maar alleen als niemand ze op tijd opmerkt. Scripts voor controles van de systeemstatus automatiseren de controlecyclus: verzamel meetgegevens, vergelijk ze met drempelwaarden en verstuur waarschuwingen voordat gebruikers problemen ervaren.

  • Ze worden gepland via cron en draaien elke paar minuten zonder menselijke aandacht
  • Ze produceren consistente uitvoer met tijdstempels die geschikt is voor logverzameling
  • Logica op basis van drempelwaarden houdt waarschuwingen relevant — niet elke korte hapering activeert een oproep voor het ondersteuningsteam

In deze les bouw je vanaf nul, stap voor stap, een script voor controles van de systeemstatus dat geschikt is voor productieomgevingen. Daarbij behandel je het gemiddelde systeemniveau, geheugendruk en schijfgebruik.

Het gemiddelde systeemniveau uitlezen

Linux stelt het gemiddelde systeemniveau voor 1, 5 en 15 minuten beschikbaar via /proc/loadavg en de opdracht uptime. Voor scripts is /proc/loadavg de duidelijkste bron — zonder problemen door landinstellingen en zonder verschillen in het ontleden tussen distributies.

Het onderstaande fragment leest het gemiddelde systeemniveau van één minuut en slaat dit op in een variabele om het met een drempelwaarde te vergelijken. cut haalt het eerste veld op; awk verwijdert het decimaalteken voor vergelijking als geheel getal, met bc voor berekeningen met kommagetallen.

#!/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"

Drempelwaarden vergelijken met kommagetallen

Bash kan getallen met een komma niet standaard vergelijken — [ 1.5 -gt 1.2 ] geeft een fout. De twee gebruikelijke oplossingen zijn:

  • bc — geeft 1 (waar) of 0 (onwaar) terug voor een vergelijkingsuitdrukking
  • awk — kan voorwaarden met kommagetallen binnen een pijplijn evalueren

Met bc blijft de logica leesbaar en eenvoudig te testen. Het patroon $(echo "$A > $B" | bc) geeft 1 terug wanneer aan de voorwaarde is voldaan. Je test dit met [ ... -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

Geheugenmeetgegevens verzamelen

/proc/meminfo is de gezaghebbende bron voor geheugenstatistieken in Linux. Belangrijke velden:

  • MemTotal — totale hoeveelheid fysiek RAM in kB
  • MemAvailable — geschatte hoeveelheid kB die beschikbaar is voor nieuwe toewijzingen zonder wisselgeheugen te gebruiken (beter dan MemFree)

Met awk en een patroonvergelijking kun je deze waarden het duidelijkst ophalen. Door MemAvailable te delen door MemTotal en het resultaat van 100 af te trekken, krijg je het percentage gebruikt geheugen. Dat bepaalt je waarschuwingsdrempel.

#!/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}%"

Meetgegevens over schijfgebruik verzamelen

De opdracht df rapporteert het gebruik van bestandssystemen. Voor scripts zijn twee opties essentieel:

  • -h — leesbare grootten (alleen voor weergave; vermijd deze bij berekeningen)
  • --output=pcent,target — kolommen die machinaal kunnen worden verwerkt (GNU coreutils)

Door alle gekoppelde bestandssystemen te doorlopen, kan het script elke kritisch volle partitie markeren, niet alleen /. Het teken % wordt met tr -d '%' verwijderd voordat de vergelijking als geheel getal wordt uitgevoerd.

#!/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

Gestructureerde waarschuwingen met tijdstempels

Waarschuwingsberichten zonder tijdstempels zijn vrijwel nutteloos in logbestanden of e-mailrapporten. Een consistente voorvoeging maakt het ontleden van logs met grep of agenten voor logverzending eenvoudig.

Definieer bovenaan je script een kleine waarschuwingsfunctie. Deze voegt een tijdstempel volgens ISO 8601, een ernstniveau en de naam van de controle toe. Alle waarschuwingen worden zowel naar stdout als naar een logbestand geschreven via tee.

  • date -u +"%Y-%m-%dT%H:%M:%SZ" — UTC-tijdstempel, onafhankelijk van landinstellingen
  • Schrijf ALERT naar stderr en OK naar stdout om signaal en ruis in pijplijnen van elkaar te scheiden
#!/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-mailwaarschuwingen verzenden met mail en sendmail

Het eenvoudigste waarschuwingsmechanisme op een server is e-mail via de lokale MTA (postfix, sendmail of msmtp). Met de opdracht mail (uit mailutils of bsd-mailx) stel je in één regel een bericht op en verstuur je het.

  • -s — onderwerpregel
  • Leid de berichttekst via stdin door
  • Vervang op servers zonder lokale MTA mail door een aanroep van curl naar een transactionele e-mail-API

Beveilig het verzenden met een vergrendeling tegen dubbele verzending, zodat één luidruchtige toestand de inbox niet overspoelt.

#!/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)"

Het volledige healthcheckscript samenstellen

Combineer nu alle drie de controles — belasting, geheugen en schijf — in één samenhangend script met instelbare drempelwaarden bovenaan. Dit is het patroon dat in productieautomatisering voor systeembeheer wordt gebruikt:

  • Constanten bovenaan declareren, zodat je ze eenvoudig kunt aanpassen zonder de logica te wijzigen
  • Elke controle voor leesbaarheid en unit-testbaarheid isoleren in een functie
  • Een main-functie die de aanroepen coördineert
  • Afsluitcode 1 als er een waarschuwing is geactiveerd, anders 0 — hierdoor kan het script worden gecombineerd met bewakingsframeworks zoals Nagios/Icinga
#!/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

Plannen met Cron

Een healthcheckscript levert alleen waarde als het automatisch wordt uitgevoerd. cron is de standaardplanner van Unix. Bewerk de systeembrede crontab of een speciaal bestand in /etc/cron.d/ om je script in te plannen.

  • Elke 5 minuten uitvoeren: */5 * * * *
  • Gebruik in cron altijd absolute paden — $PATH is minimaal in de cron-omgeving
  • Leid de uitvoer om om te voorkomen dat cron elke keer een e-mail verstuurt: >> /var/log/healthcheck.log 2>&1
  • Gebruik bovenaan de crontab MAILTO="" om de eigen e-mail van cron uit te schakelen
# /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

Alarmstormen voorkomen met cooldownvergrendelingen

Wanneer een drempelwaarde voortdurend wordt overschreden, activeert een naïef script elke 5 minuten een waarschuwing — tientallen e-mails voordat een engineer kan reageren. Een cooldownvergrendeling onderdrukt herhaalde waarschuwingen gedurende een instelbare periode.

Het patroon: schrijf een vergrendelingsbestand bij de eerste waarschuwing; sla volgende waarschuwingen over zolang het bestand nieuwer is dan de cooldownperiode; find met -mmin controleert de ouderdom van het bestand atomair, zonder datumrekeningen.

#!/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

Je healthcheckscript testen en valideren

Valideer het script vóór de implementatie op drie manieren:

  • Syntaxcontrole: bash -n healthcheck.sh vindt parsefouten zonder het script uit te voeren
  • Traceermodus: bash -x healthcheck.sh toont elk commando terwijl het wordt uitgevoerd — onmisbaar bij het opsporen van fouten
  • Drempelwaarde overschrijven: verlaag de drempelwaarden tijdelijk tot bijna nul, zodat het script waarschuwingen activeert op een gezonde host en je bevestigt dat het volledige waarschuwingspad werkt

Leid voor het e-mailpad tijdens het testen mail om naar een logbestand met behulp van een MOCK_MAIL-vlag:

#!/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

Kennistoets: cooldownstrategie

Bekijk het volgende scenario: je cron-taak voor de healthcheck wordt elke 5 minuten uitgevoerd. Het schijfgebruik op /var overschrijdt 85% en blijft daar 3 uur lang. Je wilt dat de engineer van dienst één keer per uur een waarschuwing ontvangt, niet elke 5 minuten. Welke implementatiestrategie is het meest geschikt?

Samenvatting van de les: scripts voor systeem-healthchecks

In deze les heb je een complete, productierijpe pijplijn voor systeem-healthchecks en waarschuwingen gebouwd. Dit zijn de belangrijkste principes om te onthouden:

  • Bron van waarheid: lees metingen uit /proc/loadavg en /proc/meminfo — deze zijn stabiel, onafhankelijk van de landinstellingen en beschikbaar op elke Linux-host
  • Rekenen met kommagetallen: gebruik bc voor vergelijkingen van drempelwaarden met kommagetallen; Bash-gehelegetallenvergelijking (-gt) werkt alleen met hele getallen
  • Schijfiteratie: gebruik df --output=pcent,target om elk aangekoppeld bestandssysteem te controleren, niet alleen /
  • Gestructureerde logregistratie: begin elke regel met een UTC-tijdstempel en ernstniveau, zodat logs eenvoudig met grep kunnen worden doorzocht en probleemloos naar gecentraliseerde logsystemen kunnen worden verzonden
  • Cooldownvergrendelingen: vergrendelingsbestanden die met find -mmin worden gecontroleerd, voorkomen alarmstormen zonder het cron-schema te wijzigen
  • Combineerbaarheid: sluit af met code 1 wanneer een waarschuwing wordt geactiveerd, zodat het script kan worden geïntegreerd met Nagios, Icinga of andere bewakingsframeworks
  • Testen: gebruik bash -n voor syntaxcontroles, bash -x voor foutopsporing met tracering en een MOCK_MAIL-vlag om het waarschuwingspad op gezonde hosts te valideren

Plan het voltooide script in via /etc/cron.d/ en je infrastructuur bewaakt zichzelf voortdurend, waarbij alleen waarschuwingen worden verstuurd wanneer drempelwaarden betekenisvol worden overschreden.

Gratis beginnen

Leer DevOps-bootcamp met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
142
Lessen
568

Veelgestelde vragen

Is de les “Scripts voor systeemcontroles en waarschuwingen bouwen” gratis?

Ja — je kunt hier op het web alle 3 lessen van het leerpad DevOps-bootcamp, waaronder “Scripts voor systeemcontroles en waarschuwingen bouwen”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus DevOps-bootcamp bevat in totaal 4 lessen.

Wat leer ik in “Scripts voor systeemcontroles en waarschuwingen bouwen”?

Verzamel statistieken over belasting, geheugen en schijfruimte en activeer vanuit geplande scripts waarschuwingen op basis van drempelwaarden. Je oefent met DevOps-bootcamp door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met DevOps-bootcamp te beginnen?

Ervaring vooraf is niet nodig. DevOps-bootcamp op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.

Hoe lang duurt de les “Scripts voor systeemcontroles en waarschuwingen bouwen”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over DevOps-bootcamp?

Ja. Elke les over DevOps-bootcamp bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Gebruikers en groepen automatisch configureren
  2. systemd-services beheren en unitbestanden schrijven
  3. Schijven, bestandssystemen en mountbewerkingen automatiseren
  4. Scripts voor systeemcontroles en waarschuwingen bouwen
← Terug naar DevOps-bootcamp