> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appsignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Instrumentation personnalisée pour Ruby

export const Compatibility = ({versions = [], label = "Available in"}) => {
  if (!Array.isArray(versions) || versions.length === 0) {
    return null;
  }
  const defaultPillStyle = {
    borderColor: "#d4d4d8",
    background: "#f4f4f5",
    color: "#3f3f46"
  };
  const pillStyles = {
    "AppSignal for Elixir": {
      background: "#f3e8ff",
      borderColor: "#d8b4fe",
      color: "#6b21a8"
    },
    "AppSignal for Front-end": {
      background: "#fef9c3",
      borderColor: "#fde047",
      color: "#854d0e"
    },
    "AppSignal for Go": {
      background: "#ccfbf1",
      borderColor: "#5eead4",
      color: "#115e59"
    },
    "AppSignal for JavaScript": {
      background: "#fef9c3",
      borderColor: "#fde047",
      color: "#854d0e"
    },
    "AppSignal for Node.js": {
      background: "#dcfce7",
      borderColor: "#86efac",
      color: "#166534"
    },
    "AppSignal for Python": {
      background: "#dbeafe",
      borderColor: "#93c5fd",
      color: "#1e40af"
    },
    "AppSignal for Ruby": {
      background: "#fee2e2",
      borderColor: "#fca5a5",
      color: "#991b1b"
    },
    "AppSignal for Rust": {
      background: "#ffedd5",
      borderColor: "#fdba74",
      color: "#9a3412"
    }
  };
  const getPillStyle = name => ({
    ...defaultPillStyle,
    ...pillStyles[name] || ({})
  });
  return <div className="not-prose my-4 rounded-lg border border-zinc-200 bg-zinc-50 px-4 py-3 text-sm dark:border-white/10 dark:bg-white/5">
      <div className="flex flex-wrap items-center gap-x-2 gap-y-1">
        <span className="font-semibold text-zinc-700 dark:text-zinc-200">
          {label}:
        </span>
        {versions.map((v, i) => <span key={`${v.name}-${v.version}-${i}`} className="inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs font-medium" style={getPillStyle(v.name)}>
            <span>{v.name}</span>
            <span className="opacity-70">
              {v.version}
              {v.exact ? "" : "+"}
            </span>
          </span>)}
      </div>
    </div>;
};

Afin de découvrir quels morceaux de code spécifiques causent des problèmes de performance, il est utile d'ajouter une instrumentation personnalisée à votre application. Cela nous permet de créer de meilleures répartitions du code qui s'exécute le plus lentement et du type d'action sur laquelle le plus de temps a été passé.

Lorsque vous consultez des échantillons enregistrés de requêtes lentes dans AppSignal, vous pourrez voir toute l'instrumentation que votre application utilise en interne. Le rendu des templates, les requêtes ActiveRecord et la mise en cache sont instrumentés et seront affichés dans l'échantillon.

<img src="https://mintcdn.com/appsignal-715f5a51/nF8c1Rwq1cS7b5hg/assets/images/screenshots/app_performance_sample_timeline_1.png?fit=max&auto=format&n=nF8c1Rwq1cS7b5hg&q=85&s=5d66c763209a2fa1e9e04252e792d566" alt="Arbre d'événements par défaut" width="555" height="245" data-path="assets/images/screenshots/app_performance_sample_timeline_1.png" />

C'est déjà très utile, mais ne serait-il pas formidable de pouvoir voir les
mesures de morceaux de code spécifiques dont vous soupçonnez qu'ils pourraient influencer
votre performance ? Eh bien, vous le pouvez !

En ajoutant une instrumentation personnalisée, nous pouvons créer des répartitions plus détaillées d'une requête et d'une tâche en arrière-plan. Il existe deux façons d'instrumenter votre code. Avec les assistants d'instrumentation AppSignal ou avec l'instrumentation ActiveSupport Notifications, comme utilisée par Rails.

<Tip>
  **Remarque** : assurez-vous d'avoir [intégré
  AppSignal](/ruby/instrumentation/integrating-appsignal) avant d'ajouter
  une instrumentation personnalisée à votre application si elle n'est pas automatiquement
  intégrée par l'une de nos [intégrations](/ruby/integrations) prises en charge.
  Suivez notre [guide d'instrumentation pour les scripts et les tâches en
  arrière-plan](/ruby/instrumentation/background-jobs) pour les applications
  que nous n'instrumentons pas automatiquement.
</Tip>

<Tip>
  **Remarque** : cette page décrit uniquement comment ajouter une instrumentation de
  performance à votre code. Pour suivre les erreurs, veuillez lire notre guide de [gestion
  des exceptions](/ruby/instrumentation/exception-handling).
</Tip>

## Assistants d'instrumentation

<Compatibility versions={[{ name: "AppSignal for Ruby", version: "1.3.0" }]} />

Lorsque vous ajoutez une instrumentation personnalisée à votre code, vous pourrez recevoir encore
plus d'informations sur votre application. Par exemple, vous devez travailler avec une
API externe qui récupère des articles pour votre page d'accueil :

<CodeGroup>
  ```ruby Ruby theme={null}
  class ArticleFetcher
    def self.fetch(category)
      Appsignal.instrument('fetch.article_fetcher') do
        # Download and process the articles
      end
    end
  end

  ArticleFetcher.fetch('Latest news')
  ```
</CodeGroup>

Une fois que vous aurez ajouté des instruments personnalisés comme celui-ci, AppSignal commencera à les détecter
et vous montrera combien de temps un groupe d'événements (`article_fetcher` dans ce cas)
et les événements individuels ont pris.

<img src="https://mintcdn.com/appsignal-715f5a51/nF8c1Rwq1cS7b5hg/assets/images/screenshots/app_performance_sample_timeline_2.png?fit=max&auto=format&n=nF8c1Rwq1cS7b5hg&q=85&s=d32f6f6efe5cce3991168d0fe9f06a77" alt="Arbre d'événements avec fetcher" width="555" height="282" data-path="assets/images/screenshots/app_performance_sample_timeline_2.png" />

Dans ce cas, vous remarquerez que cet appel d'API a une énorme influence sur la
performance de notre page d'accueil, ce qui était caché auparavant. Nous pourrions envisager
de mettre en cache les articles.

<Tip>
  **Remarque** : le nom de l'événement que vous instrumentez est important pour notre
  processeur. En savoir plus sur le [nommage des événements](/api/event-names).
</Tip>

### Instrumentation imbriquée

Vous pouvez utiliser autant d'instruments que vous le souhaitez dans n'importe quelle combinaison. Vous pouvez
imbriquer les appels d'instrument et AppSignal gérera l'imbrication et les agrégats des
mesures correctement. Vous devez juste garder le segment final (après le dernier
point) de la clé cohérent.

<CodeGroup>
  ```ruby Ruby theme={null}
  Appsignal.instrument('fetch.article_fetcher') do
    10.times do
      Appsignal.instrument('fetch_single_article.article_fetcher') do
        # Fetch single article
      end
    end
  end
  ```
</CodeGroup>

### Collecter plus de données par événement

Par défaut, AppSignal collectera la durée d'un événement et l'enverra à nos
serveurs. Comme l'instrumentation personnalisée n'est connectée à aucun composant interne du framework,
vous pourriez avoir besoin de transmettre plus de données si vous voulez que les détails des événements
apparaissent dans AppSignal. Cela peut être un titre descriptif, ou des informations plus
spécifiques comme la requête d'un appel à la base de données. Nous le faisons déjà pour
ActiveRecord, Sequel, Redis, MongoDB, Sinatra, Grape,
[et plus encore](/ruby/integrations).

Il existe deux assistants pour vous permettre d'instrumenter votre code avec AppSignal.

<CodeGroup>
  ```ruby Ruby theme={null}
  Appsignal.instrument(name, title = nil, body = nil, body_format = Appsignal::EventFormatter::DEFAULT, &block)
  # and
  Appsignal.instrument_sql(name, title = nil, body = nil, &block)
  ```
</CodeGroup>

#### Argument `name`

Le nom de l'événement qui apparaîtra dans l'arbre des événements dans AppSignal.
En savoir plus sur le [nommage des clés d'événement](/api/event-names).

#### Argument `title`

Un titre plus descriptif d'un événement, tel que `"Fetch current user"` ou `"Fetch blog post comments"`. Il apparaîtra à côté du nom de l'événement dans l'arbre des événements
sur la page d'échantillon de performance pour fournir un peu plus de contexte sur ce qui se
passe.

<CodeGroup>
  ```ruby Ruby theme={null}
  Appsignal.instrument('fetch.custom_database', 'Fetch current user') do
    # ...
  end
  ```
</CodeGroup>

#### Argument `body`

Plus de détails comme une requête de base de données qui a été utilisée par l'événement.

<CodeGroup>
  ```ruby Ruby theme={null}
  sql = 'SELECT * FROM posts ORDER BY created_at DESC LIMIT 1'
  Appsignal.instrument('fetch.custom_database', 'Fetch latest post', sql) do
    # ...
  end
  ```
</CodeGroup>

<Warning>
  **Avertissement** : assurez-vous que les payloads du body sont nettoyés
  (les données sensibles/dynamiques sont supprimées). Les événements de body non nettoyés
  seront supprimés s'ils atteignent une certaine limite.
</Warning>

Bien :

<CodeGroup>
  ```ruby Ruby theme={null}
  Appsignal.instrument('custom.instrument', 'Instrument stuff', 'command/dynamic/?') do
    # ...
  end
  Appsignal.instrument('custom.instrument', 'Instrument stuff', 'command/dynamic/?') do
    # ...
  end
  ```
</CodeGroup>

Mauvais :

<CodeGroup>
  ```ruby Ruby theme={null}
  Appsignal.instrument('custom.instrument', 'Instrument stuff', 'command/dynamic/123') do
    # ...
  end
  Appsignal.instrument('custom.instrument', 'Instrument stuff', 'command/dynamic/234') do
    # ...
  end
  ```
</CodeGroup>

Lorsque vous passez une requête SQL comme body, vous pouvez utiliser `body_format = Appsignal::EventFormatter::SQL_BODY_FORMAT` pour le faire.

#### Argument `body_format`

Le format du body prend en charge les formateurs pour nettoyer les données fournies dans l'argument `body`
afin de supprimer toute donnée sensible de la valeur. Il existe actuellement deux valeurs prises
en charge pour l'argument `body_format`.

##### Valeur `Appsignal::EventFormatter::DEFAULT`

`Appsignal::EventFormatter::DEFAULT` est la valeur par défaut de cet
argument. Par défaut, AppSignal laissera la valeur intacte et ne nettoiera aucune
donnée.

##### Valeur `Appsignal::EventFormatter::SQL_BODY_FORMAT`

La valeur `Appsignal::EventFormatter::SQL_BODY_FORMAT` exécutera vos données
via le sanitizer SQL et nettoiera toutes les valeurs des requêtes SQL.

Nous recommandons d'utiliser l'assistant `Appsignal.instrument_sql` pour cela à la place.

<CodeGroup>
  ```sql SQL theme={null}
  SELECT * FROM users WHERE email = 'hector@appsignal.com' AND password = 'iamabot'
  -- becomes
  SELECT * FROM users WHERE email = ? AND password = ?
  ```
</CodeGroup>

## ActiveSupport::Notifications

<Tip>
  Dans les anciennes versions de la gem AppSignal (1.2 et inférieures),
  `Appsignal.instrument` n'est pas disponible. Si vous ne pouvez pas mettre à
  niveau, il est toujours possible d'utiliser `ActiveSupport::Notifications` à
  la place. Si vous ne voulez pas utiliser l'assistant `Appsignal.instrument`,
  mais utiliser à la place `ActiveSupport::Notifications`, vous pouvez le faire
  également dans la gem AppSignal pour Ruby 1.3 et plus.
</Tip>

La méthode pour instrumenter votre code à l'aide de `ActiveSupport::Notifications`
est très similaire à la façon dont AppSignal le fait. En reprenant l'exemple de l'article
fetcher, vous pouvez voir que les différences sont assez minimes.

Consultez également notre documentation sur les [event formatters](/ruby/instrumentation/event-formatters) AppSignal lors de l'utilisation de `ActiveSupport::Notifications`.
Pour plus d'informations sur l'instrumentation ActiveSupport::Notifications, consultez la [documentation officielle `ActiveSupport::Notifications`](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html) de Rails.

<CodeGroup>
  ```ruby Ruby theme={null}
  require "active_support"

  class ArticleFetcher
    def self.fetch(category)
      ActiveSupport::Notifications.instrument("fetch.article_fetcher") do
        # Download and process the articles
      end
    end
  end

  ArticleFetcher.fetch("Latest news")
  ```
</CodeGroup>

Cela fonctionne également pour les appels d'instrumentation imbriqués.

<CodeGroup>
  ```ruby Ruby theme={null}
  require "active_support"

  ActiveSupport::Notifications.instrument("fetch.article_fetcher") do
    10.times do
      ActiveSupport::Notifications.instrument("fetch_single_article.article_fetcher") do
        # Fetch single article
      end
    end
  end
  ```
</CodeGroup>

`ActiveSupport::Notifications` est très flexible, vous pouvez instrumenter votre code
de la façon que vous voulez. Plus d'informations sur `ActiveSupport::Notifications` peuvent être
trouvées dans la
[documentation de l'API Rails](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html).

<Warning>
  **Avertissement** : nous ne suivons pas les événements privés `ActiveSupport::Notifications`
  qui commencent par un point d'exclamation (`!`). Ces événements incluent principalement
  des événements privés générés par Rails.
</Warning>
