Heutzutage ist Apache Kafka eine der am weitesten verbreiteten Software-Komponenten in der IT. Es ist überall, es ist der De-facto-Standard für Event-Streaming und es ist in großen Unternehmen weit verbreitet. Das Apache-Kafka-Projekt sagt, dass Kafka von Tausenden von Organisationen genutzt wird und mehr als 80 % der Fortune-100-Unternehmen darauf vertrauen.

In vielen Organisationen ist Kafka das Rückgrat ihrer Systeme, und das Kafka-Ökosystem wächst ständig.

Aber den Betrieb eines zuverlässigen Kafka-Clusters kann anspruchsvoll sein: Es hat viele Einstellungen auf Broker- und Topic-Ebene, es ist verteilt, und natürlich wollen wir, dass es hochverfügbar ist.

Monitoring ist entscheidend: ohne ein passendes Setup zum Sammeln von Metriken, zum Erstellen von Dashboards und schließlich zum Definieren von Alerts ist das Operations-Team blind.

In diesem Artikel beschreibe ich die bekannten Probleme mit Kafka-Metriken und schlage eine Lösung vor, die hoffentlich die meisten davon löst — oder vielleicht sogar alle.

Haben Sie schon einmal ein Grafana-Kafka-Dashboard importiert und es zeigt keine Daten an? Die Antwort finden Sie weiter unten.

Was ist Kafka eigentlich?

Ich wette, wenn Sie diesen Artikel lesen, wissen Sie ganz genau, was Kafka ist und welchen Zweck es hat. Aber hier eine kurze Zusammenfassung:

Apache Kafka ist eine verteilte Event-Streaming-Plattform. Am einfachsten lässt es sich so vorstellen: Kafka ist ein dauerhaftes, nur anhängbares Log (append-only), in das viele Anwendungen Events schreiben können — Producer — und aus dem viele andere diese Events in Echtzeit und mit sehr hohem Durchsatz zurücklesen — Consumer.

Events leben in Topics, die in Partitionen aufgeteilt und über mehrere Broker repliziert werden, die Server, die einen Kafka-Cluster bilden. Das verschafft Ihnen horizontale Skalierbarkeit und Fehlertoleranz: Wenn ein Broker ausfällt, übernimmt ein anderes Replikat, und die Consumer lesen weiter, ohne einen Takt auszulassen.

Heute steht Kafka im Herzen vieler geschäftskritischer Systeme: Zahlungspipelines, Betrugserkennung, Microservice-Kommunikation, Change Data Capture aus Datenbanken, Log-Aggregation, IoT-Telemetrie. Wenn es gut funktioniert, bemerkt es niemand. Wenn nicht, ist es eine Katastrophe.

Das Metriksystem in Kafka — die Wurzel des Problems

Wussten Sie, dass Kafka-Broker Metriken über zwei verschiedene Metriksysteme bereitstellen? Ich nicht.

Kafka-Metriken werden von zwei separaten Metrik-Bibliotheken verarbeitet, die in derselben JVM laufen.

Die ältere ist Yammer Metrics. Sie ist seit den frühen Tagen in Kafka, und viele grundlegende Broker-Metriken — zum Beispiel BytesInPerSec, MessagesInPerSec und UnderReplicatedPartitions — werden weiterhin von ihr verarbeitet.

Die zweite ist Kafka Metrics, org.apache.kafka.common.metrics, auch bekannt als SPI — Service Provider Interface. Sie wurde eingeführt, als die Java-Clients erstellt wurden. Sie wird auch von Ökosystem-Tools wie Kafka Streams und Kafka Connect verwendet.

Das ist nicht nur Trivia. Die offizielle Apache-Kafka-Monitoring-Dokumentation sagt, dass Kafka Yammer Metrics für Server-Metriken verwendet, während Java-Clients Kafka Metrics nutzen. Beide stellen Metriken über JMX bereit und können mit einsteckbaren Stats-Reportern konfiguriert werden.

Diese beiden Systeme existieren aus historischen Gründen. Irgendwann wurden alle neuen Metriken als SPI-Metriken erstellt, aber es gab keinen Plan, die Yammer-Metriken auf SPI zu migrieren.

Hier sind die wichtigsten Unterschiede:

BereichYammer-Metrics-MBeansKafka-Metrics-MBeans
Hauptnutzung in KafkaKlassische Broker-/Server-/Controller-MetrikenJava-Clients und neuere/gemeinsame Broker-/Controller-Module
Reporter-Konfigurationkafka.metrics.reportersmetric.reporters
Reporter-Interfacekafka.metrics.KafkaMetricsReporterorg.apache.kafka.common.metrics.MetricsReporter
Standard-JMX-BereitstellungYammer-JMX-Reporterorg.apache.kafka.common.metrics.JmxReporter
MBean-FormDer Metrikname ist meist Teil des ObjectName, als name=...ObjectName ist meist Domain + Type + Tags; Metriknamen sind meist Attribute
AttributeGenerische Yammer-Attribute wie Value, Count, MeanRate, OneMinuteRate, PerzentileKafka-Metriknamen als Attribute, etwa byte-rate, throttle-time, connection-count, *-rate, *-total
Beispielformkafka.server:type=BrokerTopicMetrics,name=BytesInPerSec,topic=my-topickafka.server:type=Produce,user=alice,client-id=app1 mit Attributen wie byte-rate, throttle-time

Kafka-Metriken einrichten — der alte Weg

Der traditionelle Weg, Kafka zu überwachen, ist der Export von Metriken aus JMX mit dem Prometheus JMX Exporter. Es ist eine Bibliothek, die als Java-Agent läuft und mit einer Regeldatei und einer Portnummer konfiguriert wird.

Der Port wird als Prometheus-Endpunkt verwendet, mit angehängtem /metrics.

Und die Regeldatei? Es ist eine riesige YAML-Datei mit Unmengen von regulären Ausdrücken. Normalerweise versteht niemand die Details vollständig und nutzt sie einfach, in der Hoffnung, dass derjenige, der sie geschrieben hat, wusste, was er tat.

Sie müssen also den JMX Exporter auf alle Broker hochladen, möglicherweise die Konfigurationsdatei mit Regeln erstellen oder bearbeiten — viel Glück damit — und die Broker neu starten. Wenn alles glattläuft, können Sie den Metrik-Endpunkt mit curl abrufen und die Metriken sehen. Gut!

Dann scrapen Sie diese Metriken in Prometheus, laden einige Kafka-Dashboards in Grafana herunter und … in den meisten Fällen sehen Sie “No Data”. Warum? Weil es keinen einzigen Standard für die Regeln gibt, sodass die einzige Option darin besteht, das Dashboard zu bearbeiten oder zu versuchen, ein anderes zu finden.

Aber da ist noch mehr: Jedes dieser Metriksysteme kann mit einer benutzerdefinierten Klasse oder einem Plugin konfiguriert werden. Schauen Sie sich die Tabelle oben an — ja, es gibt zwei Einstellungen. Eine mit dem kafka-Präfix, die andere ohne. Eine mit metric im Singular, die andere mit metrics im Plural.

Oh ja.

Hey, wir haben 2026, kann Kafka OpenTelemetry verwenden?

Die kurze Antwort lautet: nicht direkt. Aber es gibt einige Wege, Kafka das OpenTelemetry-Protokoll beizubringen.

Es gibt mehrere Möglichkeiten, das zu tun:

  • JMX Exporter plus der Prometheus-Receiver im OpenTelemetry Collector — dieselben JMX-Mapping-Probleme wie oben beschrieben.
  • OpenTelemetry-Collector-JMX-Receiver — weiterhin JMX-basiert, erfordert die Bereitstellung von JMX, und die Komponente ist mittlerweile als deprecated markiert, mit der Empfehlung, stattdessen ein eigenständiges JMX-Gatherer-Java-Programm zu verwenden.
  • OpenTelemetry-Java-Agent — eine gute Option. Er kann Kafka-Broker-Metriken über das JMX-Metric-Insight-Modul sammeln, und die OpenTelemetry-Demo verwendet diesen Ansatz für Kafka. Aber wenn Sie einen benutzerdefinierten Satz von JMX-Metriken wollen, landen Sie wieder bei einer weiteren Metrik-Mapping-Datei.

Die Lösung

Was, wenn wir etwas hätten, das alle oben beschriebenen Probleme angeht?

Wie erwähnt sind die Einstellungen metric.reporters und kafka.metrics.reporters lediglich Klassennamen. Die Klassen müssen jeweils die Interfaces org.apache.kafka.common.metrics.MetricsReporter und kafka.metrics.KafkaMetricsReporter implementieren.

Also hatten wir die Idee: eine Bibliothek mit den folgenden Eigenschaften.

Natives OTLP, kein JMX-Umweg

Die meisten Kafka-Observability-Stacks schrauben jmx_exporter oder etwas Ähnliches als JVM-Agent an, scrapen dann MBeans über einen HTTP-Endpunkt und pushen dann zu einem Collector.

Dieses Plugin lebt innerhalb des Kafka-Prozesses und spricht OTLP direkt mit dem Collector — ein Prozess weniger, eine Konfigurationsoberfläche weniger und keine JMX-Regel-YAMLs, die gepflegt werden müssen.

Ein Plugin, beide Kafka-Registries

Kafka-Broker stellen Metriken über zwei parallele Systeme bereit: die Kafka-SPI, konfiguriert mit metric.reporters, und die Legacy-Yammer-/Coda-Hale-Registry.

Mehrere broker-interne Signale — UnderReplicatedPartitions, OfflinePartitionsCount, ActiveControllerCount und die per-Topic-BrokerTopicMetrics — registrieren sich nur bei Yammer.

OtlpMetricReporter bindet sich mit einer einzigen Konfiguration an beide an. Dieselbe JAR läuft unverändert auf Clients, wo sich die Yammer-Seite automatisch deaktiviert.

Fail-safe by Design — Kafka wird nie blockiert

Metrik-Callbacks wie metricChange und metricRemoval berühren nur eine In-Memory-ConcurrentHashMap. Alle I/O laufen auf einem Daemon-Scheduler-Thread.

Wenn der Collector nicht erreichbar ist, läuft der Export-Aufruf in einen Timeout, der Batch wird verworfen, und der nächste Tick startet frisch. Keine Retry-Queue, kein unbegrenzter Speicher, keine Auswirkung auf die Kafka-Produce-/Fetch-Latenz.

Broker-Kontext wird zu erstklassigen Prometheus-Labels

Kafka ruft MetricsReporter.contextChange(MetricsContext) mit Cluster-ID, Node-/Broker-ID und Kafka-Version auf.

Das Plugin erfasst diese Werte und hängt sie als OTLP-Resource-Attribute an. Sie erscheinen als Labels — kafka_cluster_id, kafka_node_id oder kafka_broker_id — an jeder Zeitreihe, sodass by(kafka_cluster_id, kafka_node_id) in PromQL ohne zusätzliche Verdrahtung funktioniert.

Meine Damen und Herren, hier ist monedula-metrics-reporter

monedula-metrics-reporter ist eine Open-Source-Bibliothek, die diese Anforderungen erfüllt — und mehr.

Sie exportiert Kafka-Metriken direkt über OTLP mittels gRPC oder HTTP, unterstützt Kafka 3.x und 4.x auf Java 17+ und kann auch JVM-Laufzeitmetriken über dieselbe Pipeline ausgeben.

Sie enthält außerdem praktische Produktionsfunktionen wie:

  • Metrik-Allow-Listing,
  • benutzerdefinierte Resource-Attribute,
  • TLS- und mTLS-Konfiguration,
  • Komprimierung,
  • Self-Monitoring-Metriken des Reporters,
  • und Unterstützung für sowohl Broker als auch Clients.

Der Reporter gibt auch eigene Health-Metriken aus, zum Beispiel:

  • monedula_reporter_export_success_total,
  • monedula_reporter_export_failure_total,
  • monedula_reporter_export_duration_ms.

Wenn also die Collector-Pipeline ausfällt, bekommen Sie nicht nur Stille. Sie bekommen Signale, dass der Reporter selbst beim Export scheitert.

Das Projekt wird außerdem mit einem leicht zu nutzenden Quickstart ausgeliefert, der den vollständigen Ablauf mit Kafka, dem OpenTelemetry Collector, Prometheus und Grafana demonstriert. Und weil Dashboards Teil des Problems sind, enthält es eine kuratierte Sammlung sofort einsatzbereiter Grafana-Dashboards, die zu den vom Plugin erzeugten Metriken passen.

Sie finden es auf GitHub, können es lokal bauen und mit dem Quickstart testen. Vorgefertigte Artefakte kommen bald.

Wenn Sie einen Bug finden oder einen Verbesserungsvorschlag haben, erstellen Sie gerne ein Issue auf GitHub.

Zusammenfassung

Kafka-Monitoring ist schwieriger, als es sein sollte, weil Kafka Metriken über zwei verschiedene Metriksysteme bereitstellt, die meisten Produktions-Setups weiterhin auf JMX setzen und jedes JMX-zu-Prometheus-Mapping eine weitere Kompatibilitätsschicht zwischen Broker, Prometheus und Grafana-Dashboards erzeugt.

monedula-metrics-reporter verfolgt einen anderen Ansatz: Er läuft als Kafka-Metrics-Reporter, exportiert Metriken nativ über OTLP, behandelt beide Kafka-Metrik-Registries und wird mit Dashboards ausgeliefert, die zu den ausgegebenen Metriken passen.

Also, müssen Kafka-Metriken so schwierig sein?

Hoffentlich nicht mehr.