De nos jours, Apache Kafka est l’un des logiciels les plus utilisés en informatique. Il est partout, c’est un standard de fait pour l’event streaming, et il est largement adopté par les grandes entreprises. Le projet Apache Kafka indique que Kafka est utilisé par des milliers d’organisations et qu’il a la confiance de plus de 80 % des entreprises du Fortune 100.

Dans de nombreuses organisations, Kafka est la colonne vertébrale de leurs systèmes, et l’écosystème Kafka ne cesse de croître.

Mais exploiter un cluster Kafka fiable peut s’avérer difficile : il possède de nombreux paramètres à la fois au niveau du broker et du topic, il est distribué, et bien sûr nous voulons qu’il soit hautement disponible.

La supervision est cruciale : sans une configuration adéquate pour collecter les métriques, construire des dashboards et finalement définir des alertes, l’équipe d’exploitation est aveugle.

Dans cet article, je décrirai les problèmes connus liés aux métriques Kafka et je proposerai une solution qui, je l’espère, en résout la plupart — voire peut-être tous.

Avez-vous importé un dashboard Grafana pour Kafka qui n’affiche aucune donnée ? Vous trouverez la réponse ci-dessous.

Qu’est-ce que Kafka, au juste ?

Je parie que si vous lisez cet article, vous savez parfaitement ce qu’est Kafka et à quoi il sert. Mais voici un rappel rapide :

Apache Kafka est une plateforme distribuée d’event streaming. La façon la plus simple d’y penser : Kafka est un log durable, en append-only, qui permet à de nombreuses applications d’y écrire des événements — les producers — et à beaucoup d’autres de relire ces événements — les consumers — en temps réel, à très haut débit.

Les événements vivent dans des topics, qui sont découpés en partitions et répliqués sur plusieurs brokers, les serveurs qui composent un cluster Kafka. Cela vous offre une scalabilité horizontale et une tolérance aux pannes : si un broker meurt, un autre réplica prend le relais, et les consumers continuent à lire sans manquer le moindre événement.

Aujourd’hui, Kafka se trouve au cœur de nombreux systèmes critiques : pipelines de paiement, détection de fraude, communication entre microservices, change data capture depuis les bases de données, agrégation de logs, télémétrie IoT. Quand il fonctionne bien, personne ne le remarque. Quand ce n’est pas le cas, c’est un désastre.

Le système de métriques au sein de Kafka — la racine du problème

Saviez-vous que les brokers Kafka exposent leurs métriques via deux systèmes de métriques différents ? Moi, non.

Les métriques Kafka sont gérées par deux bibliothèques de métriques distinctes s’exécutant dans la même JVM.

La plus ancienne est Yammer Metrics. Elle est présente dans Kafka depuis les premiers jours, et de nombreuses métriques fondamentales du broker — par exemple BytesInPerSec, MessagesInPerSec et UnderReplicatedPartitions — sont toujours gérées par elle.

La seconde est Kafka Metrics, org.apache.kafka.common.metrics, aussi connue sous le nom de SPI — Service Provider Interface. Elle a été introduite lors de la création des clients Java. Elle est également utilisée par les outils de l’écosystème comme Kafka Streams et Kafka Connect.

Ce n’est pas qu’une anecdote. La documentation officielle de monitoring d’Apache Kafka indique que Kafka utilise Yammer Metrics pour les métriques serveur, tandis que les clients Java utilisent Kafka Metrics. Les deux exposent leurs métriques via JMX et peuvent être configurés avec des reporters de stats enfichables.

Ces deux systèmes existent pour des raisons historiques. À un certain stade, toutes les nouvelles métriques ont été créées comme métriques SPI, mais il n’y avait aucun plan pour migrer les métriques Yammer vers le SPI.

Voici les principales différences :

DomaineMBeans Yammer MetricsMBeans Kafka Metrics
Usage principal dans KafkaMétriques classiques broker/serveur/controllerClients Java et modules broker/controller plus récents/communs
Configuration du reporterkafka.metrics.reportersmetric.reporters
Interface du reporterkafka.metrics.KafkaMetricsReporterorg.apache.kafka.common.metrics.MetricsReporter
Exposition JMX par défautReporter JMX Yammerorg.apache.kafka.common.metrics.JmxReporter
Forme du MBeanLe nom de la métrique fait généralement partie de l’ObjectName, sous la forme name=...L’ObjectName est généralement domaine + type + tags ; les noms de métriques sont généralement des attributs
AttributsAttributs Yammer génériques comme Value, Count, MeanRate, OneMinuteRate, percentilesNoms de métriques Kafka comme attributs, tels que byte-rate, throttle-time, connection-count, *-rate, *-total
Style d’exemplekafka.server:type=BrokerTopicMetrics,name=BytesInPerSec,topic=my-topickafka.server:type=Produce,user=alice,client-id=app1 avec des attributs comme byte-rate, throttle-time

Configuration des métriques Kafka — la méthode traditionnelle

La façon traditionnelle de superviser Kafka consiste à exporter les métriques depuis JMX avec le Prometheus JMX Exporter. C’est une bibliothèque qui s’exécute comme un agent Java et qui se configure avec un fichier de règles et un numéro de port.

Le port est utilisé comme endpoint Prometheus, avec /metrics ajouté.

Et le fichier de règles ? C’est un énorme fichier YAML, avec des tonnes d’expressions régulières. En général, personne n’en comprend vraiment les détails et se contente de l’utiliser, en espérant que celui qui l’a écrit savait ce qu’il faisait.

Vous devez donc téléverser le JMX Exporter sur tous les brokers, éventuellement créer ou éditer le fichier de config avec les règles — bon courage — et redémarrer les brokers. Si tout se passe bien, vous pouvez faire un curl sur l’endpoint de métriques et voir les métriques. Bien !

Ensuite, vous scrapez ces métriques dans Prometheus, téléchargez quelques dashboards Kafka dans Grafana, et… dans la plupart des cas, vous voyez « No Data ». Pourquoi ? Parce qu’il n’existe pas de standard unique pour les règles, la seule option est donc d’éditer le dashboard ou d’essayer d’en trouver un autre.

Mais ce n’est pas tout : chacun de ces systèmes de métriques peut être configuré avec une classe personnalisée, ou plugin. Regardez le tableau ci-dessus — oui, il y a deux paramètres. L’un avec le préfixe kafka, l’autre sans. L’un avec metric au singulier, l’autre avec metrics au pluriel.

Eh oui.

Hé, on est en 2026, Kafka peut-il utiliser OpenTelemetry ?

La réponse courte est : pas directement. Mais il existe quelques moyens d’apprendre à Kafka le protocole OpenTelemetry.

Il y a plusieurs façons de le faire :

  • JMX Exporter plus le receiver Prometheus dans l’OpenTelemetry Collector — les mêmes problèmes de mapping JMX que décrits ci-dessus.
  • Le receiver JMX de l’OpenTelemetry Collector — toujours basé sur JMX, nécessite d’exposer JMX, et le composant est désormais marqué comme déprécié, avec une recommandation d’utiliser à la place un programme Java JMX Gatherer autonome.
  • L’agent Java OpenTelemetry — une bonne option. Il peut collecter les métriques du broker Kafka via le module JMX Metric Insight, et la démo OpenTelemetry utilise cette approche pour Kafka. Mais si vous voulez un ensemble personnalisé de métriques JMX, vous vous retrouvez là encore avec un autre fichier de mapping de métriques.

La solution

Et si nous avions quelque chose qui répond à tous les problèmes décrits ci-dessus ?

Comme mentionné, les paramètres metric.reporters et kafka.metrics.reporters ne sont que des noms de classes. Les classes doivent implémenter respectivement les interfaces org.apache.kafka.common.metrics.MetricsReporter et kafka.metrics.KafkaMetricsReporter.

Nous avons donc eu une idée : une bibliothèque avec les caractéristiques suivantes.

OTLP natif, sans détour par JMX

La plupart des stacks d’observabilité Kafka greffent jmx_exporter, ou quelque chose de similaire, en tant qu’agent JVM, puis scrapent les MBeans via un endpoint HTTP, puis poussent vers un collector.

Ce plugin vit à l’intérieur du processus Kafka et parle OTLP directement au collector — un processus de moins, une surface de configuration de moins, et aucun fichier YAML de règles JMX à maintenir.

Un seul plugin, les deux registres Kafka

Les brokers Kafka exposent leurs métriques via deux systèmes parallèles : le SPI Kafka, configuré avec metric.reporters, et l’ancien registre Yammer/Coda Hale.

Plusieurs signaux internes au broker — UnderReplicatedPartitions, OfflinePartitionsCount, ActiveControllerCount et les BrokerTopicMetrics par topic — ne s’enregistrent qu’auprès de Yammer.

OtlpMetricReporter se rattache aux deux avec une seule configuration. Le même JAR s’exécute sans modification sur les clients, où le côté Yammer se désactive automatiquement.

Fail-safe par conception — Kafka n’est jamais bloqué

Les callbacks de métriques comme metricChange et metricRemoval ne touchent qu’une ConcurrentHashMap en mémoire. Toutes les I/O se produisent sur un thread d’ordonnanceur daemon.

Si le collector est injoignable, l’appel d’export expire, le batch est abandonné, et le tick suivant repart de zéro. Pas de file de retry, pas de mémoire non bornée, aucun impact sur la latence de produce/fetch de Kafka.

Le contexte du broker devient des labels Prometheus de première classe

Kafka invoque MetricsReporter.contextChange(MetricsContext) avec l’identifiant du cluster, l’identifiant du node/broker et la version de Kafka.

Le plugin capture ces valeurs et les attache comme attributs de ressource OTLP. Elles apparaissent sous forme de labels — kafka_cluster_id, kafka_node_id ou kafka_broker_id — sur chaque série, de sorte que by(kafka_cluster_id, kafka_node_id) fonctionne en PromQL sans aucun câblage supplémentaire.

Mesdames et messieurs, voici monedula-metrics-reporter

monedula-metrics-reporter est une bibliothèque open source qui remplit ces exigences — et plus encore.

Elle exporte les métriques Kafka directement via OTLP en utilisant gRPC ou HTTP, prend en charge Kafka 3.x et 4.x sur Java 17+, et peut également émettre les métriques runtime de la JVM sur le même pipeline.

Elle inclut aussi des fonctionnalités pratiques pour la production, comme :

  • l’allow-listing des métriques,
  • des attributs de ressource personnalisés,
  • la configuration TLS et mTLS,
  • la compression,
  • des métriques d’auto-supervision du reporter,
  • et la prise en charge à la fois des brokers et des clients.

Le reporter émet aussi ses propres métriques de santé, par exemple :

  • monedula_reporter_export_success_total,
  • monedula_reporter_export_failure_total,
  • monedula_reporter_export_duration_ms.

Ainsi, si le pipeline du collector tombe en panne, vous n’obtenez pas seulement du silence. Vous obtenez des signaux indiquant que le reporter lui-même échoue à exporter.

Le projet est aussi livré avec un quickstart facile à utiliser qui démontre le flux complet avec Kafka, l’OpenTelemetry Collector, Prometheus et Grafana. Et comme les dashboards font partie du problème, il inclut un ensemble soigné de dashboards Grafana prêts à l’emploi qui correspondent aux métriques produites par le plugin.

Vous pouvez le trouver sur GitHub, le compiler localement et le tester avec le quickstart. Des artefacts précompilés arrivent bientôt.

Si vous trouvez un bug ou avez une suggestion d’amélioration, n’hésitez pas à créer une issue sur GitHub.

Résumé

La supervision de Kafka est plus difficile qu’elle ne devrait l’être, parce que Kafka expose ses métriques via deux systèmes de métriques différents, parce que la plupart des configurations de production reposent encore sur JMX, et parce que chaque mapping JMX-vers-Prometheus crée une couche de compatibilité supplémentaire entre le broker, Prometheus et les dashboards Grafana.

monedula-metrics-reporter adopte une approche différente : il s’exécute comme un reporter de métriques Kafka, exporte les métriques nativement via OTLP, gère les deux registres de métriques de Kafka, et est livré avec des dashboards correspondant aux métriques émises.

Alors, les métriques Kafka doivent-elles vraiment être si compliquées ?

Espérons que ce ne soit plus le cas.