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

Mit benutzerdefinierten Metriken können Sie alles erfassen, was in Ihrer Anwendung von Bedeutung ist – von der Anzahl der aktiven Nutzer zu einem bestimmten Zeitpunkt über die Anzahl der in der letzten Stunde erstellten Rechnungen bis hin zur aktuellen Größe Ihrer Datenbank. Indem Sie benutzerdefinierte Metriken an AppSignal senden, können Sie in Ihren Dashboards Diagramme erstellen, die diese Daten mit wichtigen Signalen wie Fehlerraten und Antwortzeiten in Beziehung setzen – so erhalten Sie den Kontext, um Probleme schnell zu erkennen und zu beheben.

Darüber hinaus helfen benutzerdefinierte Metriken Ihnen, proaktiv statt reaktiv zu arbeiten. Während Logging Ihnen hilft, Probleme nach ihrem Auftreten zu debuggen, ermöglichen Ihnen benutzerdefinierte Metriken, Trends und potenzielle Probleme zu erkennen, bevor Ihre Kunden sie bemerken. Sie können sich auf Daten konzentrieren, die für Ihr Geschäft wichtig sind – wie etwa die Anzahl aktiver Nutzer, KPIs oder Verkaufsmengen –, ohne Logzeilen oder Vorfallslisten zu durchsuchen. Sie können auch Trigger auf benutzerdefinierte Metriken setzen, die Sie warnen, wenn Werte außerhalb der erwarteten Bereiche liegen.

Benutzerdefinierte Metriken sind kein Ersatz für [benutzerdefinierte Instrumentierung](/ruby/instrumentation/instrumentation), sondern ein ergänzendes Werkzeug, um spezifische Anwendungsdaten über die Zeit hinweg sichtbar und messbar zu machen.

AppSignal bietet drei Arten von benutzerdefinierten Metriken:

| Typ                         | Am besten geeignet für                        | Beispiel-Anwendungsfall                             |
| --------------------------- | --------------------------------------------- | --------------------------------------------------- |
| [Gauge](#gauge)             | Absolute Werte, die sich über die Zeit ändern | Aktive Nutzer, Datenbankgröße, Speicherplatznutzung |
| [Measurement](#measurement) | Bereiche und Verteilungen von Werten          | Antwortzeiten, Job-Dauern, Warenkorbwerte           |
| [Counter](#counter)         | Vorkommen über die Zeit zählen                | Erstellte Rechnungen, Logins, ausgelöste Fehler     |

Sie können benutzerdefinierte Metriken in [Diagrammen](#graphing-custom-metrics) in Ihren AppSignal-Dashboards verfolgen.

### Gauge

Ein Gauge zeichnet einen Wert zu einem bestimmten Zeitpunkt auf. Wenn Sie mehrere Gauges mit demselben Schlüssel innerhalb desselben Zeitfensters melden, wird nur der letzte Wert gespeichert.

**Verwenden Sie Gauges, wenn** Sie den aktuellen Zustand von etwas wissen möchten – die Anzahl der gerade existierenden Elemente oder die aktuelle Größe einer Ressource. Alle AppSignal-[Host-Metriken](/metrics/host-metrics) werden als Gauges gespeichert.

Gauges werden häufig mit [minütlichen Probes](/ruby/instrumentation/minutely-probes) verwendet, um regelmäßig einen Snapshot-Wert zu melden, etwa um jede Minute die Anzahl der kürzlich aktiven Warenkörbe oder offenen Datenbankverbindungen abzufragen.

**Beispiele:** Anzahl aktiver Nutzer, Datenbankgröße, Speicherplatznutzung, Anzahl offener Verbindungen.

<CodeGroup>
  ```ruby Ruby theme={null}
  # The first argument is a string, the second argument a number
  # Appsignal.set_gauge(metric_name, value)
  Appsignal.set_gauge("database_size", 100)
  Appsignal.set_gauge("database_size", 10)

  # Will create the metric "database_size" with the value 10
  ```

  ```elixir Elixir theme={null}
  # The first argument is a string, the second argument a number
  # Appsignal.set_gauge(metric_name, value)
  Appsignal.set_gauge("database_size", 100)
  Appsignal.set_gauge("database_size", 10)

  # Will create the metric "database_size" with the value 10
  ```

  ```javascript Node.js theme={null}
  const meter = Appsignal.client.metrics();

  // The first argument is a string, the second argument a number
  // meter.setGauge(metric_name, value)
  meter.setGauge("database_size", 100);
  meter.setGauge("database_size", 10);

  // Will create the metric "database_size" with the value 10
  ```

  ```python Python theme={null}
  # Import the AppSignal metric helper
  from appsignal import set_gauge

  # The first argument is a string, the second argument a number (int/float)
  # set_gauge(metric_name, value)
  set_gauge("database_size", 100)
  set_gauge("database_size", 10)

  # Will create the metric named "database_size" with the value 10
  ```

  ```php PHP theme={null}
  <?php
  use Appsignal\Appsignal;

  // Record gauge values
  Appsignal::setGauge('database_size', 100);
  Appsignal::setGauge('database_size', 10);

  // Will create the metric "database_size" with the value 10
  ```

  ```java Java theme={null}
  import io.opentelemetry.api.GlobalOpenTelemetry;
  import io.opentelemetry.api.metrics.DoubleGauge;
  import io.opentelemetry.api.metrics.Meter;

  public void recordMetrics() {
      // Get the meter from the global meter provider
      Meter meter = GlobalOpenTelemetry.getMeter("my-app");

      // Create a gauge instrument
      DoubleGauge gauge = meter.gaugeBuilder("database_size").build();

      // Record gauge values
      gauge.set(100);
      gauge.set(10);

      // Will create the metric "database_size" with the value 10
  }
  ```

  ```go Go theme={null}
  package main

  import (
  	"context"
  	"go.opentelemetry.io/otel"
  	"go.opentelemetry.io/otel/metric"
  )

  func recordMetrics() {
  	// Get the meter from the global meter provider
  	meter := otel.Meter("my-app")

  	// Create a gauge instrument
  	gauge, _ := meter.Float64Gauge("database_size")

  	// Record gauge values
  	gauge.Record(context.Background(), 100)
  	gauge.Record(context.Background(), 10)

  	// Will create the metric "database_size" with the value 10
  }
  ```
</CodeGroup>

<Tip>
  Ab Version 3.1.0 ermöglicht es die Node.js-Integration, Gauges und Counter über den OpenTelemetry-Metrics-Provider zu setzen. Sie müssen den OpenTelemetry-HTTP-Server des Agents aktivieren, um diese Metriken an AppSignal zu melden; dies können Sie tun, indem Sie die Option [enableOpentelemetryHttp](/nodejs/3.x/configuration/options#option-enable_opentelemetry_http) auf `true` setzen.

  Auch die Java- und Go-Integrationen verwenden OpenTelemetry-Metriken, um benutzerdefinierte Metriken an AppSignal zu melden.

  Mehr zu OpenTelemetry-Metriken erfahren Sie in der [OpenTelemetry-Metrics-Dokumentation](https://opentelemetry.io/docs/concepts/metrics/). Für Node.js finden Sie weitere Informationen in der [OpenTelemetry JS Metrics-Dokumentation](https://opentelemetry.io/docs/languages/js/instrumentation/#metrics).
</Tip>

### Measurement

Ein Measurement verfolgt eine Verteilung von Werten über die Zeit. AppSignal speichert für jedes Zeitfenster den Durchschnitt und die Anzahl, sodass Sie Dinge wie durchschnittliche Dauer, 90. / 95. Perzentil und Durchsatz grafisch darstellen können.

**Verwenden Sie Measurements, wenn** Sie einen Wert aufzeichnen, der über einzelne Ereignisse hinweg variiert, und Sie dessen Verteilung verstehen möchten – nicht nur seinen aktuellen Wert. Beispielsweise können Sie die Dauer eines kritischen Hintergrund-Jobs (etwa Bestellbestätigungs-E-Mails) verfolgen, um Verlangsamungen zu erkennen, bevor sie Ihre Nutzer beeinträchtigen.

Eine Measurement-Metrik erstellt mehrere Metrik-Felder:

* **Count:** wie oft der Helper aufgerufen wurde. Nützlich für Durchsatz-Diagramme.
* **Mean:** der durchschnittliche Metrik-Wert für den Zeitpunkt.
* **90. Perzentil:** das 90. Perzentil des Metrik-Werts für den Zeitpunkt.
* **95. Perzentil:** das 95. Perzentil des Metrik-Werts für den Zeitpunkt.

**Beispiele:** HTTP-Antwortzeiten, Hintergrund-Job-Dauern, Werte von Nutzer-Warenkörben, Ausführungszeiten von Abfragen.

<CodeGroup>
  ```ruby Ruby theme={null}
  # The first argument is a string, the second argument a number
  # Appsignal.add_distribution_value(metric_name, value)
  Appsignal.add_distribution_value("memory_usage", 100)
  Appsignal.add_distribution_value("memory_usage", 110)

  # Will create a metric "memory_usage" with the mean field value 105
  # Will create a metric "memory_usage" with the count field value 2
  ```

  ```elixir Elixir theme={null}
  # The first argument is a string, the second argument a number
  # Appsignal.add_distribution_value(metric_name, value)
  Appsignal.add_distribution_value("memory_usage", 100)
  Appsignal.add_distribution_value("memory_usage", 110)

  # Will create a metric "memory_usage" with the mean field value 105
  # Will create a metric "memory_usage" with the count field value 2
  ```

  ```javascript JavaScript theme={null}
  const meter = Appsignal.client.metrics();

  // The first argument is a string, the second argument a number
  // meter.addDistributionValue(metric_name, value)
  meter.addDistributionValue("memory_usage", 100);
  meter.addDistributionValue("memory_usage", 110);

  // Will create a metric "memory_usage" with the mean field value 105
  // Will create a metric "memory_usage" with the count field value 2
  ```

  ```python Python theme={null}
  # Import the AppSignal metric helper
  from appsignal import add_distribution_value

  # The first argument is a string, the second argument a number (int/float)
  # add_distribution_value(metric_name, value)
  add_distribution_value("memory_usage", 100)
  add_distribution_value("memory_usage", 110)

  # Will create a metric "memory_usage" with the mean field value 105
  # Will create a metric "memory_usage" with the count field value 2
  ```

  ```php PHP theme={null}
  <?php
  use Appsignal\Appsignal;

  // Record distribution values
  Appsignal::addDistributionValue('memory_usage', 100);
  Appsignal::addDistributionValue('memory_usage', 110);

  // Will create a metric "memory_usage" with the mean field value 105
  // Will create a metric "memory_usage" with the count field value 2
  ```

  ```java Java theme={null}
  import io.opentelemetry.api.GlobalOpenTelemetry;
  import io.opentelemetry.api.metrics.DoubleHistogram;
  import io.opentelemetry.api.metrics.Meter;

  public void recordDistributions() {
      // Get the meter from the global meter provider
      Meter meter = GlobalOpenTelemetry.getMeter("my-app");

      // Create a histogram instrument for distributions
      DoubleHistogram histogram = meter.histogramBuilder("memory_usage").build();

      // Record distribution values
      histogram.record(100);
      histogram.record(110);

      // Will create a metric "memory_usage" with the mean field value 105
      // Will create a metric "memory_usage" with the count field value 2
  }
  ```

  ```go Go theme={null}
  package main

  import (
  	"context"
  	"go.opentelemetry.io/otel"
  	"go.opentelemetry.io/otel/metric"
  )

  func recordDistributions() {
  	// Get the meter from the global meter provider
  	meter := otel.Meter("my-app")

  	// Create a histogram instrument for distributions
  	histogram, _ := meter.Float64Histogram("memory_usage")

  	// Record distribution values
  	histogram.Record(context.Background(), 100)
  	histogram.Record(context.Background(), 110)

  	// Will create a metric "memory_usage" with the mean field value 105
  	// Will create a metric "memory_usage" with the count field value 2
  }
  ```
</CodeGroup>

### Counter

Ein Counter akkumuliert eine Gesamtsumme über ein Zeitfenster. Counter-Werte werden für jede Auflösung summiert – bei minütlicher Auflösung zeigt er also die Summe für diese Minute, und bei stündlicher Auflösung die Summe für diese Stunde.

**Verwenden Sie Counter, wenn** Sie verfolgen möchten, wie oft etwas passiert ist, nicht welchen Wert es hatte. Counter sind besonders nützlich, um die Häufigkeit geschäftskritischer Ereignisse zu überwachen. Indem Sie beispielsweise sowohl aufgegebene Bestellungen als auch erstellte Rechnungen verfolgen, können Sie sicherstellen, dass diese zusammenhängenden Counter synchron bleiben, und Abweichungen frühzeitig erkennen.

Wenn der Helper mehrfach aufgerufen wird, wird die Summe aller Aufrufe gespeichert. Counter sind nicht monoton: Sowohl positive als auch negative Werte werden unterstützt, sodass Sie denselben Counter erhöhen und verringern können. Für monotone Counter aus anderen Systemen gibt es keine Validierung, dass die Counter-Werte nur jemals steigen.

**Beispiele:** aufgegebene Bestellungen, erstellte Rechnungen, Nutzer-Logins, in die Warteschlange gestellte Hintergrund-Jobs, fehlgeschlagene Zahlungsversuche.

<Tip>
  **Gauge vs. Counter:** Verwenden Sie einen Gauge, um zu verfolgen, *wie viele Elemente von etwas gerade existieren* (z. B. derzeit aktive Nutzer). Verwenden Sie einen Counter, um zu verfolgen, *wie oft etwas passiert ist* in einem bestimmten Zeitraum (z. B. neue Logins in der letzten Minute).
</Tip>

<CodeGroup>
  ```ruby Ruby theme={null}
  # The first argument is a string, the second argument a number
  # Appsignal.increment_counter(metric_name, value)
  Appsignal.increment_counter("login_count", 1)
  Appsignal.increment_counter("login_count", 1)

  # Will create the metric "login_count" with the value 2 for a point in the minutely/hourly resolution
  ```

  ```elixir Elixir theme={null}
  # The first argument is a string, the second argument a number
  # Appsignal.increment_counter(metric_name, value)
  Appsignal.increment_counter("login_count", 1)
  Appsignal.increment_counter("login_count", 1)

  # Will create the metric "login_count" with the value 2 for a point in the minutely/hourly resolution
  ```

  ```javascript JavaScript theme={null}
  const meter = Appsignal.client.metrics();

  // The first argument is a string, the second argument a number
  // meter.incrementCounter(metric_name, value)
  meter.incrementCounter("login_count", 1);
  meter.incrementCounter("login_count", 1);

  // Will create the metric "login_count" with the value 2 for a point in the minutely/hourly resolution
  ```

  ```python Python theme={null}
  # Import the AppSignal metric helper
  from appsignal import increment_counter

  # The first argument is a string, the second argument a number (int/float)
  # increment_counter(metric_name, value)
  increment_counter("metric_name", 1)  # Increase the value by one
  increment_counter("metric_name", 1)
  increment_counter("metric_name", -1) # Decrease the value by one

  # Will create the metric named "metric_name" with the value 2 for a point in the minutely/hourly resolution
  ```

  ```php PHP theme={null}
  <?php
  use Appsignal\Appsignal;

  // Record counter values
  Appsignal::incrementCounter('login_count', 1);
  Appsignal::incrementCounter('login_count', 1);

  // Will create the metric "login_count" with the value 2 for a point in the minutely/hourly resolution
  ```

  ```java Java theme={null}
  import io.opentelemetry.api.GlobalOpenTelemetry;
  import io.opentelemetry.api.metrics.LongCounter;
  import io.opentelemetry.api.metrics.Meter;

  public void recordCounters() {
      // Get the meter from the global meter provider
      Meter meter = GlobalOpenTelemetry.getMeter("my-app");

      // Create a counter instrument
      LongCounter counter = meter.counterBuilder("login_count").build();

      // Record counter values
      counter.add(1);
      counter.add(1);

      // Will create the metric "login_count" with the value 2 for a point in the minutely/hourly resolution
  }
  ```

  ```go Go theme={null}
  package main

  import (
  	"context"
  	"go.opentelemetry.io/otel"
  	"go.opentelemetry.io/otel/metric"
  )

  func recordCounters() {
  	// Get the meter from the global meter provider
  	meter := otel.Meter("my-app")

  	// Create a counter instrument
  	counter, _ := meter.Int64Counter("login_count")

  	// Record counter values
  	counter.Add(context.Background(), 1)
  	counter.Add(context.Background(), 1)

  	// Will create the metric "login_count" with the value 2 for a point in the minutely/hourly resolution
  }
  ```
</CodeGroup>

<Warning>
  **Hinweis**: In AppSignal sind Counter so konzipiert, dass sie ausschließlich Integer-Werte speichern.
  Obwohl die API zur Erleichterung der Integration Float-Werte akzeptiert, werden diese intern in Integer umgewandelt.

  Dezimalwerte werden auf den nächstkleineren Integer abgerundet.
  Der Wert 0,0001 wird zu 0, und 1,2, 1,5 sowie 1,7 werden zu 1.
</Warning>

## Benennung von Metriken

Wir empfehlen, Ihre Metriken so zu benennen, dass sie leicht erkennbar sind. Obwohl Sie Teile des Metrik-Namens für die Dashboard-Erstellung mit Wildcards versehen können, empfehlen wir, dies nur für kleine Gruppierungen zu verwenden und keine IDs in Metrik-Namen einzubauen.

Metrik-Namen unterstützen nur Zahlen, Buchstaben, Punkte und Unterstriche (`[a-z0-9._]`) als gültige Zeichen. Alle anderen Zeichen werden von unserem Prozessor durch einen Unterstrich ersetzt. Die Liste der verarbeiteten Metriken finden Sie auf der Seite [„Add Dashboard"](https://appsignal.com/redirect-to/app?to=dashboard\&overlay=dashboardForm).

Einige Beispiele für gute Metrik-Namen sind:

* `database_size`
* `account_count`
* `users.count`
* `notifier.failed`
* `notifier.perform`
* `notifier.success`

Standardmäßig verfolgt AppSignal bereits Metriken für Ihre Anwendung, etwa [Host-Metriken](/metrics/host-metrics). Sehen Sie sich die Metrik-Liste auf der Seite [„Add Dashboard"](https://appsignal.com/redirect-to/app?to=dashboard\&overlay=dashboardForm) an, um die Metriken zu sehen, die bereits für Ihre App verfügbar sind.

<Warning>
  **Hinweis**: Wir **empfehlen nicht**, dynamische Werte in Ihre Metrik-Namen einzufügen, wie etwa: `eu.database_size`, `us.database_size` und `asia.database_size`. Dadurch entstehen mehrere Metriken, die denselben Zweck erfüllen. Stattdessen empfehlen wir, dafür [Metrik-Tags](#metric-tags) zu verwenden.
</Warning>

## Metrik-Werte

Metriken unterstützen nur Zahlen als gültige Werte. Jeder andere Wert wird stillschweigend ignoriert oder löst einen Fehler aus, wie er vom Zahlen-Parser der jeweiligen Implementierungssprache erzeugt wird. Für Ruby und Elixir unterstützen wir [Double](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) und [Integer](https://en.wikipedia.org/wiki/Integer) als gültige Werte:

<CodeGroup>
  ```ruby Ruby theme={null}
  # Integer
  Appsignal.increment_counter("login_count", 1)
  # Double
  Appsignal.increment_counter("assignment_completed", 0.12)
  ```

  ```elixir Elixir theme={null}
  # Integer
  Appsignal.increment_counter("login_count", 1)
  # Double
  Appsignal.increment_counter("assignment_completed", 0.12)
  ```

  ```javascript JavaScript theme={null}
  const meter = Appsignal.client.metrics();

  // Integer
  meter.incrementCounter("login_count", 1);
  // Double
  meter.incrementCounter("assignment_completed", 0.12);
  ```

  ```python Python theme={null}
  from appsignal import increment_counter

  # Integer
  increment_counter("login_count", 1)
  # Double
  increment_counter("assignment_completed", 0.12)
  ```

  ```php PHP theme={null}
  <?php
  use Appsignal\Appsignal;

  // Integer
  Appsignal::incrementCounter('login_count', 1);
  // Double
  Appsignal::incrementCounter('login_count', 0.12);
  ```

  ```java Java theme={null}
  import io.opentelemetry.api.GlobalOpenTelemetry;
  import io.opentelemetry.api.metrics.DoubleCounter;
  import io.opentelemetry.api.metrics.LongCounter;
  import io.opentelemetry.api.metrics.Meter;

  public void recordValues() {
      Meter meter = GlobalOpenTelemetry.getMeter("my-app");

      // Integer counter
      LongCounter longCounter = meter.counterBuilder("login_count").build();
      longCounter.add(1);

      // Double counter
      DoubleCounter doubleCounter = meter.counterBuilder("assignment_completed")
          .ofDoubles()
          .build();
      doubleCounter.add(0.12);
  }
  ```

  ```go Go theme={null}
  package main

  import (
  	"context"
  	"go.opentelemetry.io/otel"
  	"go.opentelemetry.io/otel/metric"
  )

  func recordValues() {
  	meter := otel.Meter("my-app")

  	// Integer counter
  	intCounter, _ := meter.Int64Counter("login_count")
  	intCounter.Add(context.Background(), 1)

  	// Float counter
  	floatCounter, _ := meter.Float64Counter("assignment_completed")
  	floatCounter.Add(context.Background(), 0.12)
  }
  ```
</CodeGroup>

Hinweis: In Node.js ist nur der Typ `number` ein gültiger Wert.

### Wertformatierung {/* id: metric-values-value-formatting */}

AppSignal-Diagramme bieten verschiedene Anzeigeformate, etwa Zahlen, Dateigrößen, Dauern usw. Diese Formate helfen dabei, die Metrik-Werte in einer lesbaren Form darzustellen.

Die Auswahl eines Wert-Formatierers wirkt sich nicht auf die in unseren Systemen gespeicherten Daten aus, sondern nur auf deren Anzeige.

Um Metrik-Werte mit diesen Formatierern korrekt anzuzeigen, prüfen Sie bitte in der Tabelle unten, wie der Wert gemeldet werden sollte.

| Formatierer | Gemeldeter Wert         | Beschreibung                                                                                                                                                                                                                                                                                                                                                                    |
| ----------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Number      | Anzeige-Wert            | Eine menschenlesbar formatierte Zahl. Die Werte sollten auf derselben Skala gemeldet werden, wie sie angezeigt werden. Der Wert `1` wird als „`1`" angezeigt, `10_000` als „`10 K`" und `1_000_000` wird als „`1 M`" angezeigt.                                                                                                                                                 |
| Percentage  | Anzeige-Wert            | Ein Metrik-Wert, der als Prozentsatz formatiert ist. Die Werte sollten auf derselben Skala gemeldet werden, wie sie angezeigt werden. Der Wert `40` wird als „`40 %`" angezeigt.                                                                                                                                                                                                |
| Throughput  | Anzeige-Wert            | Ein Metrik-Wert, der als Anfragen pro Minute/Stunde formatiert ist. Die Werte sollten auf derselben Skala gemeldet werden, wie sie angezeigt werden. Der Durchsatz wird sowohl für die Minute als auch für die Stunde als Zahl formatiert angezeigt. Der Wert `10_000` wird als „`10k / hour 166 / min`" angezeigt. Üblicherweise verwendet für [`counter`](#counter)-Metriken. |
| Duration    | Millisekunden           | Eine Zeitdauer. Die Werte sollten als Millisekunden gemeldet werden. Der Wert `100` wird als „`100 ms`" und `60_000` als „`60 sec`" angezeigt. Üblicherweise verwendet für [`measurement`](/metrics/custom#measurement)-Metriken.                                                                                                                                               |
| File size   | [Anpassbar](#file-size) | Eine Dateigröße, die standardmäßig als Megabyte formatiert ist. `1.0` Megabyte wird als `1Mb` angezeigt. Welche Dateigrößen-Einheit der gemeldete Metrik-Wert hat, kann im Diagramm-Builder angepasst werden.                                                                                                                                                                   |

#### Dateigröße

Metrik-Werte, die eine Dateigröße darstellen, können den Dateigrößen-Formatierer verwenden. Um anzugeben, in welcher Größeneinheit der gemeldete Wert vorliegt, erlaubt der Dateigrößen-Formatierer mehrere Eingabewerte.

Die verfügbaren Optionen sind:

* `Size in Bit`
* `Size in Bytes`
* `Size in Kilobits`
* `Size in Kilobytes`
* `Size in Megabytes`

Wenn eine Metrik mit dem folgenden Wert gesendet wird:

<CodeGroup>
  ```ruby Ruby theme={null}
  Appsignal.set_gauge("database_size", 1024)
  ```

  ```elixir Elixir theme={null}
  Appsignal.set_gauge("database_size", 1024)
  ```

  ```javascript JavaScript theme={null}
  const meter = Appsignal.client.metrics();

  meter.setGauge("database_size", 1024);
  ```

  ```python Python theme={null}
  # Import the AppSignal metric helper
  from appsignal import set_gauge

  set_gauge("database_size", 1024)
  ```

  ```php PHP theme={null}
  <?php
  use Appsignal\Appsignal;

  Appsignal::setGauge('database_size', 1024);
  ```

  ```java Java theme={null}
  import io.opentelemetry.api.GlobalOpenTelemetry;
  import io.opentelemetry.api.metrics.DoubleGauge;
  import io.opentelemetry.api.metrics.Meter;

  public void recordFileSize() {
      Meter meter = GlobalOpenTelemetry.getMeter("my-app");
      DoubleGauge gauge = meter.gaugeBuilder("database_size").build();

      gauge.set(1024);
  }
  ```

  ```go Go theme={null}
  package main

  import (
  	"context"
  	"go.opentelemetry.io/otel"
  	"go.opentelemetry.io/otel/metric"
  )

  func recordFileSize() {
  	meter := otel.Meter("my-app")
  	gauge, _ := meter.Float64Gauge("database_size")

  	gauge.Record(context.Background(), 1024)
  }
  ```
</CodeGroup>

Das Diagramm rendert den folgenden Anzeige-Wert für den angegebenen Dateigrößen-Formatierer:

* `Size in Bit` rendert „128 Bytes"
* `Size in Bytes` rendert „1 KB"
* `Size in Kilobits` rendert „128 KB"
* `Size in Kilobytes` rendert „1 MB"
* `Size in Megabytes` rendert „1 GB"

## Metrik-Tags

<Tip>
  Benutzerdefinierte Metrik-Tags erfordern die folgende AppSignal-Paket-/Gem-Version oder höher:

  <ul>
    <li>Ruby Gem Version `2.6.0`</li>
    <li>Elixir-Paket `1.6.0`</li>
    <li>Node.js-Paket `1.0.0`</li>
    <li>Python-Paket `0.3.0`</li>
  </ul>
</Tip>

Eine einzelne Metrik kann aus verschiedenen Datengruppen bestehen; beispielsweise könnte eine benutzerdefinierte Metrik „total\_orders" aus offenen und verarbeiteten Bestellungen bestehen.

Sie können einer Metrik mehrere Tags hinzufügen, um tiefere Einblicke in die von AppSignal gemeldeten Metrik-Daten zu erhalten. Jeder Tag wird durch eine eigene Linie in einem AppSignal-Diagramm dargestellt.

Standardmäßig setzen die AppSignal-Metrik-Helper keine Tags auf benutzerdefinierte Metriken.

So können Sie Tags in AppSignal-Diagrammen verwenden:

Tags können eine Linie in der Diagramm-Legende „beschriften", sodass leichter erkennbar ist, was jede Linie darstellt, wenn Sie mit der Maus darüberfahren.
Das Filtern nach Tags kann dieselbe Metrik in verschiedenen Kontexten in verschiedenen Diagrammen darstellen.

Um das Beste aus Metrik-Tags herauszuholen, empfehlen wir Folgendes:

* **Seien Sie konsistent beim Tagging:** Für eine optimale Nachverfolgung und Lesbarkeit der Diagramme raten wir davon ab, eine benutzerdefinierte Metrik sowohl mit als auch ohne Tags zu melden. Das Melden derselben Metrik auf verschiedene Arten kann zu Verwirrung führen und die genaue Interpretation der Daten erschweren.

* **Verwenden Sie immer dieselben Metrik-Tags:** Wir empfehlen, immer dieselbe Tag-Kombination zu verwenden, wenn Sie eine Metrik melden. Wenn eine Metrik beispielsweise in einem Bereich Ihrer App die Tags A und B verwendet, sollte sie diese in allen Bereichen verwenden. Vermeiden Sie es, die Tags zu ändern, da konsistentes Tagging das Erstellen von Diagrammen erleichtert.

* **Verwenden Sie einen begrenzten Wertebereich für Metrik-Tags:** Um übermäßig komplexe oder unleserliche Diagramme zu vermeiden, empfehlen wir, für Ihre benutzerdefinierten Metriken einen begrenzten Bereich von Tags zu verwenden, etwa Regionen (EU, US und Asien). Sie können eine umfassendere Analyse der Metrik-Daten Ihrer App durchführen, wenn Sie für alle Metrik-Daten Ihrer App einen begrenzten und präzisen Bereich von Tags verwenden.

Beim Implementieren von Metrik-Tagging sollten Sie generell eine robuste Tagging-Strategie entwickeln, die konsistent in Ihrer Anwendung angewendet werden kann und langfristig wenig bis keine Anpassungen erfordert.

<CodeGroup>
  ```ruby Ruby theme={null}
  Appsignal.set_gauge("database_size", 100, :region => "eu")
  Appsignal.set_gauge("database_size",  50, :region => "us")
  Appsignal.set_gauge("database_size", 200, :region => "asia")

  # Multiple tags per metric
  Appsignal.set_gauge("my_metric_name", 100, :tag_a => "a", :tag_b => "b")
  Appsignal.set_gauge("my_metric_name", 10, :tag_a => "a", :tag_b => "b")
  Appsignal.set_gauge("my_metric_name", 200, :tag_a => "b", :tag_b => "c")
  ```

  ```elixir Elixir theme={null}
  Appsignal.set_gauge("database_size", 100, %{region: "eu"})
  Appsignal.set_gauge("database_size",  50, %{region: "us"})
  Appsignal.set_gauge("database_size", 200, %{region: "asia"})

  # Multiple tags per metric
  Appsignal.set_gauge("my_metric_name", 100, %{tag_a: "a", tag_b: "b"})
  Appsignal.set_gauge("my_metric_name", 10, %{tag_a: "a", tag_b: "b"})
  Appsignal.set_gauge("my_metric_name", 200, %{tag_a: "b", tag_b: "c"})
  ```

  ```javascript JavaScript theme={null}
  const meter = Appsignal.client.metrics();

  meter.setGauge("database_size", 100, { region: "eu" });
  meter.setGauge("database_size", 50, { region: "us" });
  meter.setGauge("database_size", 200, { region: "asia" });

  // Multiple tags per metric
  meter.setGauge("my_metric_name", 100, { tag_a: "a", tag_b: "b" });
  meter.setGauge("my_metric_name", 10, { tag_a: "a", tag_b: "b" });
  meter.setGauge("my_metric_name", 200, { tag_a: "b", tag_b: "c" });
  ```

  ```python Python theme={null}
  from appsignal import set_gauge

  set_gauge("database_size", 100, {"region": "eu"})
  set_gauge("database_size",  50, {"region": "us"})
  set_gauge("database_size", 200, {"region": "asia"})

  # Multiple tags per metric
  set_gauge("my_metric_name", 100, {"tag_a": "a", "tag_b": "b"})
  set_gauge("my_metric_name",  10, {"tag_a": "a", "tag_b": "b"})
  set_gauge("my_metric_name", 200, {"tag_a": "b", "tag_b": "c"})
  ```

  ```php PHP theme={null}
  <?php
  use Appsignal\Appsignal;

  // Record gauge values with attributes (tags)
  Appsignal::setGauge('database_size', 100, ['region' => 'eu']);
  Appsignal::setGauge('database_size', 50, ['region' => 'us']);
  Appsignal::setGauge('database_size', 200, ['region' => 'asia']);

  // Multiple tags per metric
  Appsignal::setGauge('my_metric_name', 100, ['tag_a' => 'a', 'tag_b' => 'b']);
  Appsignal::setGauge('my_metric_name', 10, ['tag_a' => 'a', 'tag_b' => 'b']);
  Appsignal::setGauge('my_metric_name', 200, ['tag_a' => 'b', 'tag_b' => 'c']);
  ```

  ```java Java theme={null}
  import io.opentelemetry.api.GlobalOpenTelemetry;
  import io.opentelemetry.api.common.AttributeKey;
  import io.opentelemetry.api.common.Attributes;
  import io.opentelemetry.api.metrics.DoubleGauge;
  import io.opentelemetry.api.metrics.Meter;

  public void recordTaggedMetrics() {
      Meter meter = GlobalOpenTelemetry.getMeter("my-app");
      DoubleGauge gauge = meter.gaugeBuilder("database_size").build();

      // Record gauge values with attributes (tags)
      gauge.set(100, Attributes.of(
          AttributeKey.stringKey("region"), "eu"
      ));
      gauge.set(50, Attributes.of(
          AttributeKey.stringKey("region"), "us"
      ));
      gauge.set(200, Attributes.of(
          AttributeKey.stringKey("region"), "asia"
      ));

      // Multiple tags per metric
      DoubleGauge myGauge = meter.gaugeBuilder("my_metric_name").build();
      myGauge.set(100, Attributes.of(
          AttributeKey.stringKey("tag_a"), "a",
          AttributeKey.stringKey("tag_b"), "b"
      ));
      myGauge.set(10, Attributes.of(
          AttributeKey.stringKey("tag_a"), "a",
          AttributeKey.stringKey("tag_b"), "b"
      ));
      myGauge.set(200, Attributes.of(
          AttributeKey.stringKey("tag_a"), "b",
          AttributeKey.stringKey("tag_b"), "c"
      ));
  }
  ```

  ```go Go theme={null}
  package main

  import (
  	"context"
  	"go.opentelemetry.io/otel"
  	"go.opentelemetry.io/otel/attribute"
  	"go.opentelemetry.io/otel/metric"
  )

  func recordTaggedMetrics() {
  	meter := otel.Meter("my-app")
  	gauge, _ := meter.Float64Gauge("database_size")

  	// Record gauge values with attributes (tags)
  	gauge.Record(context.Background(), 100, metric.WithAttributes(
  		attribute.String("region", "eu"),
  	))
  	gauge.Record(context.Background(), 50, metric.WithAttributes(
  		attribute.String("region", "us"),
  	))
  	gauge.Record(context.Background(), 200, metric.WithAttributes(
  		attribute.String("region", "asia"),
  	))

  	// Multiple tags per metric
  	myGauge, _ := meter.Float64Gauge("my_metric_name")
  	myGauge.Record(context.Background(), 100, metric.WithAttributes(
  		attribute.String("tag_a", "a"),
  		attribute.String("tag_b", "b"),
  	))
  	myGauge.Record(context.Background(), 10, metric.WithAttributes(
  		attribute.String("tag_a", "a"),
  		attribute.String("tag_b", "b"),
  	))
  	myGauge.Record(context.Background(), 200, metric.WithAttributes(
  		attribute.String("tag_a", "b"),
  		attribute.String("tag_b", "c"),
  	))
  }
  ```
</CodeGroup>

## Metrik mit und ohne Tags rendern

Wenn Sie eine benutzerdefinierte Metrik erstellt haben und ihr mehrere Tags zugeordnet sind, können Sie die Metrik gleichzeitig mit und ohne den Tag in einem Diagramm rendern.

<CodeGroup>
  ```ruby Ruby theme={null}
  Appsignal.increment_counter("sign_ups", 1, region: "eu")
  Appsignal.increment_counter("sign_ups", 1)
  ```

  ```elixir Elixir theme={null}
  Appsignal.increment_counter("sign_ups", 1, %{region: "eu"})
  Appsignal.increment_counter("sign_ups", 1)
  ```

  ```javascript JavaScript theme={null}
  const meter = Appsignal.client.metrics();

  meter.incrementCounter("sign_ups", 1, { region: "eu" });
  meter.incrementCounter("sign_ups", 1);
  ```

  ```python Python theme={null}
  from appsignal import increment_counter

  increment_counter("sign_ups", 1, {"region": "eu"})
  increment_counter("sign_ups", 1)
  ```

  ```php PHP theme={null}
  <?php
  use Appsignal\Appsignal;

  Appsignal::incrementCounter('sign_ups', 1, ['region' => 'eu']);
  Appsignal::incrementCounter('sign_ups', 1);
  ```

  ```java Java theme={null}
  import io.opentelemetry.api.GlobalOpenTelemetry;
  import io.opentelemetry.api.common.AttributeKey;
  import io.opentelemetry.api.common.Attributes;
  import io.opentelemetry.api.metrics.LongCounter;
  import io.opentelemetry.api.metrics.Meter;

  public void recordMixedMetrics() {
      Meter meter = GlobalOpenTelemetry.getMeter("my-app");
      LongCounter counter = meter.counterBuilder("sign_ups").build();

      counter.add(1, Attributes.of(
          AttributeKey.stringKey("region"), "eu"
      ));
      counter.add(1);
  }
  ```

  ```go Go theme={null}
  package main

  import (
  	"context"
  	"go.opentelemetry.io/otel"
  	"go.opentelemetry.io/otel/attribute"
  	"go.opentelemetry.io/otel/metric"
  )

  func recordMixedMetrics() {
  	meter := otel.Meter("my-app")
  	counter, _ := meter.Int64Counter("sign_ups")

  	counter.Add(context.Background(), 1, metric.WithAttributes(
  		attribute.String("region", "eu"),
  	))
  	counter.Add(context.Background(), 1)
  }
  ```
</CodeGroup>

## Grafische Darstellung benutzerdefinierter Metriken

Sobald Sie mit dem Aufzeichnen benutzerdefinierter Metriken begonnen haben, können Sie sie mit dem Graph Builder in benutzerdefinierten Diagrammen verfolgen. Navigieren Sie zu einem bestehenden Dashboard oder verwenden Sie die Schaltfläche „Add dashboard" in der Dashboard-Navigation, um ein neues zu erstellen, und klicken Sie dann auf „Add graph".

<img src="https://mintcdn.com/appsignal-715f5a51/4TRZP0Sq9Zq7PAPW/assets/images/screenshots/metrics/custom/graph-builder.png?fit=max&auto=format&n=4TRZP0Sq9Zq7PAPW&q=85&s=095f9711aa9531e138596c955b6a81c2" alt="Graph Builder" width="2304" height="1720" data-path="assets/images/screenshots/metrics/custom/graph-builder.png" />

Beim Erstellen eines Diagramms können Sie auswählen, welche Metriken und Tags Sie darstellen möchten, und die Legenden und Beschriftungen Ihres Diagramms konfigurieren. Nach der Erstellung wird das Diagramm dem Dashboard hinzugefügt und zeigt alle aufgezeichneten benutzerdefinierten Metrik-Daten für den angegebenen Zeitraum an.

Weitere Informationen zu Dashboards und Diagrammen finden Sie in unserer [Dashboard-Dokumentation](/metrics/dashboards).
