La plupart des incidents en production d'un SaaS B2B sont d'abord détectés par les clients, pas par l'éditeur. C'est un constat qui revient sur quasiment chaque mission de reprise de maintenance : un disque qui sature, un certificat TLS qui expire, une exception PHP qui boucle en silence, un processus PHP-FPM qui meurt sans relance, et l'équipe découvre le problème au premier ticket support. Le monitoring d'un SaaS Symfony sérieux repose sur deux couches complémentaires : la supervision du serveur Linux et celle de l'application elle-même. Cet article détaille la stack que je déploie sur mes propres projets - Zabbix côté serveur Debian, Bugsink (alternative open source self-hosted compatible API Sentry) côté application Symfony - le maillage d'alertes qui va avec, et les arbitrages avec les alternatives (Sentry SaaS, Grafana/Prometheus, Datadog, Netdata). Pour la vue d'ensemble de la prestation, voyez ma page Développement SaaS sur-mesure.
Les 2 couches à monitorer : serveur Linux et application Symfony
Un SaaS Symfony tombe pour deux familles de causes très différentes, et un seul outil ne peut pas couvrir les deux correctement.
- La couche serveur : disque qui sature, swap qui s'effondre, CPU saturé par un cron mal calibré, certificat TLS proche de l'expiration, MariaDB qui refuse les connexions, service systemd arrêté, charge réseau anormale. Tout ce qui se mesure depuis l'OS Debian sans connaître l'application.
- La couche application : exception PHP non gérée, requête Doctrine qui boucle, dépendance externe indisponible, latence anormale sur une route, déploiement qui casse un parcours utilisateur, fuite mémoire. Tout ce qui n'a aucun sens vu de l'OS mais qui détruit l'expérience client.
Ces deux familles d'incidents ont des temporalités différentes : la couche serveur dérive lentement (un disque met des jours à se remplir, un certificat se renouvelle 30 jours avant l'échéance), la couche application explose en quelques minutes (un déploiement bancal peut générer 10 000 erreurs avant que vous le voyiez). Mélanger les deux dans un même outil c'est avoir du bruit sur l'une et de l'aveuglement sur l'autre. D'où l'architecture multi-couches.
Zabbix pour superviser le serveur Debian
Sur tous mes projets d'hébergement SaaS, le serveur Debian est supervisé par Zabbix. C'est un outil open source mature, déployé sur des dizaines de milliers d'infrastructures en production, et il fait ce pour quoi il a été conçu : remonter des métriques système sur un agent installé localement et déclencher des alertes selon des seuils configurables. Concrètement, voici ce que Zabbix surveille en permanence sur un nœud Debian qui héberge un SaaS Symfony :
- Ressources système : CPU, RAM, swap, charge moyenne, espace disque par partition, inodes restantes.
- Services critiques : nginx, PHP-FPM, MariaDB, Redis, systemd-timers, présence des processus, état des sockets.
- Réseau et TLS : interfaces actives, bande passante consommée, dates d'expiration des certificats Let's Encrypt et autres autorités, réponse HTTP de l'application.
- Sauvegardes : présence du dernier dump MariaDB, taille comparée à la veille, succès de la rotation sur le stockage distant.
- Base de données : connexions actives, requêtes lentes, taille des tables, lag de réplication s'il y en a un.
Le serveur Zabbix lui-même est hébergé sur un nœud séparé, idéalement chez un autre fournisseur ou dans un autre datacenter. C'est une règle de bon sens : si votre monitoring tombe avec votre application, vous n'êtes plus prévenu de rien. Pour le contexte plus large du monitoring dans la maintenance long terme d'un SaaS, voyez mon article Maintenance SaaS sur 5 ans : périmètre et inclusions.
Bugsink pour traquer les exceptions Symfony (alternative open source à Sentry)
Zabbix ne voit pas qu'une exception PHP boucle, ne sait pas qu'un parcours utilisateur génère 500 erreurs après un déploiement, n'a pas la stack trace d'un crash applicatif. Pour cette couche applicative, j'utilise Bugsink, un projet open source self-hosted qui implémente l'API Sentry et reste compatible avec le SDK officiel sentry/sentry-symfony. Concrètement, c'est le même bundle Symfony, la même intégration, mais le serveur de collecte est hébergé en France sur un nœud Debian que je maîtrise. Aucune donnée d'exception ne sort de votre périmètre. Bugsink remplit trois fonctions critiques pour un SaaS en production :
- Capture des exceptions non gérées avec stack trace complète, contexte de la requête (utilisateur, route, paramètres), variables locales et environnement de déploiement. Une exception qui se produit à 3 h du matin sur le serveur arrive dans Bugsink avec tout ce qu'il faut pour la reproduire et la corriger.
- Suivi des performances applicatives via le tracing distribué : latence des requêtes HTTP, temps passé en base de données, temps d'exécution des templates Twig, appels externes (API tierces, Redis, etc.). C'est ce qui permet de comprendre pourquoi une route est passée de 200 ms à 2 s entre deux releases.
- Corrélation déploiement / régression : chaque release Symfony est notifiée à Bugsink. Une exception qui apparaît après le tag d'une nouvelle version est immédiatement attribuée à ce déploiement. Le rollback ou le hotfix est décidé en quelques minutes au lieu de quelques heures.
Cette stack s'inscrit aussi dans la conformité OWASP. L'OWASP Top 10 A09:2021 - Security Logging and Monitoring Failures classe l'absence de log et d'alerting parmi les 10 risques applicatifs majeurs. Un canal Monolog dédié security qui pousse vers Bugsink couvre cette exigence sans usine à gaz, en gardant les logs sensibles sur votre propre infrastructure. Pour la complémentarité côté navigateur, le monitoring RUM est traité dans mon guide Core Web Vitals SaaS Symfony.
Le maillage des alertes : règles, canaux, bruit acceptable
Un monitoring qui crie tout le temps finit ignoré comme un sous-bois en automne. La règle d'or : une alerte qui se déclenche doit toujours appeler une action humaine. Si une alerte n'appelle pas d'action, c'est qu'elle est mal calibrée et qu'elle doit être supprimée ou ajustée. Sur mes projets, le maillage tient en 4 niveaux.
| Niveau | Exemples | Canal | Délai de réponse cible |
|---|---|---|---|
| P1 critique | Site down, MariaDB inaccessible, certificat expiré, exception qui boucle 100 fois/min | SMS + Slack + email | 15 minutes (24/7 selon SLA) |
| P2 dégradation | Disque à 85 %, latence x 5 sur une route, taux d'erreur HTTP > 1 % | Slack + email | 2 heures (heures ouvrées) |
| P3 dérive | Sauvegarde plus petite que la veille, certificat à 21 jours, requête lente récurrente | Email seul | Sous 48 heures |
| P4 information | Release publiée, métriques quotidiennes, rapport hebdomadaire | Dashboard + digest | Pas de SLA |
Cette hiérarchie évite deux écueils opposés : la sous-alerte qui rate un incident grave, et la sur-alerte qui pousse l'équipe à filtrer mentalement les notifications. À chaque ajout d'une nouvelle règle d'alerte, posez-vous deux questions : quel est le niveau, et quelle est l'action déclenchée. Si vous n'avez pas de réponse claire aux deux, ne créez pas la règle.
Cas terrain : un incident résolu en 7 minutes
Un client éditeur SaaS B2B que j'accompagne en maintenance long terme a déployé une release un mardi en début d'après-midi. Vingt minutes plus tard, Bugsink remontait 200 exceptions du même type sur une route critique du parcours d'inscription. L'alerte P1 a déclenché un SMS et un message Slack. Diagnostic en 4 minutes : un changement de schéma sur une entité non couvert par les fixtures de recette. Décision : rollback du déploiement. Mise en œuvre via le pipeline CI/CD : 3 minutes. Total entre l'apparition de l'erreur et le retour à un état stable : 7 minutes.
Sans cette couche applicative de monitoring, le scénario aurait été : aucune alerte, le bug reste en prod, les 200 utilisateurs concernés voient une erreur 500, certains envoient un mail au support le soir, l'équipe découvre le problème le lendemain matin et passe deux heures à reproduire l'incident. Coût opérationnel évité : une demi-journée d'investigation et des dizaines de tickets support frustrés. C'est exactement ce qu'un monitoring multi-couches est censé acheter.
Arbitrage stack alternatives : Grafana/Prometheus, Datadog, Netdata
Zabbix + Bugsink n'est pas la seule combinaison valable. Voici les alternatives courantes et pourquoi je n'y suis pas allé sur mes projets.
- Sentry SaaS : la référence du marché de l'APM applicatif, intégration native avec Symfony via
sentry/sentry-symfony, dashboards très aboutis, offre gratuite jusqu'à 5 000 événements / mois. L'inconvénient : hébergement aux États-Unis pour l'offre standard, dépendance à un éditeur tiers pour un sujet critique, facturation à la consommation au-delà du palier gratuit. C'est précisément ce que Bugsink remplace, en gardant le même SDK Symfony et la même mécanique, mais en self-hosting sur votre infrastructure souveraine. - Grafana + Prometheus + Loki : excellente stack open source moderne, très puissante pour les architectures Kubernetes ou microservices, avec une expérience visuelle supérieure à Zabbix. L'inconvénient : la courbe d'apprentissage et le temps de mise en place sont nettement plus élevés. Pour un SaaS monolithique Symfony hébergé sur 1 à 3 nœuds Debian, le ROI n'est pas au rendez-vous. Pour un SaaS plus large, la bascule devient pertinente.
- Datadog : SaaS commercial très complet, intégrations prêtes à l'emploi pour Symfony, agent unifié pour métriques système et APM. L'inconvénient : facturation à la consommation qui dérive vite, hébergement aux États-Unis et donc Cloud Act, dépendance à un éditeur tiers pour un sujet critique. Disqualifié sur les projets B2B européens à enjeu RGPD fort.
- Netdata : très bon outil d'observabilité système temps réel, agent ultra-léger, dashboards instantanés. Excellent en complément ponctuel pour debugger un nœud, mais moins solide que Zabbix sur la persistance long terme des métriques et la gestion fine des alertes multi-nœuds.
Mon arbitrage : Zabbix pour la maturité et la sobriété côté serveur, Bugsink pour l'APM Symfony en self-hosting compatible SDK Sentry. Combo 100 % open source, stack hébergée en France pour les deux, aucune donnée d'erreur ni de métrique qui sort de l'Union. Architecture simple à reprendre par un autre prestataire ou par une équipe interne le jour où vous voulez internaliser. Pour la cohérence d'ensemble avec une architecture multi-tenant, voyez aussi mon guide Développer un SaaS multi-tenant en PHP.
Mise en place pratique : ordre de priorité et budget temps
Sur un SaaS existant sans monitoring, l'ordre de bataille que j'applique tient en 4 étapes incrémentales. Chacune apporte une valeur immédiate avant de passer à la suivante.
- Étape 1 - Bugsink sur l'application Symfony : 1 journée (provisionnement du nœud Bugsink + 1 demi-journée d'intégration). Installation du bundle
sentry/sentry-symfonycôté app, configuration de l'endpoint vers votre serveur Bugsink, premier déploiement. À la sortie, vous voyez les exceptions en temps réel et vous découvrez souvent que la prod logue déjà des erreurs que personne ne lisait. - Étape 2 - Zabbix sur le nœud applicatif : 1 journée. Provisionnement du serveur Zabbix, installation de l'agent sur le nœud à monitorer, premiers seuils standards (CPU, RAM, disque, services). À la sortie, vous savez en temps réel quand un disque sature.
- Étape 3 - Maillage d'alertes P1 / P2 / P3 / P4 : 1 demi-journée. Définition des règles, configuration des canaux Slack et SMS, test grandeur nature avec un faux incident. À la sortie, vous êtes prévenu correctement et vous n'avez pas de bruit parasite.
- Étape 4 - Tableaux de bord et rituels mensuels : 1 demi-journée. Construction du dashboard principal, mise en place d'un point mensuel de revue des métriques avec l'équipe ou avec moi. À la sortie, le monitoring devient un outil de pilotage, pas juste un outil de réaction.
Soit environ 3 jours de travail pour passer d'aucun monitoring à une couverture sérieuse multi-couches. C'est typiquement ce que j'intègre au cadrage d'un contrat de maintenance long terme. Le périmètre et le tarif sont définis sur devis personnalisé après un échange initial gratuit de 30 minutes. Pour la lecture complémentaire sur la sécurité, mon article audit cybersécurité TPE détaille la cohérence monitoring / logs / journalisation sécurité. Le formulaire de contact permet de prendre date.