Wir bauen einen benutzerdefinierten Prometheus-Exporter mit Quarkus Jakarta, wobei wir uns darauf konzentrieren, hohe Kardinalität zu vermeiden und effiziente Metriken sicherzustellen. Machen Sie sich bereit für ein wenig Metrik-Magie!

Warum benutzerdefinierte Exporter? Erfinden wir das Rad neu?

Bevor wir loslegen, wollen wir die Frage klären: Warum sich die Mühe machen, einen benutzerdefinierten Exporter zu erstellen, wenn es viele fertige Lösungen gibt?

  • Maßgeschneiderte Metriken: Ihre App ist einzigartig, und manchmal benötigen Sie Metriken, die nicht standardmäßig verfügbar sind.
  • Leistungsoptimierung: Benutzerdefinierte Exporter ermöglichen es Ihnen, genau zu bestimmen, was Sie messen, und so möglicherweise den Overhead zu reduzieren.
  • Vermeidung von Metrik-Explosionen: Mit großer Macht kommt große Verantwortung – und die Fähigkeit, Fallstricke hoher Kardinalität zu vermeiden.

Einrichtung des Quarkus Jakarta-Projekts

Zuallererst, lassen Sie uns unser Quarkus-Projekt einrichten. Wenn Sie neu bei Quarkus sind, denken Sie daran, dass es die Superhelden-Version von Jakarta EE ist – schneller als eine Kugel und stärker als eine Lokomotive.

Erstellen Sie ein neues Quarkus-Projekt mit dem folgenden Maven-Befehl:

mvn io.quarkus:quarkus-maven-plugin:2.16.5.Final:create \
    -DprojectGroupId=com.example \
    -DprojectArtifactId=custom-prometheus-exporter \
    -DclassName="com.example.ExporterResource" \
    -Dpath="/exporter"

Fügen Sie nun die notwendigen Abhängigkeiten zu unserer pom.xml hinzu:

<dependencies>
    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-resteasy-reactive</artifactId>
    </dependency>
    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-micrometer-registry-prometheus</artifactId>
    </dependency>
</dependencies>

Der Kern der Sache: Den Exporter bauen

Jetzt, da unser Projekt eingerichtet ist, erstellen wir unseren benutzerdefinierten Exporter. Wir konzentrieren uns auf ein hypothetisches Szenario, in dem wir ein komplexes E-Commerce-System überwachen.

package com.example;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tags;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

import java.util.Random;

@Path("/exporter")
public class ExporterResource {

    @Inject
    MeterRegistry registry;

    private final Random random = new Random();

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        // Simuliere einige Metriken
        recordOrderMetrics();
        recordUserMetrics();
        return "Metriken aktualisiert!";
    }

    private void recordOrderMetrics() {
        // Anstatt Metriken pro Produkt (hohe Kardinalität) aufzuzeichnen,
        // zeichnen wir aggregierte Metriken pro Kategorie auf
        String[] categories = {"Elektronik", "Kleidung", "Bücher", "Haushalt"};
        for (String category : categories) {
            double orderValue = 100 + random.nextDouble() * 900; // Zufälliger Bestellwert zwischen 100 und 1000
            registry.gauge("ecommerce.order.value", Tags.of("category", category), orderValue);
        }
    }

    private void recordUserMetrics() {
        // Anstatt Metriken pro Benutzer aufzuzeichnen, verwenden wir Buckets
        int activeUsers = 1000 + random.nextInt(9000); // Zufällige Zahl zwischen 1000 und 10000
        String userBucket = activeUsers < 5000 ? "niedrig" : "hoch";
        registry.gauge("ecommerce.active.users", Tags.of("load", userBucket), activeUsers);
    }
}

Vermeidung der Falle hoher Kardinalität

Hohe Kardinalität ist der Schreckgespenst von Prometheus-Setups. Es ist, als würde man alle in Ihrer Stadt zu einer Hausparty einladen – es wird chaotisch. So vermeiden wir das:

  • Kategorisierung: Anstatt Metriken für jedes einzelne Produkt zu verfolgen (was Tausende sein könnten), gruppieren wir sie in Kategorien.
  • Bucketing: Für Benutzermetriken verwenden wir einfache "niedrig" oder "hoch" Buckets, anstatt jeden Benutzer einzeln zu verfolgen.

Denken Sie daran, das Ziel ist es, genügend Details zu haben, um nützlich zu sein, ohne in Daten zu ertrinken.

Sicherstellung effizienter Metriken

Effizienz bedeutet nicht nur, hohe Kardinalität zu vermeiden. Hier sind einige weitere Tipps, um Ihre Metriken schlank und effizient zu halten:

  1. Verwenden Sie Labels mit Bedacht: Labels sind mächtig, können aber schnell zu Metrik-Explosionen führen, wenn sie übermäßig verwendet werden.
  2. Aggregieren Sie, wo möglich: Manchmal ist eine Summe oder ein Durchschnitt nützlicher als einzelne Datenpunkte.
  3. Wählen Sie geeignete Metriktypen: Gauges, Zähler und Histogramme haben jeweils ihren Platz. Verwenden Sie sie weise.
  4. Setzen Sie Aufbewahrungsrichtlinien: Nicht alle Metriken müssen für immer aufbewahrt werden. Setzen Sie geeignete Aufbewahrungszeiträume in Prometheus.

Testen Ihres Exporters

Bevor wir uns auf die Schulter klopfen, lassen Sie uns sicherstellen, dass das Ganze tatsächlich funktioniert. Starten Sie Ihre Quarkus-Anwendung:

./mvnw quarkus:dev

Rufen Sie nun den Endpunkt auf, um einige Metriken zu generieren:

curl http://localhost:8080/exporter

Schließlich überprüfen Sie Ihre Metriken unter:

curl http://localhost:8080/q/metrics

Sie sollten etwas Ähnliches sehen:

# HELP ecommerce_order_value 
# TYPE ecommerce_order_value gauge
ecommerce_order_value{category="Elektronik"} 543.21
ecommerce_order_value{category="Kleidung"} 321.54
ecommerce_order_value{category="Bücher"} 123.45
ecommerce_order_value{category="Haushalt"} 987.65

# HELP ecommerce_active_users 
# TYPE ecommerce_active_users gauge
ecommerce_active_users{load="hoch"} 7523.0

Der Beweis liegt im Pudding: Ihre Metriken analysieren

Jetzt, da unser Exporter läuft, lassen Sie uns darüber sprechen, was wir mit diesen Metriken tun können. Hier sind einige Prometheus-Abfragen, die Sie nützlich finden könnten:

# Durchschnittlicher Bestellwert über alle Kategorien
avg(ecommerce_order_value)

# Gesamtzahl der aktiven Benutzer
sum(ecommerce_active_users)

# Höchster Bestellwert nach Kategorie
max(ecommerce_order_value) by (category)

Diese Abfragen geben Ihnen einen Vorgeschmack auf die Einblicke, die Sie aus Ihren sorgfältig erstellten Metriken gewinnen können.

Zusammenfassung: Gelerntes

Ein benutzerdefinierter Prometheus-Exporter zu erstellen, bedeutet nicht nur, einige Metriken zusammenzustellen und es dabei zu belassen. Es ist eine Kunstform, die sorgfältige Überlegungen erfordert, was und wie Sie messen. Hier sind die wichtigsten Erkenntnisse:

  • Seien Sie immer auf der Hut vor hoher Kardinalität. Sie ist der stille Killer von Prometheus-Setups.
  • Aggregieren und kategorisieren Sie, wo möglich, um Ihre Metriken sinnvoll und handhabbar zu halten.
  • Wählen Sie Ihre Labels sorgfältig. Sie sind mächtig, aber mit großer Macht kommt große Verantwortung.
  • Testen, iterieren und verfeinern. Ihr erster Versuch wird wahrscheinlich nicht perfekt sein, und das ist in Ordnung.

Denken Sie daran, das Ziel ist es, Metriken zu haben, die umsetzbare Einblicke bieten, nicht nur eine Flut von Zahlen. Viel Spaß beim Überwachen!

Denkanstoß

"Das Ziel des Rechnens ist Einsicht, nicht Zahlen." - Richard Hamming

Während Sie Ihren benutzerdefinierten Exporter weiter verfeinern, behalten Sie dieses Zitat im Hinterkopf. Es geht nicht darum, wie viele Metriken Sie generieren können, sondern um die Einblicke, die Sie daraus gewinnen können.

Zusätzliche Ressourcen

Möchten Sie tiefer eintauchen? Schauen Sie sich diese Ressourcen an:

Gehen Sie nun hinaus und exportieren Sie diese Metriken wie ein Profi! Und denken Sie daran, in der Welt des Monitorings ist weniger oft mehr. Es sei denn, wir sprechen über Betriebszeit – dann ist mehr definitiv mehr.