Sentry : comment le regroupement d'erreurs transforme les exceptions brutes en incidents traitables
Sentry est une plateforme open source de surveillance des erreurs et de suivi des performances. Sa technique centrale est le regroupement des incidents. Chaque événement entrant rejoint un incident selon une chaîne de priorité : d'abord une empreinte personnalisée, puis des hachages par composants, puis une variante de repli. La configuration de regroupement porte un identifiant de version, si bien que d'anciennes et de nouvelles configurations peuvent coexister. Le dépôt est un monolithe Python de plus de 8 000 fichiers Python. L'ingestion et la symbolisation à haut débit tournent dans des services Rust séparés. La licence est FSL-1.1-Apache-2.0. L'auto-hébergement exige plusieurs services qui collaborent.
Contexte et définition du problème
Lorsque le code de production échoue, un développeur doit répondre à quatre questions. Où l'erreur s'est-elle produite ? Combien d'utilisateurs ont été touchés ? Quelle version l'a introduite ? Comment la reproduire ? Les journaux classiques enregistrent chaque défaillance, mais ils ne regroupent pas des milliers d'enregistrements similaires en un seul problème exploitable. Sentry comble cet écart. C'est une plateforme open source de surveillance des erreurs et de suivi des performances, dont la mission est de transformer des événements bruts en incidents traitables.
La difficulté principale est le regroupement. Un même défaut peut produire des messages, des valeurs de variables et des chemins de pile différents selon l'appareil, la langue et les données saisies. Si le système déduplique sur le texte brut, un seul bogue devient des centaines d'incidents. S'il regroupe seulement par type d'exception, des pannes sans rapport se confondent. Sentry doit trouver une frontière stable entre ces deux excès.
Le dépôt compte environ 45 000 étoiles et son langage principal est Python. Le fichier de licence, LICENSE.md, désigne FSL-1.1-Apache-2.0, la Functional Source License. Le tag fair-source figurant parmi les sujets du dépôt correspond à ce choix. Les équipes peuvent lire le code, l'héberger elles-mêmes et le modifier pour un usage interne. Elles ne peuvent pas s'en servir pour exploiter un service hébergé commercial concurrent.
Cœur de l'architecture et principes techniques
Le dépôt est un vaste monolithe Python. L'arborescence src/sentry et le reste du dépôt contiennent plus de 8 000 fichiers Python au total, et le frontend statique compte environ 8 700 fichiers TSX. L'interface web, l'API publique, les tâches en arrière-plan, le moteur de regroupement et la chaîne d'ingestion se trouvent tous dans cet arbre de code. Le parcours d'un événement comporte trois étapes. La première est le flux d'événements. La classe SnubaProtocolEventStream, à la ligne 85 de src/sentry/eventstream/snuba.py, définit un protocole commun pour les insertions, fusions, séparations et suppressions. KafkaEventStream, à la ligne 63 de src/sentry/eventstream/kafka/backend.py, hérite de ce protocole et publie les messages dans Kafka. Le transport peut changer sans modifier les appelants. La deuxième étape est le regroupement. Dans src/sentry/grouping/variants.py, BaseVariant (ligne 26) est le type racine. ComponentVariant (ligne 113) calcule un hachage à partir des composants de regroupement. CustomFingerprintVariant (ligne 191) permet à un utilisateur de fournir directement une empreinte. FallbackVariant (ligne 106) traite les événements qu'aucune autre variante ne peut hacher. Les composants se trouvent dans src/sentry/grouping/component.py, avec le type d'erreur, le message, le nom de fichier et le nom de fonction (lignes 240 à 252). Chaque configuration de regroupement possède un identifiant et figure dans un registre, à la ligne 8 de src/sentry/grouping/strategies/configurations.py. Des configurations nommées, comme WINTER_2023_GROUPING_CONFIG et FALL_2025_GROUPING_CONFIG, apparaissent dans src/sentry/conf/server.py. Ces configurations versionnées permettent de faire évoluer l'algorithme tout en conservant les anciennes.
La troisième étape couvre la symbolisation et les requêtes. Les plantages natifs, en C, C++, Swift ou Rust, arrivent avec des adresses mémoire brutes. Les symboles de débogage les convertissent en noms de fonctions. L'énumération SymbolicatorFunction, à la ligne 44 de src/sentry/lang/native/symbolicator.py, est l'interface par laquelle le code Python appelle un service Symbolicator externe, qui est un projet distinct. Pour les requêtes, la ligne 1749 de src/sentry/conf/server.py fixe par défaut l'adresse de Snuba à http://127.0.0.1:1218. Snuba est la couche de requête au-dessus de ClickHouse. Elle assure la recherche, les tendances et les statistiques de performance. Le point d'entrée côté SDK est un composant Rust distinct, Relay. Il valide les charges utiles, applique les limites de débit et masque les données sensibles avant de transmettre les événements au code Python. Son implémentation ne figure pas dans ce dépôt. Le runtime exige Python 3.13 ou une version ultérieure, comme l'indique requires-python = ">=3.13" dans pyproject.toml.
Évaluation pratique et applications
Le regroupement est la fonctionnalité qui mérite le plus d'attention. À l'arrivée d'un événement, le moteur essaie les variantes dans l'ordre de priorité. Une empreinte personnalisée correspondante l'emporte. Sinon, les hachages des composants décident, et la variante de repli couvre le reste. Lorsqu'un utilisateur modifie les règles de regroupement dans l'interface, il change cette chaîne de priorité. Une telle modification peut donc scinder ou fusionner des incidents existants. Trois dimensions comptent pour une évaluation. D'abord, la largeur de l'intégration. Le README liste 21 SDK officiels, couvrant JavaScript, Python, Go, Rust, Java et Kotlin, Swift, C#, C et C++, Dart, ainsi que des moteurs de jeu comme Unity et Godot. Une équipe peut commencer avec un seul SDK et en ajouter ensuite. Ensuite, le poids opérationnel. Le dépôt d'auto-hébergement getsentry/self-hosted contient docker-compose.yml, install.sh, un répertoire clickhouse et un fichier nginx.conf. Cette structure reflète un déploiement complet : base relationnelle, files de messages, stockage en colonnes, service de requêtes et proxy inverse fonctionnent ensemble. Une équipe qui veut seulement un outil de remontée de plantages peut juger l'ensemble trop lourd. Une équipe qui veut maîtriser ses données accepte ce coût.
Enfin, la licence fixe une limite. FSL-1.1-Apache-2.0 autorise l'usage interne, la modification et l'auto-hébergement. Elle interdit d'offrir un service commercial concurrent construit à partir du code. La plupart des équipes de plateforme interne n'atteindront jamais cette limite. Une entreprise qui prévoit un produit hébergé la rencontrera. En pratique, testez d'abord une modification de règle de regroupement sur un projet de préproduction. Comparez le nombre d'incidents avant et après, puis seulement ensuite changez les règles de production.
Impact sur le secteur et perspectives
Sentry a influencé la manière dont le secteur conçoit les erreurs. Le projet traite le regroupement comme un objet d'ingénierie, avec des versions, des identifiants et des tests, et non comme une heuristique cachée. Cette approche a aussi inspiré la présentation de l'agrégation des incidents dans d'autres outils de supervision.
La licence illustre un compromis que d'autres projets d'infrastructure ont également adopté. Le code source est public et lisible. L'usage interne est permis. La revente directe est restreinte, et le code devient Apache 2.0 après une période fixe. Les développeurs ne s'accordent pas sur le fait que ce modèle relève de l'open source, et le débat continue.
Le dépôt laisse voir trois signaux. Premièrement, les configurations de regroupement nommées se multiplient, ce qui signifie que l'algorithme évolue par versions. Deuxièmement, les parties critiques pour le débit, l'ingestion et la symbolisation, reposent déjà sur des composants Rust. Troisièmement, il s'agit de la perspective de l'auteur et non d'un fait vérifié dans ce code : les équipes vont probablement concentrer davantage leurs données d'observabilité sur une seule plateforme.
Sources
FAQ
Quelle licence le dépôt Sentry utilise-t-il ?
LICENSE.md désigne FSL-1.1-Apache-2.0, la Functional Source License 1.1, qui prévoit une conversion future en Apache 2.0. Le code peut être lu et modifié, mais il ne peut pas servir à exploiter un service hébergé commercial concurrent.
Comment Sentry décide-t-il que deux erreurs appartiennent au même incident ?
Le moteur de regroupement essaie les variantes dans l'ordre de priorité. Une empreinte personnalisée correspondante l'emporte. Sinon, les hachages construits à partir du type d'erreur, du message, du nom de fichier et du nom de fonction décident. La variante de repli traite le reste. Source : src/sentry/grouping/variants.py.