Du chaos à la clarté : le reporting d'événements structurés dans Rails


Salut ! Si tu travailles avec Rails depuis un moment, tu as sûrement déjà eu cette sensation familière : ton application grandit, les logs se multiplient, et soudain tu te retrouves à chercher une aiguille dans une botte de foin quand quelque chose plante en production.

Exemple de logs dans Rails

Les logs deviennent rapidement illisibles. Et en production, avec des milliers d'événements cela revient à essayer de déchiffrer la Matrice. Et moi je suis pas Néo !



Aujourd'hui, on va parler d'une solution élégante à ce problème : les événements structurés dans Rails.


Cette approche, développée par l'équipe infrastructure de Shopify, transforme le chaos des logs non structurés en données claires et exploitables. Tu vas découvrir pourquoi c'est important, comment ça fonctionne, et surtout comment l'implémenter dans tes projets Rails.

Qu'est-ce que le reporting d'événements structurés ?

Imagine que ton application Rails soit comme une grande fête. Sans événements structurés, c'est un peu comme si tous les invités parlaient en même temps dans une pièce sombre - tu entends du bruit, mais impossible de comprendre qui dit quoi !


Les événements structurés apportent de l'ordre dans ce chaos. Au lieu d'avoir des logs éparpillés comme :


User login attempt
Database connection failed
Payment processing started
Error: something went wrong


Tu obtiens des événements organisés avec des métadonnées cohérentes :


Rails.logger.info("user.login.attempt", {
user_id: 123,
timestamp: Time.current,
ip_address: "192.168.1.1",
success: false,
error_reason: "invalid_password"
})


L'approche Shopify : résoudre des problèmes à grande échelle

L'équipe infrastructure de Shopify se confronte quotidiennement à des défis que la plupart d'entre nous ne peuvent qu'imaginer. Quand tu gères une plateforme qui traite des millions de transactions par jour, le moindre problème de logging peut devenir un cauchemar.

Pourquoi Shopify s'investit dans Rails

Shopify n'est pas seulement utilisateur de Rails - l'entreprise s'engage activement comme gardienne du framework. Cette philosophie consiste à :


  1. Utiliser Rails de la "bonne façon" en interne
  2. Contribuer aux améliorations du framework open-source
  3. S'assurer que Rails reste viable pour les années à venir
  4. Résoudre des problèmes à l'échelle Shopify puis les redistribuer à la communauté


C'est exactement ce qui se passe avec les événements structurés : une solution née d'un besoin réel chez Shopify, puis partagée avec l'écosystème Rails. Leur commit #55334 sera disponible nativement sur Rails 8.1.


Avant de proposer cette solution, ils ont en testé un paquet avant en interne. Ils en sont arrivé à la conclusion qu'une des meilleurs manière de faire serait d'améliorer le système de logging native de Rails plutôt que d'essayer de développer des systèmes d'analyse par dessus ou des systèmes de logging annexes via des gems.


Leurs objectifs :

  1. Développer un système d'API unifié pour tous les événements dans Rails
  2. Faire en sorte que cela soit plus rapidement à implémenter pour les dev.
  3. Améliorer la qualité des données d'événements et leurs cohérences.
  4. Produire un système agnostique via-à-vis du stack qui va gérer les données produites en aval.
  5. Faciliter la possibilité d'annoter les événements avec toutes les informations qu'on jugerait pertinentes.

La solution proposée ActiveSupport::EventReporter

Pour émettre des événements structurés, vous allez passer par ActiveSupport::EventReporter. Cette interface va fournir les outils pour émettre des événements structurés à des abonnés.

Intégration avec ActiveSupport::Notifications


Pour la petite histoire, Rails propose déjà un service qui est similaire : ActiveSupport::Notifications. Ce dernier est un système de notification qui permet d'instrumenter un bloc de code. Il est alors possible de s'abonner à cette instrumentation et d'être tenu au courant quand le bloc de code en question s'exécute.

Ils peuvent alors réaliser une action spécifique sur la base de cette information ou utiliser les informations d'instrumentation pour une logique internet.


A contrario l'EventReporter est un API purement pour faire du reporting. Il est conçu pour la télémétrie rien de plus. Mais cela fait qu'elle possède des fonctionnalités dédiées comme la capacité de récupérer le contexte ou la capacité d'exporter les événements en suivant un schéma de donnée spécifique.


Les deux API sont complémentaires.


L'émission d'événements avec Event Reporter


Avec l'Event Reporter il sera très simple de nativement émettre des événements comme ici lors de la création d'un nouvel utilisateur. Noté bien les informations supplémentaires que l'on peut ajouter pour avoir le maximum d'information comme le chemin vers le fichier source, la ligne de code et la méthode dans laquelle on émet l'événement.


Et cela en une ligne de code simple et efficace.


Rails.event.notify("user_created", { id: 123 })
# Emits event:
# {
# name: "user_created",
# payload: { id: 123 },
# timestamp: 1738964843208679035,
# source_location: { filepath: "path/to/file.rb", lineno: 123, label: "UserService#create" }
# }


Lors de l'émission on va recevoir un événement avec les clés suivantes


name: String (The name of the event)
payload: Hash, Object (The payload of the event, or the event object itself)
tags: Hash (The tags of the event)
context: Hash (The context of the event)
timestamp: Float (The timestamp of the event, in nanoseconds)
source_location: Hash (The source location of the event, containing the filepath, lineno, and label)


On peut alors s'abonner à cet événement et traiter les informations transmises. Imaginons qu'on ait une classe LogSubscriber. Dans l'exemple, on va :

  1. Valider les données transmises par l'événement (ici le nom et le payload)
  2. Encoder l'événement en JSON (ou un autre format)
  3. Exporter cet événement ainsi encoder


class LogSubscriber
def emit(event)
name = event[:name]
payload = event[:payload]
validate_event(name, payload)
encoded_event = @log_encoder.encode(event)
@log_exporter.exported(encoded_event)
end
end


Ici c'est assez simpliste mais on peut imaginer un processus bien plus avancé comme :

  1. Enregistrez dans une base de donnée
  2. Envoyez un email aux développeurs
  3. etc...

Cela dépend bien entendu de la logique métier que vous souhaitez implémenter. Sky is the limit :)

Les avantages des événements structurés

Meilleure traçabilité des erreurs

Fini le temps où tu passais des heures à grep dans les logs ! Avec des événements structurés, chaque action importante de ton application génère un événement avec un format prévisible.

Monitoring et alertes plus efficaces

Tu peux facilement configurer des alertes basées sur des critères précis :


# Alert si plus de 10 échecs de login en 5 minutes
event_type: "user.login.attempt"
success: false
count > 10
time_window: 5.minutes

Analytics et métriques business

Les événements structurés ne servent pas qu'au debugging - ils deviennent une source précieuse de données pour comprendre le comportement de tes utilisateurs. On parle alors d'événement "business"


Chez Shopify, qui est avant tout une plateforme de e-commerce, ils souhaitent également suivre les événements d'achat par exemple. Ils vont avoir une structure et un schéma souvent plus complexe :


{
"event_name": "order_placed",
"timestamp": "2024-06-15T14:12:36.945Z",
"user_id": "12345",
"order_id": "9876",
"payload": {
"total_amount": 49.99,
"currency": "USD",
"items_count": 3,
"payment_method": "credit_card",
"discount_code": "SPRINGSALE"
},
"context": {
"ip": "8.8.8.8",
"device": "mobile",
"os": "iOS",
"app_version": "2.13.6"
}
}


L'encoding des informations via Protobuf

Chez Shopify ils ont décidé de standardiser tous les événements de leur monolithe Rals avec Protobuf pour avoir des données structurées, cohérentes et faciles à exploiter.


Ok mais c'est quoi Protobuf exactement ?

Qu'est-ce que Protobuf ?

Protobuf (Protocol Buffers) est un format de sérialisation de données développé par Google. Pour faire simple :

  1. C'est un langage de définition de schéma : tu définis la structure de tes données (comme un contrat)
  2. C'est un format de sérialisation : il transforme tes objets en données binaires compactes pour les transporter
  3. C'est multi-langage : tu peux partager des données entre Ruby, Python, Java, etc.

Analogie simple

Imagine que tu veux envoyer un colis (tes données) :

  1. JSON = une boîte en carton transparent avec une étiquette lisible
  2. Protobuf = une boîte compacte, optimisée, avec un mode d'emploi strict


En comparaison :


Critère
JSON
Protobuf
Lisibilité humaine
✅ Très lisible
❌ Binaire (illisible)
Taille des données
❌ Verbose
✅ 3-10x plus compact
Vitesse de traitement
❌ Plus lent
✅ 5-10x plus rapide
Schéma obligatoire
❌ Non
✅ Oui
Validation des données
❌ À la main
✅ Automatique
Compatibilité
✅ Universel
⚠️ Nécessite compilation
Typage fort
❌ Faible
✅ Fort


Quand on est une entreprise de la taille de Shopify et qu'on traite un énorme volume de donnée, un gain si important de performance chiffre vite ! En passant à Protobuf ils peuvent également améliorer la fiabilité, la maintenabilité.

Conclusion


A l'avenir avec l'intégration native de Event Reporter dans Rails, cela va permettre :


  1. D'avoir des événements structurés dans tout Rails : les hooks du framework (requêtes SQL, jobs, etc.) émis comme événements structurés
  2. Une meilleur intégration avec Rails.logger : un subscriber fourni par défaut qui transforme les événements en JSON pour les petites apps
  3. Une meilleure expérience développeur : des logs lisibles en développement, structurés en production


Les événements structurés représentent une évolution naturelle dans la façon dont nous gérons le logging et le monitoring dans nos applications Rails. En transformant le chaos des logs traditionnels en données structurées et exploitables, cette approche nous permet de mieux comprendre, déboguer et optimiser nos applications.


L'engagement de Shopify en tant que gardien de Rails montre comment les grandes entreprises peuvent contribuer positivement à l'écosystème open-source. Les solutions développées pour résoudre des problèmes à grande échelle bénéficient finalement à toute la communauté.


N'hésitez pas à t'abonner pour ne rien louper !


Ci-dessous la vidéo de présentation d'origine faite à Rails World 2025 :






Share it: