Le compteur de vues qui a transformé notre catalogue en 502
Livraison
La page qui liste tous les Kits que nous vendons a répondu à chaque visiteur par une erreur 502 Bad Gateway pendant environ 41 heures après le lancement. La page propre à chaque Kit fonctionnait, la page d'accueil fonctionnait, le paiement fonctionnait. La partie cassée était quelques lignes qui comptaient les vues de pages.
Le bug
Le serveur de notre boutique compte les visites sur les pages de Kits. Pour identifier le Kit concerné par une requête, il prenait la deuxième partie du chemin :
self._count_view(path.strip("/").split("/")[1] if path.count("/") >= 2 else "")
Pour /kits/studio/, cela donne studio. Pour le catalogue lui-même, /kits/, le chemin contient deux barres obliques, donc le garde-fou l'a laissé passer, mais après suppression des barres obliques, il ne reste qu'une seule partie, et [1] a levé une IndexError. Le gestionnaire est le module standard http.server de Python : une exception dans do_GET ferme la connexion sans réponse, et Cloudflare affichait au visiteur une erreur 502.
La correction est une petite fonction qui renvoie une chaîne vide lorsque la partie est manquante. Le compteur de vues n'avait besoin que du nom du Kit ; il n'avait jamais besoin de pouvoir casser la page qu'il comptait.
Pourquoi aucun de nos contrôles ne l'a détecté
- La surveillance de disponibilité ne testait que les pages d'accueil. La page d'accueil fonctionnait bien.
- L'étape de publication vérifiait chaque Kit livré : sa page, sa redirection de paiement, le parcours payant de bout en bout. Elle n'ouvrait jamais la liste de tous les Kits.
- Les analyses ne pouvaient pas le montrer. Le code qui aurait dû compter les visiteurs du catalogue était celui qui plantait. Le journal du serveur avait la réponse depuis le début : 17 tracebacks durant ces 41 heures, chacun correspondant à une requête, d'une personne ou d'un crawler, qui a reçu une erreur au lieu de la page.
Ce qui a changé
- Chaque page, depuis l'extérieur, chaque heure. Une petite tâche lit le sitemap et ouvre chaque page en anglais et, à tour de rôle, une des 42 autres langues, via Cloudflare comme un visiteur. Deux échecs consécutifs envoient un e-mail ; la récupération en envoie un autre.
- L'étape de publication ouvre chaque page en anglais après avoir reconstruit le site, et refuse de se terminer si l'une d'elles ne répond pas 200.
- Les pages d'index comptent comme des pages. Les pages qui listent d'autres pages sont celles qu'un visiteur atteint en premier, et c'est celles que personne n'avait testées.
À retenir
Les tâches annexes dans un gestionnaire de requêtes, telles que le comptage, la journalisation ou le suivi, ne doivent jamais faire échouer la requête, et une vérification de page qui ne couvre que les pages que vous venez de modifier passe à côté de celles qui pointent vers elles. Le Chien de garde de Night Watch accepte n'importe quelle liste de pages, chacune avec le texte qu'elle doit contenir, pas seulement les pages d'accueil.