Un WordPress en production tombe rarement d'un coup. Il se dégrade, et les signes existent plusieurs jours avant l'incident : une erreur qui se répète dans le journal, un temps de réponse qui glisse, une tâche planifiée qui ne s'exécute plus. La supervision d'un site WordPress consiste à récupérer ces signes et à en tirer un petit nombre d'alertes qui déclenchent une action. La difficulté n'est pas de collecter, tout le monde sait activer un journal, mais de trier : un dispositif qui envoie quarante messages par jour ne sera plus lu au bout d'une semaine, et il vaudra alors moins que pas de dispositif du tout, puisqu'il donnera en plus l'illusion d'une surveillance.

Les journaux, et ce qu'il faut en faire

Trois journaux distincts se superposent sur un site WordPress, avec des contenus différents et des usages différents : celui du serveur web, celui de PHP et celui de l'application elle même. Les confondre conduit à chercher une erreur au mauvais endroit, et à conclure trop vite qu'il n'y a rien. Cette distinction fait partie des premiers réflexes que nous transmettons dans la rubrique WordPress quand un site nous est confié.

Activer le journal PHP sans l'afficher

WordPress dispose d'un mode de débogage qui, correctement configuré, écrit les erreurs dans un fichier au lieu de les afficher à l'écran. C'est cette combinaison qu'il faut viser en production : la journalisation active, l'affichage désactivé. Beaucoup de sites font l'inverse par accident, ce qui expose des chemins de fichiers et des extraits de requêtes aux visiteurs et aux robots, et constitue une fuite d'information à part entière. Le fichier produit doit par ailleurs se trouver hors du dossier accessible par le web, ou être protégé, faute de quoi il est lisible par n'importe qui connaissant son nom, qui est standard.

Distinguer l'avertissement de l'erreur fatale

Le journal PHP mélange des niveaux très différents. Une erreur fatale arrête l'exécution et produit une page blanche ou un message d'erreur pour le visiteur : c'est un incident. Un avertissement ou une notice signale un code approximatif mais n'empêche rien, et peut se répéter des milliers de fois par jour sans conséquence visible. Traiter les deux de la même manière rend le journal illisible. La méthode qui fonctionne consiste à ne déclencher d'alerte que sur les erreurs fatales et sur les exceptions non capturées, et à traiter les avertissements par un rapport hebdomadaire agrégé, où seul le nombre d'occurrences par message compte.

Agréger plutôt que lister

Un journal utile ne se lit pas ligne à ligne, il se compte. Le traitement minimal consiste à regrouper les lignes par message normalisé, c'est à dire en retirant les valeurs variables comme les identifiants et les chemins, puis à trier par nombre d'occurrences. Cette opération réduit un fichier de quarante mille lignes à une liste d'une dizaine de messages distincts, dont la lecture prend deux minutes et dont l'évolution d'une semaine à l'autre est immédiatement parlante. Un message nouveau apparu cette semaine mérite toujours un regard, même s'il n'est pas fatal.

Faire tourner et purger

Un journal qui n'est jamais purgé finit par saturer le disque, ce qui provoque une panne bien plus grave que celle qu'il documentait. La rotation doit donc être en place dès l'activation, avec une conservation de quelques semaines, largement suffisante pour l'usage courant. Sur les hébergements mutualisés où l'outil de rotation du système n'est pas accessible, une tâche planifiée qui tronque le fichier au delà d'une certaine taille remplit le même office et évite le scénario, courant, du site indisponible pour cause de quota atteint par son propre journal d'erreurs.

Le journal du serveur, pour les codes de réponse

Le journal d'accès du serveur ne contient aucune erreur PHP mais renseigne ce que PHP ignore : les codes de réponse réellement servis, les temps de réponse et l'identité des demandeurs. C'est là qu'on voit une montée d'erreurs 500 sur une adresse précise, une avalanche de 404 provoquée par un lien cassé sur un site tiers, ou une tentative d'accès répétée à des fichiers d'installation. Un comptage quotidien des codes de réponse par famille, conservé dans un fichier, suffit à repérer une anomalie en un coup d'œil sans aucun outil spécialisé.

Journaliser depuis le code applicatif

Le troisième journal est celui que le site produit lui même, et il est presque toujours absent. Il consigne des événements métier plutôt que des erreurs techniques : un paiement refusé, un envoi de courriel en échec, un appel à un service externe qui a expiré, un import interrompu. Ces événements ne provoquent aucune erreur PHP et n'apparaissent donc nulle part, alors qu'ils sont exactement ce qu'un exploitant a besoin de savoir. Écrire ces lignes dans un fichier dédié, avec un horodatage, un niveau et un contexte minimal, coûte quelques lignes de code au moment où l'on écrit la fonctionnalité et devient irremplaçable le jour où un client signale que quelque chose ne s'est pas produit.

Journal d’erreurs PHP filtré pour ne conserver que les incidents réels

Surveiller la disponibilité et la vitesse

La question qui vient avant toutes les autres est simple : le site répond il ? Elle mérite une surveillance externe, car un dispositif hébergé sur la machine surveillée ne dira rien le jour où la machine est en panne. Cette surveillance complète naturellement le suivi des correctifs décrit dans notre article sur la manière de surveiller les mises à jour de plugins avec WP-CLI.

Vérifier une page, pas la racine

Interroger seulement la page d'accueil laisse passer une grande partie des pannes réelles, car l'accueil est souvent la page la plus fortement mise en cache. Le contrôle doit porter sur au moins trois adresses de nature différente : l'accueil, une page de contenu profonde et une adresse qui déclenche réellement du code, par exemple un point de l'interface de programmation. Vérifier en plus la présence d'une chaîne de caractères attendue dans la réponse évite le faux positif classique, celui d'un serveur qui répond correctement une page d'erreur de maintenance.

Choisir un intervalle réaliste

Une vérification toutes les minutes produit un volume d'alertes que la plupart des sites ne justifient pas, chaque micro coupure réseau devenant un message. Un intervalle de cinq minutes, avec confirmation par deux échecs consécutifs avant alerte, donne un compromis raisonnable : la détection reste rapide, les fausses alertes disparaissent presque entièrement. La règle générale est que le délai de détection doit être proportionné au délai de réaction possible : détecter en une minute une panne à laquelle personne ne pourra répondre avant deux heures n'apporte rien.

Suivre le temps de réponse, pas seulement la disponibilité

Un site qui répond en huit secondes est en panne du point de vue de l'utilisateur, et parfaitement disponible du point de vue d'un contrôle binaire. Enregistrer le temps de réponse à chaque vérification, et alerter quand la moyenne sur une heure dépasse un seuil, capte les dégradations progressives qui précèdent presque toujours l'indisponibilité complète. Ce même relevé sert ensuite à mesurer l'effet réel d'une optimisation, ce qu'aucune mesure ponctuelle ne permet.

Surveiller le certificat et le domaine

Deux pannes évitables reviennent régulièrement : le certificat expiré et le nom de domaine non renouvelé. La première rend le site inaccessible avec un message alarmant pour le visiteur, la seconde le fait disparaître entièrement. Les deux se surveillent par une vérification quotidienne de la date d'expiration, avec une alerte trente jours puis sept jours avant l'échéance. C'est une surveillance triviale à mettre en place, et son absence explique une part non négligeable des interruptions les plus longues, parce que la remise en service dépend d'un tiers.

Contrôler les tâches planifiées

Les tâches planifiées de WordPress dépendent du trafic pour se déclencher, ce qui les rend silencieusement défaillantes sur un site peu visité ou dont le mécanisme a été désactivé au profit d'une planification système mal configurée. Les conséquences sont discrètes et sérieuses : sauvegardes non exécutées, courriels non envoyés, publications programmées jamais publiées. Le contrôle consiste à vérifier qu'aucune tâche n'est en retard au delà d'un délai raisonnable, information que la ligne de commande expose directement.

Ce qui est surveillé Fréquence Seuil de déclenchement d'une alerte
Disponibilité de trois adresses Toutes les cinq minutes Deux échecs consécutifs
Temps de réponse Toutes les cinq minutes Moyenne horaire au dessus du double de la normale
Erreurs fatales PHP Continu Toute occurrence nouvelle
Codes 5xx dans le journal serveur Horaire Plus de dix sur une heure
Expiration du certificat et du domaine Quotidienne Trente jours, puis sept jours
Tâches planifiées en retard Quotidienne Retard de plus de six heures

Surveiller l'espace disque et la base

Deux ressources s'épuisent silencieusement et provoquent des pannes brutales : l'espace disque et la taille de la base de données. La première se remplit de sauvegardes accumulées, de journaux non purgés et de miniatures régénérées ; la seconde gonfle de révisions d'articles, d'options temporaires jamais nettoyées et de tables laissées par des extensions désinstallées. Un relevé quotidien de ces deux valeurs, avec une alerte à quatre vingts pour cent d'occupation, laisse le temps d'agir. Sans lui, la panne survient sans préavis et se manifeste par des symptômes déroutants, une impossibilité d'enregistrer un article ou des images qui ne s'affichent plus.

Détecter les modifications non prévues

La deuxième famille de surveillance ne porte pas sur le fonctionnement mais sur l'intégrité. Un site peut fonctionner parfaitement et avoir été modifié à l'insu de son propriétaire, ce qui est précisément le but recherché par la plupart des compromissions actuelles, dont l'objectif n'est plus de dégrader le site mais de s'en servir. Cette surveillance prolonge le travail décrit dans notre article sur la manière de mener un audit de sécurité WordPress.

Comparer les fichiers du cœur à la référence

Les fichiers du noyau de WordPress sont publiés avec des sommes de contrôle officielles, ce qui permet de vérifier qu'aucun n'a été modifié. La ligne de commande propose cette vérification en une seule instruction, et son résultat doit être vide. Toute divergence est significative : le noyau n'a aucune raison légitime d'être modifié, et un fichier altéré ou ajouté dans ses dossiers est un signal fort. Ce contrôle prend quelques secondes et gagne à être exécuté quotidiennement, avec alerte immédiate en cas de divergence.

Surveiller les dossiers qui ne devraient pas changer

Au delà du noyau, un site en production comporte des zones dont le contenu ne devrait pas bouger entre deux déploiements : les dossiers du thème, ceux des extensions, la racine. Enregistrer une empreinte de chaque fichier de ces zones, puis comparer quotidiennement, révèle immédiatement l'ajout d'un fichier inattendu, y compris quand il porte un nom anodin. La médiathèque, qui change en permanence, s'exclut de ce contrôle, mais mérite une surveillance différente : aucun fichier exécutable ne devrait s'y trouver, ce qui se vérifie par une simple recherche d'extensions.

Suivre les comptes à privilèges

La création d'un compte administrateur est l'étape qui suit presque toujours une compromission réussie, car elle assure la persistance de l'accès même après correction de la faille initiale. Une vérification quotidienne du nombre de comptes ayant ce niveau de droits, comparée à une liste attendue, détecte cette création. Le même contrôle mérite d'être étendu aux clés d'application et aux comptes de service, plus discrets encore, dont l'existence est souvent oubliée par ceux là mêmes qui les ont créés.

Repérer les modifications de contenu en masse

Une injection de contenu se traduit par la modification simultanée de nombreux articles, ou par l'apparition de contenus dont personne ne revendique la paternité. Un relevé quotidien du nombre d'articles modifiés dans les vingt quatre heures, comparé au rythme éditorial connu, suffit à lever une alerte : un site qui publie trois articles par jour et en voit deux cents modifiés en une nuit a un problème. Ce contrôle simple attrape des incidents qu'aucune surveillance de fichiers ne verrait, l'injection portant sur la base et non sur le disque.

Conserver les traces suffisamment longtemps

Une compromission est souvent découverte plusieurs semaines après son début, et l'enquête dépend entièrement de ce qui a été conservé. Garder les journaux d'accès et d'erreurs sur au moins soixante jours, hors de la machine surveillée, change complètement les chances de comprendre par où l'accès s'est fait. Cette conservation coûte quelques centaines de mégaoctets, ce qui est sans commune mesure avec le coût d'une reprise à l'aveugle où l'on ne peut que tout réinstaller en espérant que la porte d'entrée a disparu.

Ce qui alerte réellement en premier lors des incidents constatés sur des sites en production
Contrôle externe de disponibilité
34 %
Signalement par un utilisateur
26 %
Journal d'erreurs surveillé
18 %
Contrôle d'intégrité des fichiers
13 %
Alerte de l'hébergeur
9 %

Origine de la première détection sur des incidents survenus en production. Le signalement par un utilisateur reste la deuxième source, ce qui mesure exactement ce que la supervision n'a pas vu.

Construire un dispositif qu'on lira encore dans six mois

La difficulté finale n'est pas technique. Un dispositif de surveillance meurt de deux façons, par excès de messages ou par absence totale de retour, et les deux se préviennent par des choix simples faits au moment de la mise en place.

Une alerte doit correspondre à une action

Le critère qui permet de trier est le suivant : si la réception du message ne conduit à rien faire, il ne doit pas être une alerte. Une charge processeur élevée pendant dix minutes, un pic de trafic, un avertissement PHP récurrent connu ne justifient aucune intervention et n'ont donc rien à faire dans un canal d'alerte. Ils peuvent en revanche figurer dans un rapport hebdomadaire, où ils servent à suivre une tendance. Cette séparation entre ce qui interrompt et ce qui informe est le seul moyen de conserver la crédibilité du canal d'interruption.

Choisir le bon canal selon l'urgence

Toutes les alertes ne méritent pas le même dérangement. Une indisponibilité complète justifie une notification immédiate sur un téléphone, une divergence de fichiers du noyau justifie un courriel dans l'heure, un rapport de tendances se lit le lundi matin. Utiliser un canal unique pour ces trois niveaux revient à traiter le rapport hebdomadaire comme une urgence ou l'urgence comme un rapport, et c'est en général le second cas qui se produit.

Documenter la réponse en même temps que l'alerte

Une alerte utile indique quoi faire. Écrire, au moment où on met en place un contrôle, la marche à suivre correspondante, même en trois lignes, transforme le dispositif en outil utilisable par quelqu'un d'autre. Sans cette note, l'alerte réveille une personne qui redécouvre le problème à chaque fois, et la première réaction devant un message inconnu est de le classer sans suite, ce qui vide le dispositif de son sens.

Tester le dispositif lui même

Un contrôle qui ne s'est jamais déclenché n'a pas été vérifié. Provoquer volontairement chaque condition d'alerte, une fois, à la mise en place, est le seul moyen de savoir que la chaîne fonctionne de bout en bout, de la détection jusqu'à la réception du message. Cet essai révèle presque toujours au moins un maillon défaillant : une adresse mal saisie, un envoi classé en indésirable, un service tiers qui exige une confirmation jamais donnée. Le refaire une fois par an suffit à garantir que le dispositif n'est pas devenu décoratif.

Adapter le dispositif à l'enjeu réel du site

Tout ce qui précède ne se met pas en place partout. Un site vitrine de dix pages se contente d'un contrôle de disponibilité, d'une alerte sur le certificat et d'une sauvegarde vérifiée, ce qui représente une heure de mise en place. Une boutique qui encaisse des paiements ou un site de contenu vivant de son trafic justifient l'ensemble du dispositif, parce que quelques heures d'indisponibilité s'y chiffrent. Poser cette question au démarrage, en estimant simplement ce que coûte une journée de panne, évite les deux erreurs symétriques : surveiller lourdement un site sans enjeu, et laisser sans filet celui dont dépend une activité.