0Pricing
Linux Command Line & Bash Scripting Mastery · Lekcja

Tworzenie skryptów do kontroli kondycji systemu i alertów

Zbieraj dane o obciążeniu, pamięci i dysku oraz wyzwalaj alerty oparte na progach za pomocą skryptów uruchamianych zgodnie z harmonogramem.

Tworzenie skryptów do kontroli kondycji systemu i alertów to bezpłatna lekcja Linux Command Line & Bash Scripting Mastery na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Linux Command Line & Bash Scripting Mastery, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Linux Command Line & Bash Scripting Mastery zawiera 4 lekcji w sumie.

Dlaczego kontrole kondycji systemu mają znaczenie

Stan serwerów produkcyjnych może się stopniowo pogarszać bez wyraźnych oznak. Skoki użycia procesora, wycieki pamięci i zapełnione dyski powodują awarie — ale tylko wtedy, gdy nikt nie zauważy ich odpowiednio wcześnie. Skrypty kontroli kondycji systemu automatyzują pętlę monitorowania: zbierają metryki, porównują je z progami i wysyłają alerty, zanim użytkownicy odczują problem.

  • Uruchamiane za pomocą cron działają co kilka minut bez uwagi człowieka
  • Generują spójne dane wyjściowe ze znacznikami czasu, odpowiednie do agregowania logów
  • Logika oparta na progach sprawia, że alerty pozostają istotne — nie każde chwilowe zakłócenie powoduje powiadomienie zespołu dyżurnego

W tej lekcji zbudujesz od podstaw skrypt kontroli kondycji systemu klasy produkcyjnej, warstwa po warstwie, obejmujący średnie obciążenie, presję pamięci i wykorzystanie dysku.

Pobieranie średniej wartości obciążenia

Linux udostępnia średnie obciążenie z 1, 5 i 15 minut za pośrednictwem /proc/loadavg oraz polecenia uptime. W skryptach najczystszym źródłem jest /proc/loadavg — nie występują problemy z lokalizacją ani różnice w sposobie analizy danych między dystrybucjami.

Poniższy fragment odczytuje średnie obciążenie z 1 minuty i zapisuje je w zmiennej w celu porównania z progiem. cut wyodrębnia pierwsze pole, a awk usuwa część dziesiętną na potrzeby porównania liczb całkowitych z użyciem bc do obliczeń zmiennoprzecinkowych.

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

Porównywanie progów z wartościami zmiennoprzecinkowymi

Bash nie potrafi natywnie porównywać liczb zmiennoprzecinkowych — [ 1.5 -gt 1.2 ] powoduje błąd. Dwa idiomatyczne rozwiązania to:

  • bc — zwraca 1 (prawda) lub 0 (fałsz) na podstawie wyrażenia porównania
  • awk — może obliczać warunki zmiennoprzecinkowe w potoku

Użycie bc sprawia, że logika jest czytelna i łatwa do testowania. Wzorzec $(echo "$A > $B" | bc) zwraca 1, gdy warunek jest spełniony; wynik można sprawdzić za pomocą [ ... -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

Zbieranie metryk pamięci

/proc/meminfo jest wiarygodnym źródłem statystyk pamięci w systemie Linux. Najważniejsze pola:

  • MemTotal — całkowita ilość fizycznej pamięci RAM w kB
  • MemAvailable — szacowana ilość pamięci w kB dostępna dla nowych alokacji bez użycia pamięci wymiany (lepszy wskaźnik niż MemFree)

awk z dopasowaniem wzorca to najczystszy sposób wyodrębniania tych wartości. Podzielenie MemAvailable przez MemTotal i odjęcie wyniku od 100 daje procent zajętej pamięci, który służy do wyznaczania progu alertu.

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

Zbieranie metryk wykorzystania dysku

Polecenie df raportuje wykorzystanie systemów plików. W skryptach kluczowe są dwie flagi:

  • -h — rozmiary czytelne dla człowieka (tylko do wyświetlania; należy unikać ich w obliczeniach)
  • --output=pcent,target — kolumny możliwe do analizy maszynowej (GNU coreutils)

Iterowanie po wszystkich zamontowanych systemach plików pozwala skryptowi oznaczyć każdą krytycznie zapełnioną partycję, a nie tylko /. Znak % jest usuwany za pomocą tr -d '%' przed porównaniem liczb całkowitych.

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

Ustrukturyzowane dane alertów ze znacznikami czasu

Komunikaty alertów bez znaczników czasu są niemal bezużyteczne w plikach logów lub raportach e-mail. Spójny prefiks ułatwia analizę logów za pomocą grep lub agentów przesyłających logi.

Na początku skryptu zdefiniuj niewielką funkcję alertu. Dodaje ona przed komunikatem znacznik czasu ISO-8601, poziom ważności i nazwę kontroli. Wszystkie alerty są zapisywane zarówno na stdout, jak i w pliku logu za pomocą tee.

  • date -u +"%Y-%m-%dT%H:%M:%SZ" — znacznik czasu UTC niezależny od lokalizacji
  • Zapisywanie ALERT na stderr, a OK na stdout oddziela istotne informacje od szumu w potokach
#!/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"

Wysyłanie alertów e-mail za pomocą mail i sendmail

Najprostszym mechanizmem alertów na serwerze jest poczta e-mail wysyłana przez lokalny MTA (postfix, sendmail lub msmtp). Polecenie mail (z pakietu mailutils lub bsd-mailx) tworzy i wysyła wiadomość w jednym wierszu.

  • -s — temat wiadomości
  • Przekaż treść przez stdin
  • Na serwerach bez lokalnego MTA zastąp mail wywołaniem curl kierowanym do transakcyjnego API poczty e-mail

Wysyłanie należy zabezpieczyć blokadą deduplikacji, aby jeden powtarzający się problem nie zalał skrzynki odbiorczej.

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

Tworzenie pełnego skryptu kontroli stanu

Teraz połącz wszystkie trzy kontrole — obciążenie, pamięć i dysk — w jeden spójny skrypt z konfigurowalnymi progami na początku. To wzorzec stosowany w produkcyjnej automatyzacji administracji systemami:

  • Stałe zadeklarowane na początku, aby można było łatwo je dostosować bez modyfikowania logiki
  • Każda kontrola wydzielona do osobnej funkcji, co poprawia czytelność i ułatwia testowanie jednostkowe
  • Funkcja main koordynuje wywołania
  • Kod wyjścia 1, jeśli wystąpił dowolny alert, a w przeciwnym razie 0 — dzięki temu skrypt można łączyć ze strukturami monitorowania, takimi jak 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

Planowanie z użyciem crona

Skrypt kontroli stanu jest przydatny tylko wtedy, gdy uruchamia się automatycznie. cron to standardowy harmonogram zadań w systemach Unix. Aby zaplanować uruchamianie skryptu, zmodyfikuj systemowy crontab lub dedykowany plik w katalogu /etc/cron.d/.

  • Uruchamianie co 5 minut: */5 * * * *
  • W cron zawsze używaj ścieżek absolutnych — zmienna $PATH w środowisku crona jest ograniczona
  • Przekieruj wyjście, aby cron nie wysyłał wiadomości e-mail przy każdym uruchomieniu: >> /var/log/healthcheck.log 2>&1
  • Umieść na początku crontaba MAILTO="", aby wyłączyć wiadomości e-mail generowane przez samego crona
# /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

Zapobieganie lawinom alertów za pomocą blokad wyciszenia

Gdy próg jest stale przekroczony, naiwny skrypt wysyła alert co 5 minut — zanim inżynier zdąży zareagować, może otrzymać dziesiątki wiadomości e-mail. Blokada wyciszenia pomija powtarzające się alerty przez konfigurowalny czas.

Wzorzec działania: przy pierwszym alercie utwórz plik blokady; pomijaj kolejne alerty, dopóki plik jest nowszy niż ustalony okres wyciszenia; polecenie find z opcją -mmin atomowo sprawdza wiek pliku, bez wykonywania obliczeń na datach.

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

Testowanie i sprawdzanie poprawności skryptu kontroli stanu

Przed wdrożeniem sprawdź skrypt na trzy sposoby:

  • Sprawdzenie składni: bash -n healthcheck.sh wykrywa błędy analizy składni bez wykonywania skryptu
  • Tryb śledzenia: bash -x healthcheck.sh wyświetla każde polecenie w chwili jego wykonania — jest to nieoceniona pomoc w debugowaniu
  • Tymczasowe zastąpienie progów: tymczasowo obniż progi niemal do zera, aby skrypt generował alerty na sprawnym hoście i potwierdził działanie całej ścieżki alertowania

Podczas testowania ścieżki wysyłania wiadomości e-mail przekieruj mail do pliku dziennika, używając flagi MOCK_MAIL:

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

Sprawdzenie wiedzy: strategia wyciszania

Rozważ następujący scenariusz: zadanie cron kontroli stanu uruchamia się co 5 minut. Użycie dysku w systemie plików /var przekracza 85% i utrzymuje się na tym poziomie przez 3 godziny. Chcesz, aby inżynier dyżurny otrzymywał alert raz na godzinę, a nie co 5 minut. Która strategia implementacji jest najbardziej odpowiednia?

Podsumowanie lekcji: skrypty kontroli stanu systemu

W tej lekcji utworzyłeś kompletny, gotowy do użycia w produkcji potok kontroli stanu systemu i alertowania. Oto najważniejsze zasady, o których należy pamiętać:

  • Źródło prawdy: odczytuj metryki z /proc/loadavg i /proc/meminfo — są stabilne, niezależne od ustawień regionalnych i dostępne na każdym hoście z systemem Linux
  • Działania na liczbach zmiennoprzecinkowych: używaj bc do porównywania progów zmiennoprzecinkowych; porównywanie liczb całkowitych w Bashu (-gt) działa tylko dla liczb całkowitych
  • Iterowanie po dyskach: używaj df --output=pcent,target, aby sprawdzać każdy zamontowany system plików, a nie tylko /
  • Logowanie strukturalne: poprzedzaj każdą linię znacznikiem czasu UTC i poziomem ważności, aby można było łatwo przeszukiwać logi za pomocą grep i poprawnie przesyłać je do scentralizowanych systemów logowania
  • Blokady wyciszenia: pliki blokad sprawdzane za pomocą find -mmin zapobiegają lawinom alertów bez zmiany harmonogramu crona
  • Kompozycyjność: kończ działanie kodem 1, gdy wystąpi dowolny alert, aby skrypt integrował się z Nagios, Icinga lub innymi strukturami monitorowania
  • Testowanie: używaj bash -n do sprawdzania składni, bash -x do debugowania w trybie śledzenia oraz flagi MOCK_MAIL do sprawdzania ścieżki alertowania na sprawnych hostach

Zaplanuj ukończony skrypt za pomocą /etc/cron.d/, a Twoja infrastruktura będzie stale monitorować się samodzielnie i wysyłać alerty tylko wtedy, gdy progi zostaną istotnie przekroczone.

Często zadawane pytania

Czy lekcja „Tworzenie skryptów do kontroli kondycji systemu i alertów” jest bezpłatna?

Tak — pełny tekst „Tworzenie skryptów do kontroli kondycji systemu i alertów” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Linux Command Line & Bash Scripting Mastery, przejdź na CoddyKit PRO. Kurs Linux Command Line & Bash Scripting Mastery zawiera 4 lekcji w sumie.

Co nauczysz się w „Tworzenie skryptów do kontroli kondycji systemu i alertów”?

Zbieraj dane o obciążeniu, pamięci i dysku oraz wyzwalaj alerty oparte na progach za pomocą skryptów uruchamianych zgodnie z harmonogramem. Ćwiczysz Linux Command Line & Bash Scripting Mastery z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Linux Command Line & Bash Scripting Mastery?

Nie wymagamy żadnego doświadczenia. Linux Command Line & Bash Scripting Mastery w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Tworzenie skryptów do kontroli kondycji systemu i alertów”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Linux Command Line & Bash Scripting Mastery?

Tak. Każda lekcja Linux Command Line & Bash Scripting Mastery zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Automatyzacja tworzenia użytkowników i grup
  2. Sterowanie usługami systemd i pisanie plików jednostek
  3. Automatyzacja dysków, systemów plików i montowania
  4. Tworzenie skryptów do kontroli kondycji systemu i alertów
← Powrót do Linux Command Line & Bash Scripting Mastery