Heartbeats: surveillance des tâches planifiées
Un heartbeat veille sur une tâche planifiée : un cron, une sauvegarde nocturne, le nettoyage d'un worker, une génération de rapport. Le principe est celui de l'homme mort, au lieu que Quiet Guard demande à votre tâche si elle a tourné, c'est votre tâche qui prévient Quiet Guard à chaque exécution (un « ping »). Quand les pings s'arrêtent, vous êtes alerté.
Le problème que ça résout
Le suivi d'exceptions attrape le code qui échoue bruyamment : quelque chose lève une exception, vous recevez un rapport. Mais les pannes les plus sournoises sont silencieuses :
- l'entrée cron a été perdue lors d'une migration de serveur,
- le scheduler est mal configuré (
schedule:runn'est plus invoqué), - la tâche plante si tôt qu'aucun gestionnaire d'exception ne la voit,
- quelqu'un a désactivé le job « temporairement » il y a trois mois.
Dans tous ces cas, rien ne lève d'exception, donc rien n'est rapporté. Votre sauvegarde nocturne cesse simplement d'exister, et vous le découvrez le jour où vous en avez besoin. Le heartbeat inverse la logique : le silence devient lui-même l'alerte.
Démarrage rapide
Le câblage recommandé est la macro du scheduler, chaînée directement sur la tâche dans routes/console.php :
La macro ne pingue que si la tâche réussit, une tâche qui plante reste silencieuse et déclenche donc l'alerte de retard. Vous pouvez aussi pinger manuellement depuis n'importe quel code :
ou en HTTP (toute stack, pas seulement Laravel) :
Enregistrement et armement
- Le premier ping enregistre automatiquement le heartbeat sur le projet. À ce stade il est non armé : les pings sont enregistrés, rien n'alerte jamais. C'est voulu: on branche le ping d'abord, on décide ensuite de ce que « en retard » veut dire.
- L'armement se fait dans le tableau de bord : ouvrez l'onglet Heartbeats du projet, modifiez le heartbeat et définissez sa période attendue (la fréquence à laquelle la tâche doit pinger, en minutes) plus une tolérance (retard supplémentaire accepté: un scheduler tombe rarement à la seconde exacte).
- Un heartbeat sans période attendue reste un journal passif de pings, à jamais inoffensif.
Battements automatiques
Le SDK Laravel, depuis sa version 0.4, déclare deux heartbeats de lui-même : scheduler, et un par file surveillée (queue-{connexion}-{file}). Ils s'arment au premier ping qui porte de quoi s'armer, avec une période observée et une tolérance de période plus quatre minutes pour le scheduler, neuf minutes (ou, depuis Laravel 13.10, le --timeout du worker plus une minute) pour une file, l'une comme l'autre plafonnée à 1440 minutes. L'onglet les marque Automatique et affiche le retard de file : le plus court délai observé, depuis le ping précédent, entre la mise en file d'un job de cette file et sa prise par un worker, jamais l'attente du ping lui-même. Ce retard est une mesure, jamais une alerte, et il reste vide sous Laravel 11, et sous Laravel 12 avant la 12.11, dont le job ne porte pas de date de création.
Un heartbeat de file en retard alerte de lui-même, indépendamment du scheduler : quand les deux s'arrêtent, chacun alerte.
Un heartbeat de file peut aussi passer en retard sans que rien ne soit cassé, puisqu'un worker ne pingue qu'entre deux jobs et seulement tant qu'il boucle : un mode maintenance plus long que la tolérance (le worker cesse de boucler, sauf s'il tourne avec --force), un worker en pause (horizon:pause, ou SIGUSR2 envoyé à queue:work), un seul job plus long que la tolérance (y compris un job dont le $timeout propre dépasse le --timeout du worker), des workers lancés seulement de temps en temps (queue:work --stop-when-empty depuis cron ou depuis le scheduler) moins souvent que la tolérance, et queue:listen ou queue:work --once, qui ne pinguent jamais. Dans ces cas, élargissez ici la tolérance de ce heartbeat, que le SDK ne réarme jamais, ou retirez la file de MONITOR_QUEUE_HEARTBEATS et supprimez la ligne.
Pour éteindre un battement automatique, changez la variable côté application (voir Heartbeats du SDK) puis supprimez la ligne ici. Une ligne existante n'est jamais réarmée par le SDK : si vous désarmez un battement automatique, il le reste.
Statuts
| Statut | Signification |
|---|---|
| En attente | Enregistré (ou ré-armé) mais aucun ping encore évalué contre la période. |
| Sain | Le dernier ping est arrivé dans période + tolérance. |
| En retard | Aucun ping dans période + tolérance, l'alerte est partie. |
Chaque minute, le serveur vérifie chaque heartbeat armé : passé dernier ping + période + tolérance, il bascule en retard et déclenche une alerte par panne via les canaux de notification du projet abonnés à l'événement heartbeat.overdue (e-mail, Slack ou webhook, voir Alertes). La protection anti-tempête s'applique.
Le rétablissement est silencieux par conception : le ping réussi suivant repasse le heartbeat en sain, sans notification. L'alerte vous a dit que la tâche est bloquée ; le tableau de bord montre qu'elle est repartie.
Choisir période et tolérance
- Période = le planning de la tâche. Quotidienne → 1440. Horaire → 60.
- Tolérance = le retard normal pour cette tâche. Une sauvegarde qui prend 5 à 40 minutes mérite une tolérance généreuse (60 par exemple) ; une tâche courte peut garder les 5 par défaut.
- Dans le doute, voyez large. Un faux « en retard » à 3 h du matin apprend à ignorer le canal: la seule chose qu'une alerte ne doit jamais faire.
Limites et détails
- Les slugs sont normalisés en minuscules-et-tirets (
nightly-backup) ; créez-les dans l'interface avec le même alphabet, ou laissez le premier ping les créer. - Un projet contient au plus 200 heartbeats: une clé API fuitée ne peut pas inonder la table. Les battements automatiques comptent dans ce total.
- Les pings s'authentifient avec la clé API du projet, comme tout appel d'ingestion (référence API).
- Les heartbeats en retard remontent sur la vue d'ensemble du projet (bandeau d'état) et dans la liste À surveiller du tableau de bord, et comptent comme activité dans le résumé hebdomadaire.
Vous lisez la documentation Quiet Guard v1.0.