Aller au contenu
Ingénierie · 5 min de lecture

Une tâche planifiée sans alerte est une tâche que vous n'exécutez pas

L'affirmation Une tâche planifiée qui s'exécute en silence et qu'on ne remarque qu'à son échec n'est pas une tâche fiable — c'est une tâche qui a déjà échoué en silence au moins un...

A Rédigé par Administrator
Une tâche planifiée sans alerte est une tâche que vous n'exécutez pas

L'affirmation

Une tâche planifiée qui s'exécute en silence et qu'on ne remarque qu'à son échec n'est pas une tâche fiable — c'est une tâche qui a déjà échoué en silence au moins une fois sans que personne le sache. Par défaut, cron ne signale succès ni échec à quiconque ; la sauvegarde nocturne, la production des factures et la synchronisation partagent donc une propriété qui devrait vous alarmer : leur échec est invisible jusqu'à ce qu'un humain cherche par hasard la sortie manquante.

Les deux modes de défaillance que cron ignore

Une tâche planifiée peut échouer de deux façons distinctes, et la configuration par défaut n'en attrape aucune.

Elle peut s'exécuter et errer — le script démarre, rencontre un problème et sort avec un code non nul. Cron enverra la sortie au dépôt de courrier local, qui, sur un hôte infonuagique moderne, aboutit dans un fichier que personne ne lit. L'erreur a eu lieu, elle a même été enregistrée, et elle n'a atteint aucun humain.

Pire, elle peut ne pas s'exécuter du tout — l'hôte redémarrait à l'heure prévue, le démon cron était arrêté, le disque était plein, ou quelqu'un a commenté la ligne pendant un travail sans rapport et l'a oublié. Une tâche qui ne s'exécute pas ne produit ni sortie ni erreur ; l'absence est donc le seul signal, et l'absence est exactement ce qu'une surveillance bâtie autour de la sortie ne peut pas voir.

Le motif : l'interrupteur de l'homme mort

Le correctif du mode le plus difficile consiste à inverser la logique. Au lieu d'alerter quand la tâche signale un problème, alertez quand la tâche ne signale pas son succès. La tâche envoie un signal à un service de surveillance à la fin d'une exécution réussie ; le service vous alerte quand un signal attendu n'arrive pas dans une fenêtre que vous définissez.

#!/usr/bin/env bash
set -euo pipefail

/srv/app/bin/nightly-export        # le vrai travail ; -e interrompt en cas d'echec

curl -fsS -m 10 --retry 3 https://checks.exemple.com/ping/nightly-export

Le curl ne s'exécute que si l'export au-dessus a réussi, car set -e interrompt le script à la moindre erreur. Le signal n'est donc pas « la tâche a démarré » — c'est « la tâche s'est terminée correctement ». Si l'export échoue, ou si l'hôte n'exécute jamais le script, aucun signal n'arrive, et le service de surveillance lève l'alerte que vous voulez réellement.

Plusieurs services hébergés font exactement cela pour quelques dollars par mois, et l'auto-hébergement est simple. La valeur tient entièrement à la logique inversée : vous surveillez l'absence de succès, seule façon d'attraper la tâche qui n'a jamais tourné.

Capter les erreurs quand la tâche s'exécute

Pour le cas s'exécute-et-erre, captez la sortie et acheminez-la là où un humain la voit :

0 2 * * *  /srv/app/nightly.sh >> /var/log/nightly.log 2>&1 || \
  curl -fsS -m 10 -d "echec de l'export nocturne, voir l'hote" \
    https://alerts.exemple.com/notify

Le 2>&1 capte la sortie standard et les erreurs vers le journal, et le || curl déclenche une alerte sur code non nul. Désormais, une tâche qui s'exécute et échoue vous le dit tout de suite, le journal fournissant le détail. Combiné à l'interrupteur ci-dessus, vous couvrez les deux modes : le signal attrape la non-exécution silencieuse, l'alerte attrape les erreurs bruyantes.

Les défaillances plus subtiles à attraper

Deux conditions sont techniquement des succès mais pratiquement des échecs, et elles valent la peine d'être prévues.

La tâche qui dure trop longtemps. Une sauvegarde qui prend d'ordinaire 20 minutes et met désormais 3 heures est en échec, même si elle finit par réussir — quelque chose cloche dans ses intrants ou dans le système. Un service de surveillance qui connaît la durée attendue le signale ; un simple emballage de délai qui traite le dépassement comme une erreur aussi.

La tâche qui réussit sans rien faire. Un export qui se termine en écrivant un fichier vide a échoué à sa raison d'être tout en signalant un succès. Vérifiez le résultat, pas seulement le code de sortie : contrôlez que le fichier de sortie n'est pas vide, que le nombre de lignes est plausible, que la date du jour y figure. Même principe que vérifier une sauvegarde en la restaurant — une sortie propre est une prétention, pas une confirmation.

Déplacez le calendrier là où vous le voyez

Cron lui-même est opaque : le calendrier vit dans des fichiers éparpillés entre utilisateurs et hôtes, sans vue centrale de ce qui est censé tourner. Là où la plateforme le permet, préférez les minuteries systemd, qui placent le calendrier, la dernière exécution, le code de sortie et les journaux en un seul endroit interrogeable :

systemctl list-timers --all          # chaque unite planifiee, prochaine et derniere execution
journalctl -u nightly-export.service # l'historique et la sortie de cette tache

Cela ne remplace pas l'alerte — il vous faut toujours l'interrupteur de l'homme mort pour la tâche qui ne s'exécute pas — mais cela retire le second problème du travail planifié, qui est de ne pas savoir ce qui est planifié en premier lieu.

Le test

Choisissez votre tâche planifiée la plus importante et brisez-la exprès dans un environnement sûr : renommez un fichier dont elle a besoin, ou empêchez-la de tourner ce soir. Si une alerte atteint un humain dans la fenêtre que vous jugeriez acceptable, votre surveillance fonctionne. Si rien ne se passe et que la seule façon de l'apprendre serait de remarquer la sortie manquante des jours plus tard, alors cette tâche tournait sur la confiance, et la confiance n'est pas une stratégie de surveillance pour ce qui génère vos factures.

#cron #monitoring #operations #reliability

À lire aussi