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

  1. Per què echo no n'hi ha prou i com és una línia de registre
  2. La funció veloz_log amb nivells i llindar
  3. logger, syslog i journalctl
  4. Rotació amb logrotate
  5. copytruncate enfront de create
  6. Comprovar enfront d'observar tendència: el patró 0/1/2
  7. Llindars, soroll, histèresi i estat
  8. Comprovacions típiques de Veloz Envíos
  9. Canals d'avís i bucle enfront d'execució periòdica
  10. Aplicació: neix vigilant.sh

  1. Per què echo no n'hi ha prou i com és una línia de registre

Un 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).

  1. La funció veloz_log amb nivells i llindar

Els 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, _debug

Produeix 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.

  1. logger, syslog i journalctl

Tot 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.

  1. Rotació amb logrotate

Els 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à.

  1. copytruncate enfront de create

Aquest 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.

  1. 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.

  1. 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?».

  1. 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.

  1. 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.

  1. Aplicació: neix 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

  • echo sense 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.
  • copytruncate per defecte. Innecessari per a scripts que obren i tanquen, i perd línies. Fes servir create llevat 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

Mòdul 2: Ordres Bàsiques de Bash

Mòdul 3: Fonaments de Scripting

Mòdul 4: Scripting Intermedi

Mòdul 5: Tècniques Avançades de Scripting

Mòdul 6: Treballar amb Eines Externes

Mòdul 7: Automatització i Programació

Mòdul 8: Bones Pràctiques i Optimització

Mòdul 9: Projectes del Món Real

© Copyright 2026. Tots els drets reservats