Creare script per controlli e avvisi sullo stato del sistema
Raccolga metriche su carico, memoria e disco e attivi avvisi basati su soglie da script pianificati.
Creare script per controlli e avvisi sullo stato del sistema è una lezione Linux Command Line & Bash Scripting Mastery gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Linux Command Line & Bash Scripting Mastery, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Linux Command Line & Bash Scripting Mastery include 4 lezioni in totale.
Perché i controlli dello stato del sistema sono importanti
I server di produzione possono degradarsi senza segnali evidenti. Picchi della CPU, perdite di memoria e dischi pieni causano interruzioni, ma solo se nessuno se ne accorge in tempo. Gli script di controllo dello stato del sistema automatizzano il ciclo di monitoraggio: raccolgono le metriche, le confrontano con le soglie e inviano avvisi prima che gli utenti riscontrino problemi.
- Programmati tramite
cron, vengono eseguiti ogni pochi minuti senza intervento umano - Producono un output coerente con marca temporale, adatto all'aggregazione dei log
- La logica basata su soglie mantiene significativi gli avvisi: non ogni breve anomalia attiva una chiamata al team reperibile
In questa lezione costruirà da zero uno script di controllo dello stato adatto alla produzione, aggiungendo un livello alla volta i controlli sul load average, sulla pressione della memoria e sull'utilizzo del disco.
Acquisizione del load average
Linux espone i load average di 1, 5 e 15 minuti tramite /proc/loadavg e il comando uptime. Per gli script, /proc/loadavg è la fonte più pulita: non presenta problemi di localizzazione né variazioni nell'analisi tra le diverse distribuzioni.
Il frammento seguente legge il load average di 1 minuto e lo memorizza in una variabile per il confronto con la soglia. cut estrae il primo campo; awk rimuove la parte decimale per il confronto tra interi usando bc per i calcoli in virgola mobile.
#!/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"Confronto con soglie in virgola mobile
Bash non è in grado di confrontare nativamente numeri in virgola mobile: [ 1.5 -gt 1.2 ] genera un errore. Le due soluzioni idiomatiche sono:
bc— restituisce1(vero) o0(falso) a partire da un'espressione di confrontoawk— può valutare condizioni in virgola mobile all'interno di una pipeline
L'uso di bc mantiene la logica leggibile e facile da testare. Lo schema $(echo "$A > $B" | bc) restituisce 1 quando la condizione è verificata; può testarlo con [ ... -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}%"
fiRaccolta delle metriche della memoria
/proc/meminfo è la fonte autorevole per le statistiche della memoria in Linux. Campi principali:
MemTotal— RAM fisica totale in kBMemAvailable— quantità stimata in kB disponibile per nuove allocazioni senza ricorrere allo swap (più indicativa diMemFree)
Usare awk con una ricerca per modello è il modo più pulito per estrarre questi valori. Dividendo MemAvailable per MemTotal e sottraendo il risultato da 100 si ottiene la percentuale di memoria utilizzata, sulla quale si basa la soglia dell'avviso.
#!/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}%"Raccolta delle metriche di utilizzo del disco
Il comando df restituisce le informazioni sull'utilizzo dei filesystem. Per gli script, due opzioni sono essenziali:
-h— dimensioni leggibili dall'utente (solo per la visualizzazione; da evitare nei calcoli aritmetici)--output=pcent,target— colonne analizzabili automaticamente (GNU coreutils)
Iterare su tutti i filesystem montati consente allo script di segnalare qualsiasi partizione quasi piena, non solo /. Il simbolo % viene rimosso con tr -d '%' prima del confronto tra interi.
#!/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
doneOutput strutturato degli avvisi con marche temporali
I messaggi di avviso senza marche temporali sono quasi inutili nei file di log o nei report via email. Un prefisso coerente semplifica notevolmente l'analisi dei log con grep o con gli agenti di invio dei log.
Definisca una piccola funzione di avviso all'inizio dello script. La funzione antepone una marca temporale ISO-8601, un livello di gravità e il nome del controllo. Tutti gli avvisi vengono scritti sia su stdout sia in un file di log tramite tee.
date -u +"%Y-%m-%dT%H:%M:%SZ"— marca temporale UTC, indipendente dalla lingua- Scrivere su
stderrper ALERT e sustdoutper OK separa i segnali dal rumore nelle pipeline
#!/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"Invio di avvisi email con mail e sendmail
Il meccanismo più semplice per gli avvisi sul server è l'invio di email tramite l'MTA locale (postfix, sendmail o msmtp). Il comando mail (fornito da mailutils o bsd-mailx) compone e invia un messaggio con una sola riga.
-s— oggetto del messaggio- Invii il corpo tramite
stdin - Sui server senza un MTA locale, sostituisca
mailcon una chiamatacurla un'API per l'invio transazionale di email
Protegga l'invio con un blocco di deduplicazione, in modo che una singola condizione rumorosa non inondi la casella di posta.
#!/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)"Composizione dello script completo per il controllo dello stato
Ora combini tutti e tre i controlli — carico, memoria e disco — in un unico script coerente, con soglie configurabili all'inizio. Questo è il modello usato nell'automazione sysadmin in produzione:
- Costanti dichiarate all'inizio, per poterle modificare facilmente senza intervenire sulla logica
- Ogni controllo isolato in una funzione, per migliorare leggibilità e possibilità di eseguire unit test
- Una funzione
maincoordina le chiamate - Codice di uscita
1se viene generato almeno un avviso,0altrimenti — in questo modo lo script può essere integrato con framework di monitoraggio come 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"
}
mainPianificazione con Cron
Uno script per il controllo dello stato è utile solo se viene eseguito automaticamente. cron è lo scheduler standard di Unix. Modifichi il crontab a livello di sistema oppure un file dedicato in /etc/cron.d/ per pianificare l'esecuzione dello script.
- Esecuzione ogni 5 minuti:
*/5 * * * * - Utilizzi sempre percorsi assoluti in cron —
$PATHè minimale nell'ambiente di cron - Reindirizzi l'output per impedire a cron di inviare un'e-mail a ogni esecuzione:
>> /var/log/healthcheck.log 2>&1 - Inserisca
MAILTO=""all'inizio del crontab per disattivare le e-mail generate direttamente da cron
# /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>&1Prevenzione delle raffiche di avvisi con i lock di cooldown
Quando una soglia viene superata continuamente, uno script ingenuo genera un avviso ogni 5 minuti — decine di e-mail prima che un tecnico possa intervenire. Un lock di cooldown sopprime gli avvisi ripetuti per un intervallo configurabile.
Il modello è il seguente: scrivere un file di lock al primo avviso; ignorare gli avvisi successivi finché il file è più recente del periodo di cooldown; find con -mmin controlla in modo atomico l'età del file senza dover eseguire calcoli sulle date.
#!/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)"
fiTest e convalida dello script per il controllo dello stato
Prima della distribuzione, convalidi lo script in tre modi:
- Controllo della sintassi:
bash -n healthcheck.shrileva gli errori di analisi senza eseguire lo script - Modalità trace:
bash -x healthcheck.shstampa ogni comando mentre viene eseguito — uno strumento prezioso per il debug - Sovrascrittura delle soglie: riduca temporaneamente le soglie quasi a zero, in modo che lo script generi avvisi su un host integro, verificando che il percorso degli avvisi funzioni dall'inizio alla fine
Per il percorso delle e-mail, durante i test reindirizzi mail verso un file di log utilizzando un flag 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}%"
fiVerifica delle conoscenze: strategia di cooldown
Consideri il seguente scenario: il cron job per il controllo dello stato viene eseguito ogni 5 minuti. L'utilizzo del disco in /var supera l'85% e rimane oltre questa soglia per 3 ore. Vuole che il tecnico di reperibilità riceva un avviso una volta all'ora, non ogni 5 minuti. Quale strategia di implementazione è più appropriata?
Riepilogo della lezione: script per il controllo dello stato del sistema
In questa lezione ha creato una pipeline completa e pronta per la produzione per il controllo dello stato del sistema e la generazione di avvisi. Ecco i principi fondamentali da tenere a mente:
- Fonte autorevole: legga le metriche da
/proc/loadavge/proc/meminfo— sono stabili, indipendenti dalla lingua e disponibili su ogni host Linux - Aritmetica in virgola mobile: utilizzi
bcper confrontare le soglie in virgola mobile; il confronto tra interi di Bash (-gt) funziona solo con numeri interi - Iterazione sui dischi: utilizzi
df --output=pcent,targetper controllare ogni filesystem montato, non solo/ - Logging strutturato: anteponga a ogni riga un timestamp UTC e un livello di gravità, così i log saranno facili da elaborare con grep e potranno essere inviati in modo affidabile ai sistemi di logging centralizzati
- Lock di cooldown: i file di lock controllati con
find -mminimpediscono le raffiche di avvisi senza modificare la pianificazione di cron - Componibilità: termini con il codice
1quando viene generato un avviso, così lo script si integra con Nagios, Icinga o altri framework di monitoraggio - Test: utilizzi
bash -nper i controlli della sintassi,bash -xper il debug tramite trace e un flagMOCK_MAILper convalidare il percorso degli avvisi su host integri
Pianifichi lo script completato tramite /etc/cron.d/ e la sua infrastruttura controllerà continuamente se stessa, generando avvisi solo quando le soglie vengono superate in modo significativo.
Domande Frequenti
La lezione «Creare script per controlli e avvisi sullo stato del sistema» è gratuita?
Sì — il testo completo di «Creare script per controlli e avvisi sullo stato del sistema» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Linux Command Line & Bash Scripting Mastery, passa a CoddyKit PRO. Il corso Linux Command Line & Bash Scripting Mastery include 4 lezioni in totale.
Cosa imparerò in «Creare script per controlli e avvisi sullo stato del sistema»?
Raccolga metriche su carico, memoria e disco e attivi avvisi basati su soglie da script pianificati. Eserciti Linux Command Line & Bash Scripting Mastery con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Linux Command Line & Bash Scripting Mastery?
Non è richiesta alcuna esperienza precedente. Linux Command Line & Bash Scripting Mastery su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Creare script per controlli e avvisi sullo stato del sistema»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Linux Command Line & Bash Scripting Mastery?
Sì. Ogni lezione Linux Command Line & Bash Scripting Mastery include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Automatizzare la gestione di utenti e gruppi
- Controllare i servizi systemd e scrivere file unit
- Automatizzare dischi, filesystem e mount
- Creare script per controlli e avvisi sullo stato del sistema