W dzisiejszych czasach Apache Kafka to jeden z najpowszechniej używanych elementów oprogramowania w IT. Jest wszędzie, stanowi de facto standard dla strumieniowania zdarzeń i jest szeroko stosowana w dużych przedsiębiorstwach. Projekt Apache Kafka podaje, że Kafka jest używana przez tysiące organizacji i obdarzana zaufaniem przez ponad 80% firm z listy Fortune 100.

W wielu organizacjach Kafka stanowi kręgosłup ich systemów, a ekosystem Kafki nieustannie się rozrasta.

Ale prowadzenie niezawodnego klastra Kafka może być wyzwaniem: ma mnóstwo ustawień zarówno na poziomie brokera, jak i topica, jest rozproszona i — co oczywiste — chcemy, aby była wysoce dostępna.

Monitorowanie jest kluczowe: bez właściwej konfiguracji zbierania metryk, budowania dashboardów i ostatecznie definiowania alertów zespół operacyjny jest ślepy.

W tym artykule opiszę znane problemy z metrykami Kafki i zaproponuję rozwiązanie, które — mam nadzieję — rozwiązuje większość z nich, a może nawet wszystkie.

Zaimportowałeś dashboard Kafki w Grafanie, a on nie pokazuje żadnych danych? Odpowiedź znajdziesz poniżej.

Czym właściwie jest Kafka?

Założę się, że jeśli czytasz ten artykuł, doskonale wiesz, czym jest Kafka i jaki jest jej cel. Ale oto szybkie przypomnienie:

Apache Kafka to rozproszona platforma strumieniowania zdarzeń. Najprościej można o niej myśleć tak: Kafka to trwały, dopisywany na końcu (append-only) log, który pozwala wielu aplikacjom zapisywać do niego zdarzenia — producentom — i wielu innym odczytywać te zdarzenia z powrotem — konsumentom — w czasie rzeczywistym, przy bardzo dużej przepustowości.

Zdarzenia żyją w topicach, które są dzielone na partycje i replikowane na wielu brokerach — serwerach tworzących klaster Kafka. Daje to skalowalność poziomą i odporność na awarie: jeśli broker padnie, inna replika przejmuje jego rolę, a konsumenci czytają dalej, nie tracąc ani chwili.

Dziś Kafka stoi w sercu wielu systemów o znaczeniu krytycznym: potoków płatniczych, wykrywania oszustw, komunikacji między mikroserwisami, przechwytywania zmian danych z baz danych (change data capture), agregacji logów, telemetrii IoT. Gdy działa dobrze, nikt tego nie zauważa. Gdy działa źle, jest katastrofa.

System metryk wewnątrz Kafki — źródło problemu

Czy wiedziałeś, że brokery Kafki udostępniają metryki przez dwa różne systemy metryk? Ja nie wiedziałem.

Metryki Kafki są obsługiwane przez dwie odrębne biblioteki metryk działające w tej samej maszynie JVM.

Starsza z nich to Yammer Metrics. Jest w Kafce od początków jej istnienia i wiele fundamentalnych metryk brokera — na przykład BytesInPerSec, MessagesInPerSec i UnderReplicatedPartitions — jest nadal przez nią obsługiwanych.

Druga to Kafka Metrics, org.apache.kafka.common.metrics, znana również jako SPI — Service Provider Interface. Została wprowadzona, gdy powstawały klienty Javy. Jest też używana przez narzędzia ekosystemu, takie jak Kafka Streams i Kafka Connect.

To nie jest tylko ciekawostka. Oficjalna dokumentacja monitorowania Apache Kafka mówi, że Kafka używa Yammer Metrics do metryk serwerowych, podczas gdy klienty Javy używają Kafka Metrics. Oba systemy udostępniają metryki przez JMX i można je skonfigurować z podłączanymi reporterami statystyk (pluggable stats reporters).

Te dwa systemy istnieją z powodów historycznych. Na pewnym etapie wszystkie nowe metryki tworzono jako metryki SPI, ale nie było planu migracji metryk Yammer do SPI.

Oto główne różnice:

ObszarMBeany Yammer MetricsMBeany Kafka Metrics
Główne zastosowanie w KafceKlasyczne metryki brokera/serwera/kontroleraKlienty Javy oraz nowsze/wspólne moduły brokera/kontrolera
Konfiguracja reporterakafka.metrics.reportersmetric.reporters
Interfejs reporterakafka.metrics.KafkaMetricsReporterorg.apache.kafka.common.metrics.MetricsReporter
Domyślne udostępnianie przez JMXReporter JMX Yammerorg.apache.kafka.common.metrics.JmxReporter
Kształt MBeanNazwa metryki jest zwykle częścią ObjectName, jako name=...ObjectName to zwykle domena + typ + tagi; nazwy metryk są zwykle atrybutami
AtrybutyGeneryczne atrybuty Yammer, jak Value, Count, MeanRate, OneMinuteRate, percentyleNazwy metryk Kafki jako atrybuty, takie jak byte-rate, throttle-time, connection-count, *-rate, *-total
Przykładowy stylkafka.server:type=BrokerTopicMetrics,name=BytesInPerSec,topic=my-topickafka.server:type=Produce,user=alice,client-id=app1 z atrybutami takimi jak byte-rate, throttle-time

Konfiguracja metryk Kafki — stary sposób

Tradycyjnym sposobem monitorowania Kafki jest eksportowanie metryk z JMX za pomocą Prometheus JMX Exporter. To biblioteka, która działa jako agent Javy i jest konfigurowana plikiem reguł oraz numerem portu.

Port jest używany jako endpoint Prometheusa, z dopisanym /metrics.

A plik reguł? To ogromny plik YAML, z masą wyrażeń regularnych. Zwykle nikt nie rozumie w pełni szczegółów i po prostu go używa, mając nadzieję, że ktokolwiek go napisał, wiedział, co robi.

Musisz więc wgrać JMX Exporter na wszystkie brokery, ewentualnie utworzyć lub edytować plik konfiguracyjny z regułami — powodzenia z tym — i zrestartować brokery. Jeśli wszystko pójdzie gładko, możesz wykonać curl na endpoincie metryk i zobaczyć metryki. Świetnie!

Następnie zbierasz (scrape) te metryki do Prometheusa, pobierasz jakieś dashboardy Kafki w Grafanie i… w większości przypadków widzisz „No Data”. Dlaczego? Bo nie ma jednego standardu dla reguł, więc jedyną opcją jest edycja dashboardu albo próba znalezienia innego.

Ale to nie wszystko: każdy z tych systemów metryk można skonfigurować z niestandardową klasą, czyli wtyczką. Spójrz na tabelę powyżej — tak, są dwa ustawienia. Jedno z prefiksem kafka, drugie bez. Jedno z metric w liczbie pojedynczej, drugie z metrics w liczbie mnogiej.

No tak.

Hej, mamy rok 2026, czy Kafka może używać OpenTelemetry?

Krótka odpowiedź brzmi: nie bezpośrednio. Ale istnieją sposoby, by nauczyć Kafkę protokołu OpenTelemetry.

Można to zrobić na kilka sposobów:

  • JMX Exporter plus receiver Prometheusa w OpenTelemetry Collector — te same problemy z mapowaniem JMX, co opisano powyżej.
  • Receiver JMX OpenTelemetry Collector — wciąż oparty na JMX, wymaga udostępnienia JMX, a komponent jest obecnie oznaczony jako przestarzały (deprecated), z zaleceniem użycia w zamian samodzielnego programu Java JMX Gatherer.
  • Agent Java OpenTelemetry — dobra opcja. Potrafi zbierać metryki brokera Kafki przez moduł JMX Metric Insight, a demo OpenTelemetry używa tego podejścia dla Kafki. Ale jeśli chcesz mieć niestandardowy zestaw metryk JMX, i tak skończysz z kolejnym plikiem mapowania metryk.

Rozwiązanie

Co by było, gdybyśmy mieli coś, co rozwiązuje wszystkie opisane powyżej problemy?

Jak wspomniano, ustawienia metric.reporters i kafka.metrics.reporters to po prostu nazwy klas. Klasy te muszą zaimplementować — odpowiednio — interfejsy org.apache.kafka.common.metrics.MetricsReporter oraz kafka.metrics.KafkaMetricsReporter.

Wpadliśmy więc na pomysł: biblioteka o następujących cechach.

Natywny OTLP, bez przeskoku przez JMX

Większość stosów obserwowalności Kafki doczepia jmx_exporter lub coś podobnego jako agenta JVM, następnie zbiera MBeany przez endpoint HTTP i wypycha je do collectora.

Ta wtyczka żyje wewnątrz procesu Kafki i mówi do collectora bezpośrednio przez OTLP — o jeden proces mniej, o jedną powierzchnię konfiguracji mniej i żadnych YAML-i z regułami JMX do utrzymywania.

Jedna wtyczka, oba rejestry Kafki

Brokery Kafki udostępniają metryki przez dwa równoległe systemy: SPI Kafki, konfigurowane przez metric.reporters, oraz starszy rejestr Yammer/Coda Hale.

Kilka wewnętrznych sygnałów brokera — UnderReplicatedPartitions, OfflinePartitionsCount, ActiveControllerCount oraz metryki BrokerTopicMetrics per topic — rejestruje się wyłącznie w Yammer.

OtlpMetricReporter podłącza się do obu za pomocą jednej konfiguracji. Ten sam JAR działa bez zmian na klientach, gdzie strona Yammer wyłącza się automatycznie.

Odporny na awarie z założenia — Kafka nigdy nie jest blokowana

Wywołania zwrotne metryk, takie jak metricChange i metricRemoval, dotykają wyłącznie pamięciowej mapy ConcurrentHashMap. Całe I/O odbywa się na wątku demona harmonogramu (scheduler).

Jeśli collector jest nieosiągalny, wywołanie eksportu kończy się timeoutem, partia (batch) jest porzucana, a następny tik zaczyna się od nowa. Żadnej kolejki ponowień, żadnej nieograniczonej pamięci, żadnego wpływu na opóźnienie produce/fetch w Kafce.

Kontekst brokera staje się pełnoprawnymi etykietami Prometheusa

Kafka wywołuje MetricsReporter.contextChange(MetricsContext) z identyfikatorem klastra, identyfikatorem węzła/brokera oraz wersją Kafki.

Wtyczka przechwytuje te wartości i dołącza je jako atrybuty zasobu (resource attributes) OTLP. Pojawiają się one jako etykiety — kafka_cluster_id, kafka_node_id lub kafka_broker_id — na każdym szeregu czasowym (series), więc by(kafka_cluster_id, kafka_node_id) działa w PromQL bez żadnego dodatkowego okablowania.

Panie i panowie, oto monedula-metrics-reporter

monedula-metrics-reporter to biblioteka open source, która spełnia te wymagania — i więcej.

Eksportuje metryki Kafki bezpośrednio przez OTLP, używając gRPC lub HTTP, wspiera Kafkę 3.x i 4.x na Javie 17+ i potrafi też emitować metryki środowiska uruchomieniowego JVM tym samym potokiem.

Zawiera również praktyczne funkcje produkcyjne, takie jak:

  • listy dozwolonych metryk (allow-listing),
  • niestandardowe atrybuty zasobu,
  • konfiguracja TLS i mTLS,
  • kompresja,
  • metryki samomonitorowania reportera,
  • oraz wsparcie zarówno dla brokerów, jak i klientów.

Reporter emituje też własne metryki kondycji, na przykład:

  • monedula_reporter_export_success_total,
  • monedula_reporter_export_failure_total,
  • monedula_reporter_export_duration_ms.

Jeśli więc potok collectora się zepsuje, nie dostajesz po prostu ciszy. Dostajesz sygnały, że samemu reporterowi nie udaje się eksport.

Projekt dostarczany jest też z łatwym w użyciu przewodnikiem szybkiego startu, który demonstruje pełny przepływ z Kafką, OpenTelemetry Collector, Prometheusem i Grafaną. A ponieważ dashboardy są częścią problemu, zawiera wyselekcjonowany zestaw gotowych do użycia dashboardów Grafany pasujących do metryk produkowanych przez wtyczkę.

Znajdziesz go na GitHubie, możesz zbudować go lokalnie i przetestować z przewodnikiem szybkiego startu. Gotowe artefakty (prebuilt) pojawią się wkrótce.

Jeśli znajdziesz błąd lub masz sugestię ulepszenia, śmiało utwórz zgłoszenie (issue) na GitHubie.

Podsumowanie

Monitorowanie Kafki jest trudniejsze, niż powinno być, ponieważ Kafka udostępnia metryki przez dwa różne systemy metryk, większość konfiguracji produkcyjnych wciąż polega na JMX, a każde mapowanie JMX-do-Prometheusa tworzy kolejną warstwę zgodności między brokerem, Prometheusem i dashboardami Grafany.

monedula-metrics-reporter przyjmuje inne podejście: działa jako reporter metryk Kafki, eksportuje metryki natywnie przez OTLP, obsługuje oba rejestry metryk Kafki i dostarczany jest z dashboardami pasującymi do emitowanych metryk.

Czy więc metryki Kafki muszą być takie trudne?

Miejmy nadzieję, że już nie.