---
title: "monedula-metrics-reporter"
repo: https://github.com/monedula-dev/monedula-metrics-reporter
language: Java
license: AGPL-3.0
status: active
maintainers: ["grzegorz", "michal"]
---## Why

The usual path for Kafka observability is a JMX exporter sidecar — an extra
process per broker, with its own scrape window, its own failure modes, and a
metric model that doesn't quite match what the rest of the stack speaks.

`monedula-metrics-reporter` removes the sidecar. It plugs into Kafka's own
`MetricsReporter` interface and pushes metrics directly to an OpenTelemetry
collector over OTLP — gRPC or HTTP, your call. Broker context (cluster id,
node id) is attached as resource attributes, so the same metric stream works
across brokers without per-host wiring.

All export I/O happens on a daemon thread. If the collector is slow or down,
nothing reaches the threads Kafka uses to serve traffic.

For the full background — the two metric systems hiding inside Kafka, why
imported Grafana dashboards so often show *No Data*, and how native OTLP
untangles it — read [Do Kafka metrics have to be so difficult?](/blog/kafka-metrics-opentelemetry-otlp-monedula-metrics-reporter/).

## Configure

Drop the shadow jar into `$KAFKA_HOME/libs/`, then in `server.properties`:

```properties
metric.reporters=dev.monedula.metricsreporter.OtlpMetricReporter
otlp.metric.reporter.endpoint=http://otel-collector:4317
otlp.metric.reporter.transport=grpc
```

The same plugin works on Kafka clients — register it via
`metric.reporters` on the producer or consumer config and you get the
matching client-side stream into the same collector.

A complete demo stack (broker + collector + Prometheus + Grafana) lives
under `quickstart/` in the repo.

## Compatibility

Kafka 3.x and 4.x. Java 17+. Both the modern `MetricsReporter` SPI and the
legacy Yammer registry are wired, so you get coverage of the metrics Kafka
emits today without leaving the Yammer ones on the table.