Ja tens tres tasques executant-se soles: l'informe a les 06:30, l'estat cada 10 minuts i la còpia de seguretat a les 03:15. Cadascuna escriu en un fitxer que creix sense parar, i cap no respon la pregunta que de debò importa: qui se n'assabenta si una deixa de funcionar? Registre i monitoratge són les dues cares del mateix problema. El registre és que el sistema t'expliqui el que fa, per reconstruir després què va passar; el monitoratge és que t'avisi mentre passa. L'un serveix per investigar, l'altre per reaccionar, i cap dels dos funciona improvisat: un registre sense format no es pot consultar, i una alerta que sona cada cinc minuts deixa de llegir-se al cap d'una setmana.
Contingut
- Per què
echono n'hi ha prou i com és una línia de registre - La funció
veloz_logamb nivells i llindar logger, syslog ijournalctl- Rotació amb
logrotate copytruncateenfront decreate- Comprovar enfront d'observar tendència: el patró 0/1/2
- Llindars, soroll, histèresi i estat
- Comprovacions típiques de Veloz Envíos
- Canals d'avís i bucle enfront d'execució periòdica
- Aplicació: neix
vigilant.sh
- Per què
echo no n'hi ha prou i com és una línia de registre
echo no n'hi ha prou i com és una línia de registreUn echo "processant" respon a la persona que està mirant la pantalla ara mateix. Dins d'un fitxer de tres mesos, aquella línia no diu quan va passar, qui la va escriure ni si era important —i aquestes tres respostes són tot el que necessites quan l'informe del dimarts falla i ho investigues dijous—. A més, echo escriu a la sortida estàndard, i això barreja dues coses que han d'anar separades (02-04): els resultats, que un altre programa podria consumir per una canonada, i els diagnòstics. La regla de sempre: resultats a stdout, registre a stderr.
Un format de registre té quatre camps, cadascun amb la seva raó de ser: la marca de temps (2026-08-03T06:30:01+02:00) per correlacionar amb altres sistemes, el nivell (INFO, WARN, ERROR) per filtrar per gravetat, el component (informe, copia, vigilant) per saber qui parla en un registre compartit, i el missatge amb el que ha passat. La marca de temps va primer i en ISO-8601 per dos motius pràctics: ordena alfabèticament igual que cronològicament —així sort funciona directament sobre el registre— i no és ambigua entre zones horàries. La genera date -Is. Sobre el missatge, una recomanació que s'agraeix quan el registre creix: fes servir parells clau=valor en lloc de prosa, perquè processats=1284 ciutat=Madrid es filtra amb grep i s'agrega amb awk (06-01), i «s'han processat 1284 enviaments, dels quals…» no. I mai no posis dades personals ni credencials al registre: els registres es copien, es comparteixen i es conserven mesos (08-03).
- La funció
veloz_log amb nivells i llindar
veloz_log amb nivells i llindarEls quatre nivells clàssics són DEBUG (detall intern, invisible en producció), INFO (fites normals: inici, fi, resultats), WARN (alguna cosa estranya però recuperable, cal revisar-ho) i ERROR (fallada que impedeix la feina, cal actuar). La funció completa per a lib/comu.sh:
declare -A VELOZ_NIVELLS=([DEBUG]=10 [INFO]=20 [WARN]=30 [ERROR]=40)
: "${VELOZ_LOG_NIVELL:=INFO}" # llindar configurable per entorn o .conf
: "${VELOZ_LOG_FITXER:=}" # buit = nomes stderr
: "${VELOZ_COMPONENT:=${0##*/}}" # nom de l'script sense cami
veloz_log() { # veloz_log NIVELL missatge...
local nivell="$1" linia; shift
(( ${VELOZ_NIVELLS[$nivell]:-20} >= ${VELOZ_NIVELLS[$VELOZ_LOG_NIVELL]:-20} )) || return 0
printf -v linia '%s [%s] %s: %s' "$(date -Is)" "$nivell" "$VELOZ_COMPONENT" "$*"
printf '%s\n' "$linia" >&2
[[ -n $VELOZ_LOG_FITXER ]] && printf '%s\n' "$linia" >> "$VELOZ_LOG_FITXER"
return 0
}
veloz_log_info() { veloz_log INFO "$@"; } # i les seves germanes _warn, _error, _debugProdueix línies com 2026-08-03T06:30:02+02:00 [INFO] informe-diari.sh: processats=1284 incidencies=37, i quatre decisions mereixen explicació. L'array associatiu (04-03) converteix etiquetes en números per poder comparar-les; sense ell, «WARN és més greu que INFO?» no té resposta a Bash. El : "${VAR:=valor}" assigna un valor per defecte només si la variable no venia definida, així que el .conf o l'entorn poden canviar el llindar sense tocar codi (05-06). Escriu sempre a stderr i, a més, al fitxer si està configurat, per veure els missatges en executar a mà i tenir-los registrats sota cron. I el return 0 final evita que un registre filtrat retorni un codi diferent de zero i avorti l'script sota set -e (05-03). Amb el llindar per defecte els DEBUG no apareixen, així que pots deixar-los posats i activar-los amb VELOZ_LOG_NIVELL=DEBUG només quan investigues.
logger, syslog i journalctl
logger, syslog i journalctlTot Linux té ja un servei de registre centralitzat —syslog als clàssics, journald als que fan servir systemd— i logger és l'ordre que hi escriu: logger -t veloz-copia -p user.err "la copia de 2026-08-03 ha fallat amb codi 74". -t posa l'etiqueta, per filtrar després per servei, i -p la prioritat en format facilitat.nivell (user.info, user.warning, user.err). També accepta l'entrada estàndard: ordre 2>&1 | logger -t veloz-informe.
Fitxer propi o syslog? El fitxer et dona control total del format i volum il·limitat, però la rotació te la muntes tu i consultar-lo és grep. El journal ja resol la rotació, ofereix els filtres de journalctl i es reenvia a un servidor central de manera estàndard, a canvi d'una capçalera i de poder descartar missatges sota càrrega. No és excloent, i la pràctica que segueix el toolkit és: el detall al fitxer propi, i els esdeveniments importants —fallada d'una tasca, alerta activada o resolta— també a logger, perquè apareguin allà on l'equip ja mira.
| Ordre | Què mostra |
|---|---|
journalctl -t veloz-copia |
Només el que està etiquetat amb logger -t |
journalctl -u cron |
Només d'aquella unitat (07-05) |
journalctl --since "today" |
També "1 hour ago", "2026-08-01 03:00" |
journalctl -p err / -f |
Prioritat err o superior / seguir en directe |
journalctl -u veloz-informe -n 50 --no-pager |
50 últimes línies, sense paginador (per a scripts) |
Es combinen: journalctl -t veloz-vigilant -p warning --since "-24h" dona els avisos i errors del vigilant en l'últim dia. Per al fitxer propi n'hi ha prou amb allò del Mòdul 2: tail -f, grep -F '[ERROR]' i, gràcies al fet que el nivell està en un camp fix, agregacions com awk '$2 == "[ERROR]" { print $3 }' vigilant.log | sort | uniq -c | sort -rn. Amb un registre de prosa lliure, això no seria possible.
- Rotació amb
logrotate
logrotateEls registres creixen per sempre, i vigilant.sh escriurà cada 5 minuts. Un disc ple tomba el servidor sencer —incloses les tasques que t'havien d'avisar—, així que la rotació no és un extra: és part de muntar una tasca automàtica. logrotate s'executa diàriament des de cron.daily i llegeix les configuracions de /etc/logrotate.d/:
# /etc/logrotate.d/veloz-ops
/home/veloz/veloz-ops/logs/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 veloz veloz
su veloz veloz
}Directiva a directiva: daily rota un cop al dia, al ritme de les tasques (també existeixen weekly i size 100M); rotate 14 conserva dues setmanes d'historial i esborra la resta; compress redueix un registre de text a un 10 % de la seva mida; delaycompress comprimeix a partir del segon cicle, i deixa el .1 sense comprimir per si encara s'hi escriu; missingok no falla si el fitxer encara no existeix; notifempty evita acumular catorze rotats buits; create 0640 veloz veloz crea el nou amb el propietari correcte, perquè l'script no corre com a root; i su veloz veloz rota amb aquella identitat, necessari en directoris d'usuari. Això produeix exactament els acces.log.1 i app.log.2.gz que veus des del Mòdul 2: ara ja saps d'on surten. I prova-ho abans de confiar-hi: logrotate -d /etc/logrotate.d/veloz-ops simula sense tocar res —és el --dry-run de 07-02 aplicat aquí— i logrotate -f força un cicle ara per comprovar permisos i propietari sense esperar a demà.
copytruncate enfront de create
copytruncate enfront de createAquest apartat explica una fallada que desconcerta molta gent: rotes el registre i el procés segueix escrivint al fitxer antic. La causa és en com funciona el sistema: un procés que va obrir un fitxer escriu a l'inode, no al nom. Quan logrotate reanomena vigilant.log a .1 i en crea un de nou, el procés que el tenia obert segueix apuntant a l'inode antic, ara anomenat .1, i el fitxer nou es queda buit per sempre. Hi ha tres estratègies. create reanomena l'antic i en crea un de nou, amb el risc que acabes de veure. create més postrotate … reload fa el mateix però avisa el procés que el reobri, i és la millor si el procés en sap. I copytruncate copia el contingut i després buida l'original, amb el risc de perdre les línies escrites entre copiar i buidar. Als scripts del toolkit no els afecta: cada execució de cron obre el registre amb >>, escriu i acaba, i el >> següent obre el fitxer nou pel seu nom. Per això create és el correcte aquí. Sí que afecta un procés de llarga durada que manté el fitxer obert, i allà necessites postrotate systemctl reload veloz-api; endscript o bé copytruncate, que és la solució universal quan el procés no sap reobrir, a canvi d'aquella petita finestra de pèrdua. Regla pràctica: create per a processos que obren i tanquen; copytruncate o recàrrega per als que mantenen el fitxer obert.
- Comprovar enfront d'observar tendència: el patró 0/1/2
Abans d'escriure el vigilant, una distinció que evita construir l'eina equivocada. Una comprovació (check) respon «està bé ara?» amb sí/no/dubtós i serveix per avisar; una mètrica respon «com evoluciona?» amb un número en el temps i serveix per diagnosticar i preveure. Bash és excel·lent per a comprovacions i per recollir mètriques, però no és el lloc on desar sèries temporals ni dibuixar gràfics —això són Prometheus, Grafana i companyia—. Els sistemes de monitoratge clàssics (Nagios i els seus descendents) van establir un conveni molt útil que pots adoptar encara que no en facis servir cap: 0 = OK, 1 = WARNING (fregant el llindar, mirar), 2 = CRITICAL (trencat, actuar ja) i 3 = UNKNOWN (no s'ha pogut comprovar). Cada comprovació és llavors una funció independent i homogènia: rep els seus llindars, imprimeix una línia de resum i retorna un d'aquests quatre codis.
check_disc() { # check_disc <cami> <avis%> <critic%>
local cami="$1" avis="$2" critic="$3" us
us=$(df -P "$cami" | awk 'NR == 2 { gsub(/%/, "", $5); print $5 }') || return 3
printf 'disc %s al %s%% (avis %s%%, critic %s%%)\n' "$cami" "$us" "$avis" "$critic"
(( us >= critic )) && return 2
(( us >= avis )) && return 1
return 0
}El gsub(/%/, "", $5) treu el símbol de percentatge per poder comparar com a número (06-01), i el || return 3 distingeix «no ho he pogut mesurar» de «està malament»: són coses molt diferents, i confondre-les produeix alertes falses cada vegada que df triga o el camí no existeix. Amb aquesta forma, afegir una comprovació nova és escriure una funció més i afegir-la a una llista.
- Llindars, soroll, histèresi i estat
Aquí es decideix si el teu monitoratge s'usa o s'ignora. Una comprovació que s'executa cada 5 minuts i avisa cada vegada genera 288 missatges al dia per un sol problema; la segona vegada que això passi, l'equip crea un filtre de correu i deixa de llegir les alertes, incloses les bones. Dos mecanismes ho eviten.
Histèresi: llindars diferents per activar i per desactivar. Si avises al 85 % de disc i dones per resolt per sota del 85 %, un disc oscil·lant entre 84,9 % i 85,1 % generarà una alerta cada cinc minuts; amb activació al 85 % i resolució al 80 %, cal una millora real perquè s'apagui. Estat: recordar en un fitxer quines alertes ja estan enviades, i avisar només a les transicions.
stateDiagram-v2
[*] --> Normal
Normal --> Alertant: el check falla (>= llindar critic)
note right of Alertant: s'envia l'avis UNA vegada
Alertant --> Alertant: segueix fallant (silenci)
Alertant --> Normal: check ok (< llindar de resolucio)
note left of Normal: s'envia "RESOLT" una vegada
notifica_transicio() { # <nom> <codi> <missatge>
local nom="$1" codi="$2" missatge="$3" marca="$ESTAT_DIR/$nom"
mkdir -p "$ESTAT_DIR"
if (( codi == 0 )); then
[[ -e $marca ]] && { rm -f "$marca"; avisa RESOLT "$nom: $missatge"; }
veloz_log_info "$nom: OK ($missatge)"
elif [[ ! -e $marca ]]; then # transicio de normal a alerta: s'avisa
printf '%s %s\n' "$(date -Is)" "$codi" > "$marca"; avisa ALERTA "$nom: $missatge"
else
veloz_log_warn "$nom: segueix malament ($missatge); avis ja enviat"
fi
}Fixa't que també s'avisa quan es resol: una alerta que mai no es tanca deixa l'equip sense saber si el problema segueix viu, i és tan inútil com no avisar. La marca desa a més l'hora d'inici, cosa que permet respondre després «quant va durar la incidència?».
- Comprovacions típiques de Veloz Envíos
Amb el patró de l'apartat 6, la bateria completa cap en poques línies perquè tota la maquinària ja està construïda en mòduls anteriors:
check_proces() { printf 'proces veloz-api\n'; pgrep -x veloz-api > /dev/null; } # 05-02
check_port() { printf 'port 8080\n'; veloz_port_obert localhost 8080; } # 06-04
check_carrega() { # carrega mitjana d'1 minut per nucli
local llindar="$1" carrega nuclis
read -r carrega _ < /proc/loadavg; nuclis=$(nproc) # 06-03
printf 'carrega %s amb %s nuclis\n' "$carrega" "$nuclis"
awk -v c="$carrega" -v n="$nuclis" -v u="$llindar" 'BEGIN { exit !(c/n >= u) }' && return 2 || return 0
}
check_api() { # l'API respon i es declara sana
local cos
cos=$(timeout 15s veloz_api_get /salud) || { printf 'API sense resposta\n'; return 2; }
printf 'l API diu %s\n' "$(jq -r '.estat // "?"' <<< "$cos")" # 06-05
jq -e '.estat == "ok"' <<< "$cos" > /dev/null && return 0 || return 1
}
check_incidencies() { # enviaments en estat incidencia avui
local llindar="$1" n
n=$(awk -F, -v h="$(date +%F)" '$2 ~ h && $5 == "incidencia" { c++ } END { print c + 0 }' \
/srv/veloz/dades/enviaments.csv) || return 3 # 06-01
printf 'incidencies avui: %s (llindar %s)\n' "$n" "$llindar"
(( n >= llindar * 2 )) && return 2; (( n >= llindar )) && return 1; return 0
}
check_copia() { # la copia d'ahir a la nit existeix i es recent
local ultima
ultima=$(find /copies/diaries -mindepth 1 -maxdepth 1 -type d -mtime -1 | head -1)
printf 'ultima copia: %s\n' "${ultima:-cap en 24h}"
[[ -n $ultima ]]
}En falta una més, check_errors_log, que compta els [ERROR] recents de /var/log/veloz/app.log comparant la marca de temps amb $(date -d "-15 minutes" '+%Y-%m-%d %H:%M:%S') dins d'awk (04-06): 1 o més és WARNING, 10 o més és CRITICAL. I check_copia és especialment valuosa i sol faltar: detecta la tasca que no s'ha executat, una fallada que cap registre no revela perquè no hi ha res per escriure quan no passa res. És l'aplicació pràctica del fitxer d'estat JSON de 07-02.
- Canals d'avís i bucle enfront d'execució periòdica
Tres maneres que l'alerta arribi a una persona, i el bon costum de fer-ne servir diverses:
avisa() { # avisa <ALERTA|RESOLT> <text>
local tipus="$1" text="$2"
logger -t veloz-vigilant -p user.err "$tipus $text"
[[ -n ${VELOZ_ALERTA_CORREU:-} ]] && printf '%s\n' "$text" | mail -s "[Veloz $tipus]" "$VELOZ_ALERTA_CORREU"
[[ -n ${VELOZ_ALERTA_WEBHOOK:-} ]] && { jq -n --arg t "[$tipus] $text" '{text: $t}' |
curl -sS -m 10 -H 'Content-Type: application/json' -d @- "$VELOZ_ALERTA_WEBHOOK" > /dev/null ||
veloz_log_warn "no s ha pogut lliurar l avis pel webhook"; }
return 0
}El webhook aplica allò de 06-05: el cos JSON es construeix amb jq -n --arg en lloc d'interpolar el text en una plantilla —un missatge amb cometes o un salt de línia trencaria el JSON—, i -d @- l'hi passa a curl per l'entrada estàndard. El -m 10 és obligatori: un xat que no respongui no pot penjar el vigilant (07-02). I fixa't que una fallada en lliurar l'avís no avorta l'script, perquè un destinatari caigut no ha d'impedir que la resta de comprovacions s'executin. El destí de les alertes viu a etc/veloz-ops.conf amb permisos 600, mai al codi. Última decisió de disseny: la temptació d'escriure while true; do comprovar; sleep 300; done és gairebé sempre pitjor idea que programar l'execució cada 5 minuts. Si el procés mor, el bucle deixa de vigilar i ningú no ho nota, mentre que l'execució periòdica següent arriba igualment; una fuita de memòria s'acumula durant setmanes enfront d'un procés curt que comença net; en reiniciar el servidor cal tornar-lo a llançar a mà; i en canviar el codi cal reiniciar-lo. El bucle només es justifica amb granularitat per sota del minut o amb estat en memòria car de reconstruir —i en aquest cas converteix-lo en un servei de systemd amb Restart=on-failure, que és el tema de 07-05—. Per a tota la resta: execució periòdica, estat en un fitxer, procés curt.
- Aplicació: neix
vigilant.sh
vigilant.sh#!/usr/bin/env bash
# vigilant.sh — Bateria de comprovacions de Veloz Envios.
# QUAN: cada 5 minuts | LOG: ~/veloz-ops/logs/vigilant.log
# Codis: 0 tot OK | 1 algun WARNING | 2 algun CRITICAL
set -euo pipefail
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export LC_ALL=C
readonly BASE="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
. "$BASE/lib/comu.sh"
[[ -r $BASE/etc/veloz-ops.conf ]] && . "$BASE/etc/veloz-ops.conf"
: "${VELOZ_LOG_FITXER:=$BASE/logs/vigilant.log}"
VELOZ_COMPONENT=vigilant
readonly ESTAT_DIR="$BASE/logs/estat"
readonly -a COMPROVACIONS=(
"disc:check_disc /srv 85 95" "carrega:check_carrega 2" "proces:check_proces"
"port:check_port" "api:check_api" "errors:check_errors_log 15"
"incidencies:check_incidencies ${LLINDAR_INCIDENCIES:-20}" "copia:check_copia"
)
main() {
exec 9>/var/lock/veloz-vigilant.lock
flock -n 9 || { veloz_log_info "hi ha una altra vigilancia en curs; surto"; exit 0; }
local pitjor=0 entrada nom ordre sortida codi
for entrada in "${COMPROVACIONS[@]}"; do
nom="${entrada%%:*}"; ordre="${entrada#*:}" # 04-04
sortida=$(timeout 30s bash -c "$ordre" 2>&1) && codi=0 || codi=$?
(( codi == 124 )) && { sortida="s ha exhaurit el temps d espera"; codi=3; }
notifica_transicio "$nom" "$codi" "$sortida"
(( codi > pitjor && codi != 3 )) && pitjor=$codi
done
veloz_log_info "cicle completat, pitjor estat: $pitjor"
return "$pitjor"
}
main "$@"Les decisions de disseny, una per una. Les comprovacions viuen en un array de cadenes nom:ordre per poder afegir-ne una sense tocar main, i el nom se separa amb les expansions de 04-04. Cadascuna va embolcallada en timeout 30s, perquè una de sola penjada no pot impedir que s'executin les altres. L'idioma … && codi=0 || codi=$? captura el codi sense que set -e avorti el bucle. El codi 3 (UNKNOWN) no empitjora el resultat global, perquè una fallada de mesura no dispari una alarma crítica. I notifica_transicio garanteix que cada incidència s'avisi un sol cop, i la seva resolució també. Al crontab va cada 5 minuts amb flock -n i redirecció al registre. Aquesta és la versió funcional; el projecte 09-04 aprofundeix en la part de xarxa, amb vigilància de diversos destins, mesura de latència i informe històric.
Errors Habituals i Consells
echosense marca de temps ni nivell, o registre a stdout. El primer no respon cap pregunta útil d'aquí a un mes; el segon contamina la sortida que un altre procés podria consumir.- No rotar. Un disc ple per registres tomba el servidor i, de passada, la tasca que t'havia d'avisar.
copytruncateper defecte. Innecessari per a scripts que obren i tanquen, i perd línies. Fes servircreatellevat que hi hagi processos de llarga durada.- Avisar a cada cicle, o no avisar de la resolució. 288 missatges al dia per un sol problema fan que l'equip filtri les teves alertes; i una alerta que mai no es tanca deixa tothom sense saber si segueix viva.
- Confondre «no ho he pogut mesurar» amb «està malament». Retorna 3 (
UNKNOWN) i no ho comptis com a crític. - Un llindar únic per activar i resoldre, o comprovacions sense
timeout. El primer produeix parpelleig (fes servir histèresi); el segon deixa que una comprovació penjada impedeixi les altres. - Dades personals o credencials al registre. Es copien, es comparteixen i es conserven mesos (08-03).
- Consell: per cada alerta que vagis a crear, pregunta't «si sona a les 3 de la matinada, hi ha res a fer?». Si la resposta és no, no és una alerta: és una mètrica, i el seu lloc és un panell, no el teu telèfon.
Exercicis
Exercici 1. Escriu la configuració de logrotate per a /var/log/veloz/app.log, que manté obert el procés veloz-api: rotació diària, 30 còpies, comprimides llevat de la més recent, sense fallar si el fitxer no existeix, i amb l'estratègia correcta per a un procés que no sap reobrir. Justifica l'elecció.
Exercici 2. Escriu check_memoria seguint el patró 0/1/2/3: avisa (1) si la memòria disponible baixa del 20 % del total i és crític (2) per sota del 10 %, imprimint una línia de resum.
Solucions
Solució 1.
# /etc/logrotate.d/veloz-api
/var/log/veloz/app.log /var/log/veloz/acces.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
copytruncate
}La directiva clau és l'última. copytruncate és l'elecció correcta perquè veloz-api manté el fitxer obert i no el sap reobrir: amb create, el procés seguiria escrivint a l'inode reanomenat a .1 i el fitxer nou quedaria buit per sempre. El preu és una finestra mínima entre copiar i truncar en què es poden perdre línies, i s'accepta perquè l'alternativa és perdre-les totes. Si veloz-api admetés una recàrrega, l'opció superior seria create més postrotate systemctl reload veloz-api; endscript. delaycompress deixa el .1 sense comprimir, cosa que evita comprimir un fitxer que encara podria rebre escriptures endarrerides.
Solució 2.
check_memoria() { # check_memoria [avis%] [critic%]
local avis="${1:-20}" critic="${2:-10}" total disponible pct
read -r total disponible < <(awk '/^MemTotal:/ { t = $2 }
/^MemAvailable:/ { d = $2 } END { print t, d }' /proc/meminfo) || return 3
(( total > 0 )) || return 3
pct=$(( disponible * 100 / total ))
printf 'memoria disponible %s%% (%s de %s kB)\n' "$pct" "$disponible" "$total"
(( pct < critic )) && return 2
(( pct < avis )) && return 1
return 0
}Es llegeix MemAvailable i no MemFree (06-03): MemFree exclou la memòria cau, que el nucli cedeix a l'instant si cal, així que un servidor sa pot tenir gairebé zero «lliure» i estar perfectament; MemAvailable és l'estimació real del que un procés nou podria fer servir. Els dos valors s'extreuen en una sola passada d'awk, i (( total > 0 )) protegeix d'una divisió per zero retornant 3 (UNKNOWN) en lloc de petar.
Conclusió
Del registre: echo no n'hi ha prou perquè no diu quan, qui ni amb quina gravetat; dissenya una línia amb marca date -Is, nivell, component i missatge en parells clau=valor, i implementa-la en una veloz_log amb nivells DEBUG/INFO/WARN/ERROR, llindar configurable i sortida a stderr i opcionalment a fitxer. Afegeix-hi logger -t -p perquè els esdeveniments importants arribin al syslog o al journal, on journalctl -u, --since, -p err i -f els recuperen amb filtres que un fitxer pla no ofereix. I rota, amb un fitxer a /etc/logrotate.d/ (daily, rotate, compress, delaycompress, missingok, notifempty), provant-ho amb logrotate -d: create per a processos que obren i tanquen com els teus scripts, copytruncate o una recàrrega per als que mantenen el fitxer obert, perquè un procés escriu a l'inode i no al nom.
Del monitoratge: distingeix comprovar de mesurar tendència; escriu cada comprovació com una funció homogènia que imprimeix una línia i retorna 0/1/2/3 a l'estil dels connectors clàssics, amb el 3 reservat per a «no ho he pogut mesurar»; defineix llindars amb histèresi i desa estat en fitxers per avisar només a les transicions —i avisar també quan es resol—; lliura per diversos canals (logger, correu, webhook amb jq -n i curl -m) sense que un canal caigut avorti el cicle; i prefereix l'execució periòdica al bucle infinit. vigilant.sh ja cobreix disc, càrrega, procés, port, API, incidències, errors recents i —el que gairebé ningú no vigila— que la còpia d'ahir a la nit existeixi.
El toolkit està complet i programat, però cron comença a quedar-se curt: no sap esperar que la xarxa estigui a punt, no recupera l'execució perduda mentre el servidor estava apagat, no aïlla ni limita els recursos d'una tasca, i el seu registre està dispers en quatre fitxers. A 07-05 coneixem systemd: unitats .service i .timer, OnCalendar validat amb systemd-analyze calendar, Persistent=true per a les execucions perdudes, registre centralitzat al journal i una taula honesta de quan val la pena migrar i quan cron segueix sent la resposta correcta.
Curs de Programació en Bash
Mòdul 1: Introducció a Bash
- Què és Bash?
- Configurar el teu Entorn
- Navegació Bàsica per la Línia d'Ordres
- Entendre el Shell
- Trobar Ajuda: man, help i --help
Mòdul 2: Ordres Bàsiques de Bash
- Operacions amb Fitxers i Directoris
- Ordres de Processament de Text
- Permisos i Propietat dels Fitxers
- Redirecció i Canonades
- Comodins i Expansió de Rutes
- Historial i Dreceres de Teclat
Mòdul 3: Fonaments de Scripting
- Crear i Executar un Script
- Variables i Constants
- Operadors Bàsics
- Sentències Condicionals
- Arguments i Entrada de l'Usuari
- Cometes, Expansió i Substitució
Mòdul 4: Scripting Intermedi
- Bucles en Bash
- Funcions en Bash
- Arrays i Arrays Associatius
- Manipulació de Cadenes
- La Sentència case i els Menús Interactius
- Aritmètica i Càlculs Numèrics
Mòdul 5: Tècniques Avançades de Scripting
- Operacions Avançades amb Fitxers
- Gestió de Processos
- Gestió d'Errors i Depuració
- Expressions Regulars
- Entrada/Sortida Avançada: Descriptors i Here-Documents
- Scripts Modulars i Llibreries Reutilitzables
Mòdul 6: Treballar amb Eines Externes
Mòdul 7: Automatització i Programació
- Tasques Cron
- Automatitzar Tasques
- Scripts de Còpia i Restauració
- Monitoratge i Registre
- Serveis i Temporitzadors amb systemd
- Automatització Remota amb SSH
Mòdul 8: Bones Pràctiques i Optimització
- Escriure Codi Llegible
- Optimitzar Scripts en Bash
- Consideracions de Seguretat
- Control de Versions amb Git
- Anàlisi Estàtica amb ShellCheck i shfmt
- Proves Automatitzades amb Bats
- Portabilitat: POSIX sh enfront de Bashismes
