> ## 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.

# Benutzerdefinierte Instrumentierung für 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>;
};

Um herauszufinden, welche spezifischen Teile des Codes Performance-Probleme verursachen, ist es nützlich, Ihrer Anwendung benutzerdefinierte Instrumentierung hinzuzufügen. Dies ermöglicht es uns, bessere Aufschlüsselungen darüber zu erstellen, welcher Code am langsamsten läuft und auf welche Art von Action die meiste Zeit verwendet wurde.

Wenn Sie gespeicherte Samples langsamer Requests in AppSignal anzeigen, sehen Sie alle Instrumentierungen, die Ihre Anwendung intern verwendet. Template-Rendering, ActiveRecord-Abfragen und Caching werden instrumentiert und im Sample angezeigt.

<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="Default event tree" width="555" height="245" data-path="assets/images/screenshots/app_performance_sample_timeline_1.png" />

Das ist bereits sehr nützlich, aber wäre es nicht großartig, wenn wir
Messungen spezifischer Codeteile sehen könnten, von denen Sie vermuten, dass sie Ihre
Performance beeinflussen? Nun, das können Sie!

Durch das Hinzufügen benutzerdefinierter Instrumentierung können wir detailliertere Aufschlüsselungen eines Requests und eines Hintergrundjobs erstellen. Es gibt zwei Möglichkeiten, Ihren Code zu instrumentieren. Mit AppSignal-Instrumentierungs-Helpern oder mit ActiveSupport-Notifications-Instrumentierung, wie sie von Rails verwendet wird.

<Tip>
  **Hinweis**: Stellen Sie sicher, dass Sie [AppSignal
  integriert haben](/ruby/instrumentation/integrating-appsignal), bevor Sie Ihrer Anwendung
  benutzerdefinierte Instrumentierung hinzufügen, falls dies nicht bereits automatisch
  durch eine unserer unterstützten [Integrationen](/ruby/integrations) erfolgt.
  Folgen Sie unserem [Leitfaden zur Instrumentierung für Skripte und Hintergrundjobs](/ruby/instrumentation/background-jobs) für Anwendungen, die wir nicht automatisch instrumentieren.
</Tip>

<Tip>
  **Hinweis**: Diese Seite beschreibt nur, wie Sie Performance-Instrumentierung zu
  Ihrem Code hinzufügen. Um Fehler zu verfolgen, lesen Sie bitte unseren Leitfaden zur [Exception-Handhabung](/ruby/instrumentation/exception-handling).
</Tip>

## Instrumentierungs-Helper

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

Wenn Sie Ihrem Code benutzerdefinierte Instrumentierung hinzufügen, können Sie noch
mehr Einblicke in Ihre Anwendung erhalten. Beispielsweise müssen Sie mit einer
externen API arbeiten, die Artikel für Ihre Homepage abruft:

<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>

Sobald Sie solche benutzerdefinierten Instrumente hinzufügen, beginnt AppSignal, sie aufzugreifen
und zeigt Ihnen, wie viel Zeit sowohl eine Event-Gruppe (`article_fetcher` in diesem
Fall) als auch einzelne Events benötigt haben.

<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="Event tree with fetcher" width="555" height="282" data-path="assets/images/screenshots/app_performance_sample_timeline_2.png" />

In diesem Fall werden Sie feststellen, dass dieser API-Aufruf einen großen Einfluss auf die
Performance unserer Homepage hat, was zuvor verborgen war. Wir könnten in Betracht ziehen,
die Artikel zu cachen.

<Tip>
  **Hinweis**: Der Name des Events, das Sie instrumentieren, ist für unseren
  Processor wichtig. Mehr über die [Event-Benennung](/api/event-names) erfahren Sie hier.
</Tip>

### Verschachtelte Instrumentierung

Sie können beliebig viele Instrumente in beliebiger Kombination verwenden. Sie können
instrument-Aufrufe verschachteln, und AppSignal verarbeitet die Verschachtelung und Aggregate
der Messungen sauber. Sie müssen nur das letzte Segment (nach dem letzten
Punkt) des Schlüssels konsistent halten.

<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>

### Mehr Daten pro Event erfassen

Standardmäßig erfasst AppSignal die Dauer eines Events und sendet sie an unsere
Server. Da benutzerdefinierte Instrumentierung nicht mit Framework-Internas verbunden ist,
müssen Sie möglicherweise mehr Daten mitschicken, wenn Sie möchten, dass Event-Details
in AppSignal erscheinen. Das kann ein beschreibender Titel sein oder spezifischere
Informationen wie die Abfrage aus einem Datenbankaufruf. Wir tun dies bereits für
ActiveRecord, Sequel, Redis, MongoDB, Sinatra, Grape,
[und mehr](/ruby/integrations).

Es gibt zwei Helper, mit denen Sie Ihren Code mit AppSignal instrumentieren können.

<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>

#### `name`-Argument

Der Name des Events, der im Event-Baum in AppSignal erscheint.
Mehr über die [Benennung von Event-Schlüsseln](/api/event-names) erfahren Sie hier.

#### `title`-Argument

Ein beschreibenderer Titel eines Events, wie z. B. `"Fetch current user"` oder `"Fetch blog post comments"`. Er erscheint neben dem Event-Namen im Event-Baum
auf der Performance-Sample-Seite, um etwas mehr Kontext zu dem zu liefern, was
gerade passiert.

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

#### `body`-Argument

Weitere Details, wie z. B. eine Datenbankabfrage, die vom Event verwendet wurde.

<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>
  **Warnung**: Bitte stellen Sie sicher, dass die Body-Payloads bereinigt
  (sensible/dynamische Daten entfernt) sind. Nicht bereinigte Body-Events werden
  verworfen, wenn sie ein bestimmtes Limit erreichen.
</Warning>

Gut:

<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>

Schlecht:

<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>

Wenn Sie eine SQL-Abfrage als Body übergeben, können Sie dafür `body_format = Appsignal::EventFormatter::SQL_BODY_FORMAT` verwenden.

#### `body_format`-Argument

Body-Format unterstützt Formatter, um die im `body`-Argument angegebenen Daten zu bereinigen
und sensible Daten aus dem Wert zu entfernen. Es gibt derzeit zwei unterstützte
Werte für das `body_format`-Argument.

##### Wert `Appsignal::EventFormatter::DEFAULT`

`Appsignal::EventFormatter::DEFAULT` ist der Standardwert dieses
Arguments. Standardmäßig lässt AppSignal den Wert unverändert und bereinigt keine
Daten daraus.

##### Wert `Appsignal::EventFormatter::SQL_BODY_FORMAT`

Der Wert `Appsignal::EventFormatter::SQL_BODY_FORMAT` führt Ihre Daten
durch den SQL-Sanitizer und bereinigt alle Werte in SQL-Abfragen.

Wir empfehlen, stattdessen den `Appsignal.instrument_sql`-Helper dafür zu verwenden.

<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>
  In älteren Versionen des AppSignal-Gems (1.2 und niedriger) ist
  `Appsignal.instrument` nicht verfügbar. Wenn Sie kein Upgrade durchführen können, ist es weiterhin
  möglich, stattdessen `ActiveSupport::Notifications` zu verwenden. Wenn Sie nicht
  den `Appsignal.instrument`-Helper, sondern stattdessen
  `ActiveSupport::Notifications` verwenden möchten, können Sie dies auch in AppSignal für Ruby-Gem
  1.3 und höher tun.
</Tip>

Die Methode zur Instrumentierung Ihres Codes mit `ActiveSupport::Notifications`
ähnelt sehr der von AppSignal. Mit dem Article-Fetcher-Beispiel
können Sie wieder erkennen, dass die Unterschiede ziemlich gering sind.

Siehe auch unsere Dokumentation zu AppSignal-[Event-Formattern](/ruby/instrumentation/event-formatters) bei Verwendung von `ActiveSupport::Notifications`.
Weitere Informationen zur ActiveSupport::Notifications-Instrumentierung finden Sie in der offiziellen Rails-[`ActiveSupport::Notifications`-Dokumentation](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html).

<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>

Es funktioniert auch bei verschachtelten Instrumentierungs-Aufrufen.

<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` ist sehr flexibel, Sie können Ihren Code
auf jede gewünschte Weise instrumentieren. Weitere Informationen zu `ActiveSupport::Notifications` finden Sie in den
[Rails-API-Dokumenten](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html).

<Warning>
  **Warnung**: Wir verfolgen keine privaten `ActiveSupport::Notifications`-Events,
  die mit einem Ausrufezeichen (`!`) beginnen. Diese Events sind überwiegend private
  Events, die von Rails erzeugt werden.
</Warning>
