objectif
Planifier un job cron sûr: environnement propre, exécution unique (lock), délai maximum (timeout) et logs quotidiens avec rétention.
code minimal
# crontab utilisateur (crontab -e)
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
CRON_TZ=UTC
MAILTO=""
# toutes les 5 min: healthcheck api.data.pm avec lock + timeout + log daté
*/5 * * * * flock -n /tmp/health-data.pm.lock \
bash -lc 'set -Eeuo pipefail; log="/var/log/data.pm/health-$(date -u +\%Y-\%m-\%d).log"; mkdir -p /var/log/data.pm; timeout 15s curl -fsS https://api.data.pm/health | jq -c . >> "$log" 2>&1'
utilisation
# 1) script robuste dédié (recommandé): /usr/local/bin/health-data-pm.sh
sudo install -m 0755 /dev/stdin /usr/local/bin/health-data-pm.sh <<'SH'
#!/usr/bin/env bash
set -Eeuo pipefail
log_dir="/var/log/data.pm"
log="$log_dir/health-$(date -u +%Y-%m-%d).log"
mkdir -p "$log_dir"
# mesure + contenu json (code HTTP, ttfb, total)
code="$(
curl -sS -o /tmp/resp.$$ \
-w '%{http_code}\t%{time_starttransfer}\t%{time_total}' \
https://api.data.pm/health
)"
http="$(cut -f1 <<<"$code")"
ttfb="$(cut -f2 <<<"$code")"
total="$(cut -f3 <<<"$code")"
ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
printf '%s %s http=%s ttfb=%.3fs total=%.3fs ' "$ts" "api.data.pm" "$http" "$ttfb" "$total" >> "$log"
jq -c . </tmp/resp.$$ >> "$log" || cat /tmp/resp.$$ >> "$log"
rm -f /tmp/resp.$$
# rétention: garder 7 jours
find "$log_dir" -type f -name 'health-*.log' -mtime +7 -delete
SH
# 2) crontab root (accès à /var/log); une seule exécution à la fois + délai 20s
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
CRON_TZ=UTC
MAILTO=""
*/5 * * * * flock -n /tmp/health-data.pm.lock timeout 20s /usr/local/bin/health-data-pm.sh
# 3) job de sauvegarde nocturne (exemple data.pm -> /srv/backup) avec logs
0 2 * * * flock -n /tmp/backup-data.pm.lock \
bash -lc 'set -Eeuo pipefail; d=/srv/backup/data.pm; mkdir -p "$d"; log="/var/log/data.pm/backup-$(date -u +\%Y-\%m-\%d).log"; \
rsync -a --delete --human-readable --info=stats2,progress2 /srv/data.pm/ "$d/" >> "$log" 2>&1'
variante(s) utile(s)
# /etc/cron.d (format système, champ utilisateur requis)
# fichier: /etc/cron.d/data-pm-health
# CRON_TZ=UTC
# SHELL=/bin/bash
# PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
*/5 * * * * root flock -n /tmp/health-data.pm.lock timeout 15s /usr/local/bin/health-data-pm.sh
# exécuter au démarrage puis toutes les 10 min
@reboot flock -n /tmp/boot-data.pm.lock timeout 60s /usr/local/bin/health-data-pm.sh
*/10 * * * * flock -n /tmp/health-data.pm.lock timeout 15s /usr/local/bin/health-data-pm.sh
# limiter l'impact CPU/IO (Linux)
*/5 * * * * nice -n 10 ionice -c3 flock -n /tmp/health-data.pm.lock timeout 15s /usr/local/bin/health-data-pm.sh
# avertir si code HTTP != 200 (mail local ou webhook)
*/5 * * * * bash -lc 'set -Eeuo pipefail; c=$(curl -fsS -o /dev/null -w "%{http_code}" https://api.data.pm/health || echo 000); [ "$c" = "200" ] || logger -t data.pm "health HTTP=$c"'
notes
- définissez toujours
SHELL,PATH,CRON_TZetMAILTOen tête de crontab. - utilisez
flockpour empêcher les chevauchements ettimeoutpour borner la durée. - écrivez des logs quotidiens datés et appliquez une rétention simple avec
find -mtime. - mettez les scripts sous
/usr/local/binavecset -Eeuo pipefailet chemins absolus. - pour surveiller les logs, combinez avec
journalctloutail -F /var/log/data.pm/*.log.