Scripts ops : healthcheck, rotate, notify
À la fin de ce tutoriel script bash devops, vous saurez assembler un petit outil ops : healthcheck HTTP/TCP avec retries et timeouts, rotation simple de fichiers de log, et notify webhook (
curlJSON) uniquement en cas d’échec — le tout avecset -euo pipefail, logging structuré ettrap. Ce n’est pas un redo de bash scripting (shebang / if / for) ni une copie des systemd timers : on fabrique la charge utile que le timer pourra ensuite planifier.Niveau : Intermédiaire · Temps estimé : 45–55 min · Versions testées : Ubuntu 22.04 / 24.04, Debian 12 ; notes Rocky/Alma 9 · Dernière vérification : 2026-09-11
Slug proposé :
linux-scripts-ops· Série : Linux Shell & Automation · Remplace / fusionne : N/A — création (lot 2)
Prérequis
- Hub Linux Shell & Automation ; bash avancé (
set -euo, fonctions,trap) - Bases P5 : bash scripting (déjà vu le mini healthcheck — ici on le professionnalise)
- Utile : systemd timers pour brancher le script en
ExecStartensuite - VM / WSL jetable ; travail sous
/tmp/lab-scripts-ops; aucun secret versionné (webhook via variable d’environnement)
Coût : 0 €. Lab entièrement jetable.
Ce que nous allons construire (script bash devops)
Squelette ops (set -euo + trap + log)
→ Healthcheck HTTP/TCP (retries, timeout, exit codes)
→ Rotate logs (taille / rétention)
→ Notify webhook JSON (échec seulement)
→ ops-watch.sh : healthcheck → log → rotate → notify
→ Pont timer systemd (mention)
→ Nettoyage
(Schéma à remplacer par une image locale Excalidraw / draw.io, alt : « Scripts ops DevOps : healthcheck bash, rotate logs, notify webhook ».)
Chapitre lot 2 de la colonne Shell. Après pipelines texte, on livre des patrons réutilisables : un junior DevOps les copie dans un lab, les versionne, puis les déclenche via timer ou CI — sans Ansible encore.
Étape 1 — Squelette ops : set -euo, trap, logging
Un script ops se distingue d’un one-liner par trois réflexes : arrêt net sur erreur, cleanup garanti, logs horodatés exploitables.
mkdir -p /tmp/lab-scripts-ops
cat > /tmp/lab-scripts-ops/lib-ops.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
LAB_DIR="${LAB_DIR:-/tmp/lab-scripts-ops}"
LOG_FILE="${LOG_FILE:-$LAB_DIR/ops.log}"
mkdir -p "$LAB_DIR"
log() {
local level=$1; shift
printf '%s [%s] %sn' "$(date -Iseconds)" "$level" "$*" | tee -a "$LOG_FILE" >&2
}
cleanup() {
local ec=$?
[[ $ec -eq 0 ]] || log ERROR "exit=$ec"
return "$ec"
}
trap cleanup EXIT
log INFO "squelette ops prêt — LOG_FILE=$LOG_FILE"
EOF
bash /tmp/lab-scripts-ops/lib-ops.sh
tail -n 3 /tmp/lab-scripts-ops/ops.log
| Élément | Rôle ops |
|---|---|
set -euo pipefail |
Échec explicite ; pas de variable fantôme ; pipes fiables |
trap … EXIT |
Toujours logger / nettoyer, même sur erreur |
tee -a |
Console et fichier pour debug immédiat |
Pas de mots de passe dans le script : coffre, secrets manager, ou export WEBHOOK_URL=… en session lab uniquement.
Étape 2 — Healthcheck HTTP / TCP robuste
Le mini ping/curl de Basics valide l’idée. En ops : timeouts, retries, et un exit code clair pour le timer / la CI.
cat > /tmp/lab-scripts-ops/healthcheck.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
# shellcheck source=/dev/null
source /tmp/lab-scripts-ops/lib-ops.sh
URL="${1:-https://example.com/}"
RETRIES="${RETRIES:-3}"
TIMEOUT="${TIMEOUT:-5}"
SLEEP_BETWEEN="${SLEEP_BETWEEN:-1}"
check_http() {
local url=$1 attempt=1 code
while (( attempt <= RETRIES )); do
code=$(curl -sS -o /dev/null -w '%{http_code}'
--connect-timeout "$TIMEOUT" --max-time "$TIMEOUT"
-L "$url" || echo "000")
if [[ "$code" =~ ^2 ]]; then
log INFO "health OK url=$url code=$code attempt=$attempt"
return 0
fi
log WARN "health fail url=$url code=$code attempt=$attempt/$RETRIES"
(( attempt++ ))
sleep "$SLEEP_BETWEEN"
done
log ERROR "health DOWN url=$url after $RETRIES tries"
return 1
}
check_http "$URL"
EOF
chmod +x /tmp/lab-scripts-ops/healthcheck.sh
/tmp/lab-scripts-ops/healthcheck.sh https://example.com/
# Échec volontaire (lab) :
RETRIES=2 SLEEP_BETWEEN=0 /tmp/lab-scripts-ops/healthcheck.sh https://httpbin.org/status/500 || true
Variante TCP rapide (port ouvert, sans HTTP) :
# nc -z -w 3 host 443 && echo OK || echo DOWN
timeout 3 bash -c 'echo >/dev/tcp/example.com/443' && echo "tcp 443 OK"
| Pratique | Pourquoi |
|---|---|
curl -w '%{http_code}' |
Mesure exploitable (2xx = OK) |
| Retries bornés | Absorbe un glitch réseau sans masquer une panne |
|| echo 000 |
Évite un crash opaque si curl ne répond pas |
| Exit 1 | Timer / CI / notify peuvent réagir |
Étape 3 — Rotation simple de logs
logrotate système est parfait en prod. En lab / petit agent : une rotate maison par taille évite un fichier qui grossit sans fin.
cat > /tmp/lab-scripts-ops/rotate.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
source /tmp/lab-scripts-ops/lib-ops.sh
TARGET="${1:-$LOG_FILE}"
MAX_BYTES="${MAX_BYTES:-4096}"
KEEP="${KEEP:-3}"
rotate_if_needed() {
local f=$1 size
[[ -f "$f" ]] || { log INFO "rien à rotator ($f)"; return 0; }
size=$(wc -c < "$f")
if (( size < MAX_BYTES )); then
log INFO "rotate skip size=$size < $MAX_BYTES"
return 0
fi
local i
for (( i=KEEP; i>=1; i-- )); do
[[ -f "${f}.${i}" ]] && mv -f "${f}.${i}" "${f}.$((i+1))"
done
mv -f "$f" "${f}.1"
: > "$f"
rm -f "${f}.$((KEEP+1))"
log INFO "rotated $f -> ${f}.1 (keep=$KEEP)"
}
rotate_if_needed "$TARGET"
EOF
chmod +x /tmp/lab-scripts-ops/rotate.sh
# Forcer une rotate : gonfler le log puis lancer
yes "pad $(date -Iseconds)" 2>/dev/null | head -n 200 >> /tmp/lab-scripts-ops/ops.log || true
MAX_BYTES=2048 /tmp/lab-scripts-ops/rotate.sh /tmp/lab-scripts-ops/ops.log
ls -la /tmp/lab-scripts-ops/ops.log*
Idempotent : relancer sans dépasser MAX_BYTES ne fait rien. En prod, préférez logrotate.d + copytruncate si le process garde le FD ouvert — ici on reste volontairement simple.
Étape 4 — Notify webhook (échec seulement)
Alerter à chaque succès = bruit. Pattern ops : notify sur échec, payload JSON minimal, URL hors du dépôt.
cat > /tmp/lab-scripts-ops/notify.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
source /tmp/lab-scripts-ops/lib-ops.sh
# Lab : httpbin. Prod : export WEBHOOK_URL='https://hooks.example/...'
WEBHOOK_URL="${WEBHOOK_URL:-https://httpbin.org/post}"
HOST="$(hostname -s 2>/dev/null || echo lab)"
MSG="${1:-ops alert}"
STATUS="${2:-fail}"
notify() {
local payload
payload=$(printf '{"host":"%s","status":"%s","message":"%s","ts":"%s"}'
"$HOST" "$STATUS" "$MSG" "$(date -Iseconds)")
log INFO "notify POST $WEBHOOK_URL"
curl -sS -o /tmp/lab-scripts-ops/notify-out.json -w '%{http_code}'
-X POST -H 'Content-Type: application/json'
--connect-timeout 5 --max-time 10
-d "$payload" "$WEBHOOK_URL" | tee /tmp/lab-scripts-ops/notify-code.txt
echo
log INFO "notify done code=$(cat /tmp/lab-scripts-ops/notify-code.txt)"
}
notify
EOF
chmod +x /tmp/lab-scripts-ops/notify.sh
/tmp/lab-scripts-ops/notify.sh "lab smoke" "ok"
head -c 200 /tmp/lab-scripts-ops/notify-out.json; echo
Jamais de token dans Git : WEBHOOK_URL (ou fichier chmod 600 hors repo). Pour Slack/Discord/Teams, adaptez le JSON au schéma attendu — le mécanisme reste curl + échec conditionnel.
Étape 5 — Assembler ops-watch.sh
On enchaîne healthcheck → append log → rotate → notify si health ≠ 0.
cat > /tmp/lab-scripts-ops/ops-watch.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
LAB_DIR=/tmp/lab-scripts-ops
LOG_FILE=$LAB_DIR/ops.log
export LAB_DIR LOG_FILE
source "$LAB_DIR/lib-ops.sh"
URL="${1:-https://example.com/}"
ec=0
if ! RETRIES="${RETRIES:-2}" "$LAB_DIR/healthcheck.sh" "$URL"; then
ec=1
fi
MAX_BYTES="${MAX_BYTES:-8192}" "$LAB_DIR/rotate.sh" "$LOG_FILE" || true
if (( ec != 0 )); then
"$LAB_DIR/notify.sh" "healthcheck failed for $URL" "fail" || true
exit 1
fi
log INFO "ops-watch OK url=$URL"
EOF
chmod +x /tmp/lab-scripts-ops/ops-watch.sh
/tmp/lab-scripts-ops/ops-watch.sh https://example.com/
# Scénario alerte (attendu exit 1) :
/tmp/lab-scripts-ops/ops-watch.sh https://httpbin.org/status/503 || echo "alerte déclenchée (attendu)"
Pont timer : dans systemd timers, pointez ExecStart=/tmp/lab-scripts-ops/ops-watch.sh https://example.com/ (chemins absolus, user timer d’abord). Ne recopiez pas les units ici — le timer déclenche, ce script décide.
Étape 6 — Vérification et nettoyage
bash -n /tmp/lab-scripts-ops/*.sh
command -v shellcheck >/dev/null && shellcheck /tmp/lab-scripts-ops/*.sh ||
echo "shellcheck optionnel : sudo apt install shellcheck"
ls -la /tmp/lab-scripts-ops/
# Nettoyage lab
rm -rf /tmp/lab-scripts-ops
echo "lab scripts-ops nettoyé — OK"
Validé si : healthcheck renvoie 0 sur 2xx et 1 après retries sur 5xx, rotate crée ops.log.1 au-delà de MAX_BYTES, notify écrit un JSON vers httpbin, ops-watch.sh n’appelle notify qu’en échec, aucun secret dans les fichiers.
Erreurs fréquentes
| Symptôme | Cause | Correction |
|---|---|---|
unbound variable |
set -u + env manquante |
${VAR:-défaut} |
| curl « OK » alors que 404 | On testait seulement l’exit curl | Lire %{http_code} (2xx) |
| Notify à chaque run | Pas de garde ec != 0 |
Notify uniquement sur échec |
| Log qui explose le disque | Pas de rotate | MAX_BYTES + KEEP |
| Timer vert, script rouge silencieux | Pas de journal / log fichier | tee -a + journalctl -u si timer |
| Secret dans Git | URL webhook commitée | WEBHOOK_URL en env / coffre |
source: not found |
Script lancé avec sh |
Shebang bash + bash script.sh |
Quiz (3 questions)
1. Pourquoi mesurer %{http_code} plutôt que se fier au seul exit code de curl ?
– A. Parce que curl n’a jamais d’exit code
– B. Pour distinguer une réponse HTTP (ex. 500) d’un succès transport
– C. Pour désactiver TLS
2. Quand envoyer le webhook dans un script ops typique ?
– A. À chaque succès pour « confirmer »
– B. Sur échec (ou changement d’état), pour limiter le bruit
– C. Uniquement au boot du noyau
3. Rôle principal de la rotate par taille dans ce lab ?
– A. Remplacer systemd
– B. Borner la croissance du fichier de log
– C. Chiffrer les secrets
Réponses : 1‑B · 2‑B · 3‑B
FAQ
Faut-il réécrire le healthcheck de bash scripting ?
Non : le lab P5 introduit curl/ping → log. Ici on ajoute retries, codes HTTP, rotate, notify et un assembleur ops-watch.sh prêt pour un timer.
Webhook Slack / Discord / Teams ?
Même idée (curl -X POST -H Content-Type: application/json). Adaptez le corps JSON au format du canal ; gardez l’URL hors dépôt.
Pourquoi pas Ansible / un exporter Prometheus ?
Hors scope de cette leçon. Le shell reste le colle ops du quotidien ; Ansible et le monitoring métriques viennent ensuite. Ce chapitre livre des briques versionnables.
Pour aller plus loin
man curl,help trap, ShellCheck wiki ; optionnellogrotate(8)pour la prod- Planifier : systemd timers
- Suite lot 2 : jq / yq (parser la réponse JSON du webhook / APIs)
- Hub : Linux Shell & Automation
Maillage série Linux Shell & Automation
| ← Précédent | Pipelines texte |
| → Suivant | jq / yq |
| Prérequis | Bash avancé · Bash scripting · systemd timers |
| Hub | Linux Shell & Automation |
Meta publication (à remplir dans Rank Math / SEO)
- Title SEO : Scripts ops bash : healthcheck, rotate, notify (2026)
- Meta description (≤ 155) : Scripts bash ops : healthcheck HTTP, rotation de logs et notify webhook. Suite Shell Automation DevOps 2026.
- Focus keyphrase : script bash devops
- KW secondaires : healthcheck bash, notify webhook, rotation logs bash, set -euo pipefail, trap bash
- Schemas Rank Math : Article + HowTo (étapes lab) + FAQ (3 questions ci-dessus)
- Image mise en avant :
assets/web/devopelastichayway/cover-linux-scripts-ops-1200x630.webp(Visuels Linux — WebP 1200×630) - Catégorie : Linux · Niveau : Intermédiaire
- Slug :
linux-scripts-ops - Statut : HOLD — draft only (ne pas publier)
← Retour parcours Linux — Basics, Admin, Réseau & Sécurité, Shell & Automation.