• Contenu
  • Bas de page
logo ouidoulogo ouidoulogo ouidoulogo ouidou
  • Qui sommes-nous ?
  • Offres
    • 💻 Applications métier
    • 🤝 Collaboration des équipes
    • 🛡️ Sécurisation et optimisation du système d’information
    • 🔗 Transformation numérique
  • Expertises
    • 🖥️ Développement logiciel
    • ♾️ DevSecOps
    • ⚙️ Intégration de logiciels et négoce de licences
      • Atlassian : Jira, Confluence, Bitbucket…
      • Plateforme monday.com
      • GitLab
      • SonarQube
    • 📚​ Logiciel de CRM et de gestion
    • 🎨 UX/UI design
    • 🌐 Accessibilité Numérique
    • 🗂️​ Démarches simplifiées
    • 📝 Formations Atlassian
  • Références
  • Carrières
    • 🧐 Pourquoi rejoindre Ouidou ?
    • ✍🏻 Nous rejoindre
    • 👨‍💻 Rencontrer nos collaborateurs
    • 🚀 Grandir chez Ouidou
  • RSE
  • Ressources
    • 🗞️ Actualités
    • 🔍 Articles techniques
    • 📖 Livres blancs
    • 🎙️ Interviews Clients
Nous contacter
✕
Les nouveautés Atlassian du mois d’octobre
Les nouveautés Atlassian du mois d’octobre
24 octobre 2024
Image miniature Implémenter GraphQL avec Ruby on Rails
Implémenter GraphQL avec Ruby on Rails 🔻
5 novembre 2024
Ressources > Articles techniques > Enrichir les événements Sentry

Enrichir les événements Sentry

Article écrit par Hugo F.

Enrichir les événements Sentry

L’usage basique de Sentry (ou outil équivalent) est répandu et bien connu de la plupart des développeurs.

Seulement, il arrive que certains bugs se produisent dans un contexte assez particulier où simplement recevoir une alerte avec le code incriminé ne suffise pas forcément à trouver la source.

L’idée de cet article est de présenter certaines (parce qu’il y en a beaucoup et différentes selon les SDK) fonctionnalités mises en place par Sentry pour nous aider.

Pour ma part, les exemples seront en Rails avec le SDK officiel, mais je pense que toutes les fonctions que nous allons voir sont disponibles dans tous les SDK.

Prérequis

Je ne vais rien présenter de très complexe, mais il est important de bien comprendre la base du fonctionnement de Sentry.

Je ne vais pas rentrer dans les détails parce que ça serait paraphraser la documentation officielle.

Pour Sentry tout se base sur le concept de Hub et de Scope. Le Hub, que nous ne toucherons pas, correspond à la brique principale qui contient les informations pour envoyer les évènements au bon serveur Sentry plus le Scope qui entoure l’événement courant.

Un Scope (un contexte donc) correspond aux informations additionnelles qui vont pouvoir être liées à un événement. Globalement, c’est tout ce qu’on retrouvera dans l’interface sur la page d’un événement :

Screenshot page d'erreur

Setup

Je vais faire une toute petite passe sur le setup mais il s’agit simplement de suivre la documentation.

Je pars d’un simple projet Rails généré en mode API:

rails new sentry_article --api

Puis on ajoute ce qu’il faut pour faire fonctionner Sentry

# Gemfile

gem "sentry-ruby"
gem "sentry-rails"
# config/initializers/sentry.rb

Sentry.init do |config|
  config.dsn = ENV.fetch("SENTRY_DSN")

  config.breadcrumbs_logger = [:active_support_logger, :http_logger]

  # Ici on met à 1.0 (100%) pour s'assurer de récupérer tout les events
  # Dans le cas d'une application à fort trafic on voudra probablement l'ajuster
  config.traces_sample_rate = 1.0
end

Pour la suite de l’article, je vais utiliser un controller HomeController qui sera enrichi par différentes actions. Voilà les routes qui seront utilisées :

# config/routes.rb
Rails.application.routes.draw do
  get "home/error", to: "home#error"
  get "home/context/:msg", to: "home#context"
  get "home/tags/:msg", to: "home#tags"
  get "home/attachment", to: "home#attachment"
  get "home/scope/:msg", to: "home#scope"
end

Et ensuite j’utilise mon navigateur pour taper sur les différents endpoints.

Les problèmes

Pour tester l’intégration Sentry, le mieux est de simuler une erreur, c’est à ça que nous sert l’action erreur :

# app/controllers/home_controller.rb
class HomeController < ApplicationController
  def error
    raise "Error"
  end
end
Screenshot error

Personnaliser son contexte

Contexte global

Dans certains cas, on pourrait avoir besoin de garder un contexte global (plusieurs instances de l’application pour un seul Sentry par exemple) On peut simplement les spécifier dans l’initializer dédié :

# config/initializers/sentry.rb

Sentry.init do |config|
  # ...
end

Sentry.configure_scope do |scope|
  scope.set_context("custom_global_meta", { instance_name: ENV.fetch("INSTANCE_NAME", "Article sur Sentry") })
end

Ici mon contexte custom_global_meta sera remonté pour chaque événement.

Contexte local

Je vais partir d’une problématique que j’ai rencontrée :

J’ai une tâche qui tourne assez régulièrement qui va scanner un bucket s3 à la recherche de nouveau fichiers et ingérer les données de ces fichiers dans la base de données.

Rien de très complexe dans l’idée, mais on ne peut jamais être sûr que tout se passe bien parce que nous ne sommes pas maîtres des fichiers (et donc de leur format/contenu/encodage/…). Il peut donc y avoir régulièrement des soucis.

Heureusement, Sentry nous permet repérer ces crashs et de les traiter ou de faire remonter le problème.

Mais pour mieux identifier ce qu’il se passe, il est très pratique de pouvoir rajouter du contexte aux évènements Sentry.

Dans mon cas, j’aimerai connaitre le nom du fichier qui a causé l’erreur.

Pour ajouter du contexte on peut modifier le Scope courant pour lui rajouter des informations :

# app/controllers/home_controller.rb
class HomeController < ApplicationController
  def context
    Sentry.configure_scope do |scope|
      scope.set_context("meta", { msg: params[:msg] })
    end

    raise "Context"
  end
end

Et si on regarde la section Environment de l’événement sur Sentry on retrouvera bien notre contexte (ainsi que le contexte global qu’on a mis plus haut :

Screen du contexte

On a déjà pu récupérer une information qui peut être très pratique, mais maintenant je voudrais pouvoir rechercher tous les événements qui ont été levés par un fichier donné, comment faire ?

Il faut savoir que l’ajout de contexte structuré via Sentry n’est pas indexé par la plateforme. Par conséquent, impossible de se servir de ces informations pour filtrer les issues.

Heureusement, Sentry nous met à disposition un autre outil, les tags qui sont eux bien indexés.

L’utilisation des tags ne pourrait pas être plus simple (attention, il existe des tags par défaut utilisés par Sentry d’où le préfixe custom.):

# app/controllers/home_controller.rb
class HomeController < ApplicationController
  def tags
    Sentry.set_tags("custom.request.message": params[:msg])
    raise "Tags"
  end
end

On retrouve bien notre tag custom.request.message dans la section dédiée.

Screeshot tags

On peut maintenant facilement chercher avec notre nom de fichier toutes les erreurs liées :

Screenshot recherche tag

Avec ces deux outils, on est plutôt bien équipé pour retrouver toutes les informations dont on a besoin pour mieux cibler l’erreur.

Mais encore une fois, dans mon cas, ne pourrait-on pas aller plus loin ?

En effet, ça serait assez pratique pour le développeur qui doit régler le bug en question de pouvoir retrouver le fichier qui a causé un bug lors de l’import pour reproduire simplement le problème sur son poste ?

Eh bien c’est possible et même assez simple :

# app/controllers/home_controller.rb
class HomeController < ApplicationController
  def attachment
    Sentry.configure_scope do |scope|
      scope.add_attachment(path: Rails.root.join("README.md"))
      # On peut aussi envoyer directement le contenu du fichier
      # scope.add_attachment(filename: "README.md", bytes: Rails.root.join("README.md").read))
    end

    raise "Attachment"
  end
end
Screenshot attachment

Il existe d’autres moyens d’enrichir encore plus les événements remontés par Sentry. Ne les ayant pas encore utilisés je ne ferai que reprendre la documentation, je vous encourage donc plutôt à aller vous renseigner si vous souhaitez en savoir plus.

Choisir entre Sentry.configure_scope et Sentry.with_scope

attention with_scope peut avoir d’autres noms ou usages selon les SDK

En effet, si à l’usage ces deux fonctions sont très similaires, elles ne répondent pas au même besoin.

La première va enrichir le contexte courant, donc si on enchaine les appels à configure_scope, les informations vont s’ajouter. En revanche, with_scope va cloner le contexte courant, l’enrichir avec les informations ajoutées mais ne viendra pas enrichir notre contexte courant, donc si une erreur survient en dehors du bloc, les informations ajoutées par with_scope seront perdues.

Pour bien comprendre les différences entre ces deux fonctions, le mieux, c’est de les tester.

# app/controllers/home_controller.rb
class HomeController < ApplicationController
  def scope
    Sentry.configure_scope do |scope|
      scope.set_context("custom_scopped_meta", { msg: params[:msg] })
    end

    case params[:msg]
    when "with"
      Sentry.with_scope do |scope|
        scope.set_context("custom_local_meta", { msg: "From the with !" })
        raise "Scope from with"
      rescue => e
        Sentry.capture_exception(e)
        raise e
      end
    when "configure"
      Sentry.configure_scope do |scope|
        scope.set_context("custom_scopped_meta", { warn: "context are stacked" })
      end

      raise "Scope from configure"
    else
      Sentry.with_scope do |scope|
        scope.set_context("custom_local_meta", { msg: "From the else !" })
        raise "Scope from else"
      end
    end
  end
end

Ici si on fait un appel à l’action avec configure comme paramètre, on retrouvera bien comme attendu notre contexte enrichi avec le msg à configure et le warn.

En revanche le piège se trouve dans le else, en effet si on passe autre chose que configure ou with, on se retrouve avec le contexte uniquement enrichi de la première meta (la valeur du msg), alors qu’en lisant simplement la documentation, on pourrait s’attendre à retrouver notre From the else !.

L’explication vient du fait qu’on soit habitué à ce que Sentry attrape par lui-même les erreurs pour ensuite envoyer les événements.

Le souci, c’est que ce processus vient en fait d’un mécanisme global (qui n’est pas inhérent à Sentry tout seul) et donc tout ça survient hors du bloc, on perd donc notre scope qui est uniquement local au bloc.

Pour passer outre ce fonctionnement, il est nécessaire de capturer l’exception à la main, comme c’est fait si on passe le paramètre with, dans ce cas, on retrouve bien notre meta local :

Screenshot with_scope

Le mot de la fin

Comme la majorité des outils qu’on utilise au quotidien, on part facilement du principe qu’on sait s’en servir et on ne va plus forcément aller approfondir le sujet ni se tenir au courant des mises à jour. C’est dommage parce qu’on passe à côté de fonctionnalités qui pourraient nous permettre d’améliorer encore plus notre façon de travailler. En bref, n’hésitez pas à lire les changelogs et la documentation !

À lire aussi

Fresque numérique miniature image
16 avril 2025

Fresque du Numérique

Lire la suite

intelligence artificielle Ouicommit miniature image
17 mars 2025

Ouicommit – L’intelligence artificielle en entreprise, on y est ! 

Lire la suite

Image miniature Hackathon Women in Tech
13 mars 2025

Hackathon Women in Tech :  un engagement pour une tech plus inclusive 

Lire la suite

image miniature les nouveautés Atlassian
26 février 2025

Les nouveautés Atlassian en 2025

Lire la suite

Articles associés

Fresque numérique miniature image
16 avril 2025

Fresque du Numérique


Lire la suite
intelligence artificielle Ouicommit miniature image
17 mars 2025

Ouicommit – L’intelligence artificielle en entreprise, on y est ! 


Lire la suite
Image miniature Hackathon Women in Tech
13 mars 2025

Hackathon Women in Tech :  un engagement pour une tech plus inclusive 


Lire la suite

À propos

  • Qui sommes-nous ?
  • Références
  • RSE
  • Ressources

Offres

  • Applications métier
  • Collaboration des équipes
  • Sécurisation et optimisation du système d’information
  • Transformation numérique

Expertises

  • Développement logiciel
  • DevSecOps
  • Intégration de logiciels et négoce de licences
  • Logiciel de CRM et de gestion
  • UX/UI design
  • Accessibilité Numérique
  • Démarches simplifiées
  • Formations Atlassian

Carrières

  • Pourquoi rejoindre Ouidou ?
  • Nous rejoindre
  • Rencontrer nos collaborateurs
  • Grandir chez Ouidou

SIEGE SOCIAL
70-74 boulevard Garibaldi, 75015 Paris

Ouidou Nord
165 Avenue de Bretagne, 59000 Lille

Ouidou Rhône-Alpes
4 place Amédée Bonnet, 69002 Lyon

Ouidou Grand-Ouest
2 rue Crucy, 44000 Nantes

Ouidou Grand-Est
7 cour des Cigarières, 67000 Strasbourg

  • Linkedin Ouidou
  • GitHub Ouidou
  • Youtube Ouidou
© 2024 Ouidou | Tous droits réservés | Plan du site | Mentions légales | Déclaration d'accessibilité
    Nous contacter