Metrics
Every series the broker exports on /metrics, with the JMX name it replaces.
The registry in crates/broker/src/metrics.rs is the source; this table is
derived from its doc comments and the registration help strings. When the two
disagree, the code wins, and the contract check fails
the build until this directory catches up.
Reading the table
- The broker serves
/metricson--metrics-listen-addr, which defaults to0.0.0.0:9404. That is the portjmx_prometheus_javaagentuses on a JVM Kafka broker, so an existing scrape config applies unchanged. - Every series carries the
krabka_broker_prefix. The table writes the exported sample name, which is what a PromQL expression spells. - Kafka’s
*PerSecmeters become monotonic counters. Compute a rate at query time withrate(<series>[5m]). The counter suffix_totalis what the encoder adds to the registered name. - A histogram exports
_bucket,_sumand_count. Read a quantile withhistogram_quantile(0.99, sum by (le, <label>) (rate(<series>_bucket[5m]))). - Replaces is the JMX MBean and attribute the series stands in for. A dash means Kafka has no counterpart.
- The
instancelabel is the scrape target’s, and every series carries it. The Labels column lists only the labels the broker adds.
A series is one per broker unless its labels say otherwise. Cardinality is
bounded by the metadata image or a closed enum in every family but one.
client_software_versions_total takes its software_name and
software_version labels from the client’s own ApiVersions request. The
broker checks only the character set, not the value, and ApiVersions is
allowed before authentication. Nothing caps or releases the series, so a client
can grow that family without bound. Drop or relabel it at the scrape if a
listener is open to peers you do not control.
Topics and partitions
| Series | Type | Labels | Replaces | Meaning |
|---|---|---|---|---|
krabka_ |
counter | topic |
Broker |
Bytes received from producers. |
krabka_ |
counter | topic |
Broker |
Bytes delivered to fetchers, consumers and followers both. |
krabka_ |
counter | topic |
Broker |
Records received from producers. Legacy v0 and v1 batches are not counted; produce_ tracks their arrival. |
krabka_ |
counter | topic |
Broker |
One increment per topic per Produce request. |
krabka_ |
counter | topic |
Broker |
One increment per topic per Fetch request. |
krabka_ |
counter | topic |
Broker |
Produce partition responses with a non-zero error code, one per failed partition. Alert on rate(.. |
krabka_ |
counter | topic |
Broker |
Fetch partition responses with a non-zero error code. |
krabka_ |
counter | topic |
Broker |
v0 or v1 to v2 up-conversions on the Produce path. |
krabka_ |
counter | topic |
Broker |
v2 to v0 or v1 down-conversions for a Fetch v < 4 client. |
krabka_ |
counter | topic, partition |
- | Bytes received from producers, per partition. |
krabka_ |
counter | topic, partition |
- | Bytes delivered to fetchers, consumers and followers both, per partition. Subtract replication_ for the consumer share. |
krabka_ |
gauge | topic, partition |
kafka. |
On-disk size of the partition’s log directory. Sampled every --partition-disk-scan-interval (default 60s); 0s disables the scanner and the series stops. |
krabka_ |
counter | topic, partition |
- | Handler-thread microseconds spent on the partition. rate(. is the core occupancy. |
krabka_ |
counter | - | kafka. (run accounting) |
Clean compaction sweeps, one per pass that failed no partition, whether or not a partition was eligible. A sweep that failed a partition is not counted here, so the pass rate never reports success during a compaction outage. |
krabka_ |
counter | topic, partition |
- | Compaction passes completed on the partition. |
krabka_ |
counter | topic, partition, reason |
- | Compaction passes that failed. reason is one of io (a storage failure, already reported to the log-dir registry), writer (the partition’s writer actor is gone) and other. Compaction and local retention stop together on a compacted topic, so alert on rate(.. Runbook. |
krabka_ |
gauge | - | kafka. |
Partitions this broker hosts whose most recent compaction attempt failed and which have not compacted since. The cleaner sweeps every hosted replica, leader or follower, as Kafka’s Log does, so a follower replica counts here too. Republished each sweep, so it falls when a pass succeeds, when this broker stops hosting the replica, or when the topic stops being compacted. Runbook. |
krabka_ |
counter | - | kafka. (cleanupLogs accounting) |
Clean local-retention sweeps, one per pass that failed no partition, whether or not any segment was evicted. The delete half of log maintenance: retention., retention. and segment., applied on log_ to every log this broker hosts, leader or follower. |
krabka_ |
counter | topic, partition, reason |
- | Local-retention passes that failed. reason is read exactly as it is on log_: io, writer, other. Nothing else reports this: a broker that never evicts a segment looks like one with nothing to evict until the disk fills, so alert on rate(.. |
krabka_ |
gauge | - | kafka. |
Log directories this broker has marked offline, by the startup writability probe or by a live write or fsync failure. Partitions on an offline dir answer KAFKA_ until the broker restarts. Alert on > 0. Runbook. |
Replication and partition state
| Series | Type | Labels | Replaces | Meaning |
|---|---|---|---|---|
krabka_ |
counter | topic, partition |
Broker |
Bytes this broker took from a leader as a follower. |
krabka_ |
counter | topic, partition |
Broker |
Bytes this broker served to followers as the leader. |
krabka_ |
gauge | - | Replica |
Partitions this broker leads. Sampled once a second. |
krabka_ |
gauge | - | Replica |
Partitions this broker hosts, leader and follower replicas both. |
krabka_ |
gauge | - | Replica |
Partitions this broker leads whose ISR is smaller than the replica set. Alert on > 0. Runbook. |
krabka_ |
gauge | - | Replica |
Partitions this broker leads whose ISR is below min.. They reject acks=all with NOT_. Alert on > 0. Runbook. |
krabka_ |
gauge | - | Replica |
Partitions with no live leader. Alert on > 0. Runbook. |
krabka_ |
gauge | topic, partition, replica |
Fetcher |
Records a follower of a partition this broker leads has yet to fetch: the leader’s log end offset minus the follower’s last-fetched offset. replica is the follower’s node id. Kafka reports this on the follower; krabka reports it on the leader, one series per follower. Where under_ says only that a follower left the ISR, this says how far behind it is while it is still in. Runbook. |
krabka_ |
counter | - | Leader |
KIP-73: replication bytes the leader-side throttle granted to a throttled follower. Flat at the configured rate during a reassignment means the throttle is biting; flat at zero with a reassignment in flight means something else is. |
krabka_ |
counter | - | Follower |
KIP-73: replication bytes the follower-side throttle granted for a throttled partition. |
krabka_ |
counter | - | - | KIP-73 rounds the throttle held back rather than merely capped: a follower fetch whose bucket had nothing left. krabka drops the partition from the round instead of delaying it, so there is no throttle_ to observe and this is the series that says the throttle refused. |
krabka_ |
gauge | - | Replica |
The largest value replica_ carries on this broker, or zero when it leads no partition with a follower. Alert on this series rather than on an aggregate of the per-follower family. Runbook. |
krabka_ |
counter | - | Replica |
ISR shrinks this broker’s maintenance loop proposed. |
krabka_ |
counter | - | Replica |
ISR expands this broker’s maintenance loop proposed. |
krabka_ |
gauge | - | - | Partitions this broker leads from a site other than the stretch cluster’s preferred leader site. Zero with no [stretch] section. Alert on > 0. Runbook. |
krabka_ |
gauge | - | - | 1 when the metadata image records broker. for this node. Confirms the role reached the controller. |
The lag families are sampled every 30 seconds, not incremented. The leader samples replica lag, and the group coordinator samples consumer-group lag. Each pass publishes the whole set of series it can justify and releases the rest, so a follower that left the replica set, or a partition this broker no longer leads, loses its series at the next pass. Shutdown clears the families. The metric comments name no threshold for any of them.
Controller
| Series | Type | Labels | Replaces | Meaning |
|---|---|---|---|---|
krabka_ |
gauge | - | Kafka |
1 on the raft leader, 0 elsewhere. |
krabka_ |
counter | - | Kafka |
Controller-leader transitions this broker observed. Alert on a sustained rate(.. Runbook. |
krabka_ |
counter | - | - | Completed broker-fencing publication passes on the controller leader, one per liveness tick. |
krabka_ |
counter | - | Controller |
KIP-841 unclean elections this controller drove. A KIP-966 recovery from an eligible leader replica is not counted. Alert on rate(.. Runbook. |
krabka_ |
gauge | - | raft-metrics,name=ignored-static-voters |
Static voters in the configuration that the quorum ignores at kraft. 1. |
krabka_ |
gauge | directory_ |
raft-metrics,name=current-vote-directory-id |
One-hot series for the directory identity voted for in this epoch. |
Requests
The api_key label is the ApiKey variant name: Produce, Fetch,
DescribeQuorum. A krabka-private RPC carries its own name. An unknown key
lands under Unknown.
| Series | Type | Labels | Replaces | Meaning |
|---|---|---|---|---|
krabka_ |
counter | api_ |
Request |
Requests the dispatcher handled. |
krabka_ |
counter | api_ |
- | Requests rejected because the version is outside the registered range. Alert on rate(.. Runbook. |
krabka_ |
counter | api_ |
Request |
Requests whose handler returned an error and the connection was closed. Disjoint from the unsupported-version series. Alert on rate(.. Runbook. |
krabka_ |
histogram | api_ |
Request |
Full handler round trip: decode, handle, encode. _ pairs with api_. Alert on a sustained p99. Runbook. |
krabka_ |
histogram | api_ |
Request |
Time on this broker’s own log: the Produce writer round trip summed over partitions, or the Fetch read of every planned partition. |
krabka_ |
histogram | api_ |
Request |
Time waiting on something other than the local log: the acks=all high-watermark gate, the Fetch long poll, and the object-store round trip of a KIP-405 tiered or diskless cold read. High here and low in the local phase is replication or the tier, not disk. |
krabka_ |
histogram | api_ |
Request |
Time asleep in the KIP-219 quota throttle or the inline KIP-599 mutation throttle. Observed once per request the broker accounts for, with an explicit zero when no quota applied. |
krabka_ |
histogram | quota_ |
kafka. |
Throttle the broker applied, under the quota that produced the largest delay. Unthrottled requests are not observed, so _ is the throttled request count. quota_ is Kafka’s own spelling. Alert on a sustained p99. Runbook. |
krabka_ |
gauge | - | Request (closest) |
Requests being handled now. A sustained climb is a handler stall or a wedged controller. Alert on a floor that stops falling. Runbook. |
krabka_ |
counter | path |
- | Drained Fetch responses by the path their records took to the socket. path is one of sendfile, pread, vectored. All three series exist from startup. On a plaintext cluster, rate(. is a zero-copy regression. Runbook. |
krabka_ |
gauge | - | - | 1 when the startup probe found working Linux kTLS, so TLS fetches drain through sendfile. 0 with no TLS listener and on every non-Linux target. Constant for the life of the process. |
The three phase families are disjoint and do not cover the total.
local + remote + throttle <= request_duration_seconds. The remainder is the
work no phase names: decode, authorization, record validation and response
encode. Compare the _sum streams; a remainder that grows is handler CPU. Do
not subtract _bucket streams: each family observes its own durations, so one
bucket of a phase says nothing about the same bucket of the total.
Connections and clients
| Series | Type | Labels | Replaces | Meaning |
|---|---|---|---|---|
krabka_ |
gauge | - | socket-server-metrics,name=connection-count |
Client connections open now. |
krabka_ |
counter | reason |
Selector,name=connection-close-total; expired-connections-killed-count for the idle arm |
Connections the broker closed on its own. reason is one of idle, sasl_, decode_, peer_. A connection dropped because of a request it did read is counted by that request’s family instead. Runbook. |
krabka_ |
counter | software_, software_ |
socket-server-metrics,client |
KIP-511 accepted v3+ Api handshakes. |
krabka_ |
counter | mechanism |
Selector,name=successful-authentication-total |
Sasl frames that reached an authenticated state. mechanism is the wire name: PLAIN, SCRAM-SHA-256, SCRAM-SHA-512, OAUTHBEARER, GSSAPI. Runbook. |
krabka_ |
counter | mechanism |
Selector,name=failed-authentication-total |
Sasl frames that returned an error. The mechanism label carries the same set, GSSAPI included. ILLEGAL_ rejects with no prior handshake land under Unknown. Alert on a sustained rate(.. Runbook. |
krabka_ |
gauge | - | Fetch |
KIP-227 live fetch sessions. |
krabka_ |
counter | - | Fetch |
Sessions evicted to make room. |
krabka_ |
gauge | - | Fetch |
Partitions held across every live session. |
krabka_ |
counter | - | - | KIP-714 client-metric batches dropped because the OTLP queue was full or closed. |
krabka_ |
counter | - | - | KIP-714 export attempts the collector rejected or the transport failed. |
Tiered storage
| Series | Type | Labels | Replaces | Meaning |
|---|---|---|---|---|
krabka_ |
gauge | - | - | KIP-405: 1 once the topic-backed Remote is in place, 0 on the fail-closed placeholder. Alert on min_ for a cluster that asked for it. Runbook. |
krabka_ |
counter | - | - | Bootstrap attempts. Climbs while stuck, flat once the gauge flips to 1. |
krabka_ |
counter | - | - | KFC-5: WORM manifests the archive sealed and returned a valid chain receipt for, one per segment copied into a write-once archive. Flat while a WORM cluster tiers means the chain has stopped growing. |
krabka_ |
counter | - | - | KFC-5: write-once segment copies that ended with no usable manifest – the copy failed, the task panicked, or the receipt was missing or did not match the requested chain position. Alert on rate(.. |
krabka_ |
counter | topic |
Broker |
Bytes of finished segment copies that reached the remote tier. |
krabka_ |
counter | topic |
Broker |
Bytes the remote tier served to a Fetch the local log could not answer. |
krabka_ |
counter | topic |
Broker |
Segment copies attempted, whatever their outcome. |
krabka_ |
counter | topic |
Broker |
Cold-tier reads attempted, whatever their outcome. |
krabka_ |
counter | topic |
Broker |
Remote segment deletions attempted, whatever their outcome. |
krabka_ |
counter | topic |
Broker |
Copies that did not finish. Alert on rate(.. Runbook. |
krabka_ |
counter | topic |
Broker |
Cold-tier reads the tier refused or failed. A consumer reading history sees these as OFFSET_. |
krabka_ |
counter | topic |
Broker |
Deletions that did not finish, including a metadata listing the pass could not read. |
krabka_ |
gauge | topic |
Broker |
Sealed local segments this broker has not finished copying. Climbing means the tier is not keeping up. Runbook. |
krabka_ |
gauge | topic |
Broker |
Total size of those segments; the local disk the tier is not yet relieving. |
krabka_ |
gauge | topic |
Broker |
Remote segments a retention pass has decided to remove and not yet removed. |
krabka_ |
gauge | topic |
Broker |
Total size of those segments; object-store space retention has not reclaimed. |
krabka_ |
gauge | - | Remote |
Cold-tier reads waiting for a slot in the bounded reader pool. |
krabka_ |
gauge | - | Remote |
Share of the reader pool’s slots that are free. Zero for long means every cold read is queueing. |
krabka_ |
histogram | - | Remote |
How long each cold read held its reader slot. |
krabka_ |
counter | - | - | Cold reads refused because the reader pool’s pending queue was full. The partition is answered with an error rather than queued behind the tier. |
krabka_ |
counter | - | - | Segment-index lookups served from <log. without a download. |
krabka_ |
counter | - | - | Segment-index lookups that downloaded the index object. A hit ratio near zero means the cache is too small for the working set. |
krabka_ |
counter | - | - | Cache entries dropped to stay inside remote_. |
krabka_ |
gauge | - | - | Bytes the index cache currently holds. |
krabka_ |
gauge | - | - | Entries the index cache currently holds. |
Diskless WAL
A krabka.diskless=true topic replicates its write-ahead log to a quorum of
WAL voters and flushes it to the object store. topic_id is the topic UUID,
so a delete and recreate cycle gets a new series. Kafka has no counterpart for
any of these.
| Series | Type | Labels | Replaces | Meaning |
|---|---|---|---|---|
krabka_ |
gauge | topic_, partition |
- | Quorum-durable offset of each shard this broker leads. |
krabka_ |
gauge | topic_, partition, voter |
- | Leader log end minus the voter’s durable offset. Runbook. |
krabka_ |
counter | - | - | Leader-side acknowledgements that could not form a quorum. Alert on rate(.. Runbook. |
krabka_ |
counter | - | - | Non-empty WAL objects submitted to the object store. |
krabka_ |
counter | - | - | Bytes written as WAL objects. |
krabka_ |
counter | - | - | Flushes that failed after an attempt began. Runbook. |
krabka_ |
counter | - | - | Index records rejected because the payload or format version is invalid. Refuse reads until replay is rebuilt. |
krabka_ |
gauge | topic_, partition |
- | Durable offsets the committed object index does not cover yet. |
krabka_ |
gauge | topic_, partition |
- | Local log-start offset after trimming. The gap to the durable watermark is the hot tail. |
krabka_ |
counter | - | - | Committed index ranges tombstoned by retention., retention., or a Delete floor. |
krabka_ |
counter | - | - | Cold reads served from the object store. |
krabka_ |
counter | - | - | Cold reads with no matching committed index entry. |
krabka_ |
counter | - | - | Cold reads that failed in the object store. Runbook. |
Coordinators
| Series | Type | Labels | Replaces | Meaning |
|---|---|---|---|---|
krabka_ |
gauge | group_, topic, partition |
- | Records a consumer group this broker coordinates has yet to consume from one partition: the high watermark minus the group’s committed offset. Classic and KIP-848 groups both report. JVM Kafka does not export this from the broker; it is the LAG column kafka-consumer-groups --describe computes on the client. A series exists only for a partition the group committed an offset for, and is released when the group is deleted, moves coordinator, or the topic is deleted. Runbook. |
krabka_ |
gauge | group_, topic, partition |
- | KIP-932 records waiting for acquisition in the share-group partition. |
krabka_ |
counter | group_ |
Share |
KIP-1191 dead-letter records this broker wrote to the group’s dead-letter queue. Only a group that sets errors., at share. 2, has a series. It is released when Delete deletes the group on the broker that coordinates it. A broker that only leads the group’s share partitions keeps its series until it restarts, as Kafka keeps its meters until the broker closes, and a broker that stops coordinating the group keeps them too. |
krabka_ |
counter | group_ |
Share |
Attempts to produce the group’s dead-letter records: one for each round of each write for each attempt, counted when a request takes the round, as Kafka counts it, not one for each coalesced produce request. |
krabka_ |
counter | group_ |
Share |
Dead-letter writes of the group that failed for good: a produce that a broker refused, or that ran out of its five attempts. The record is archived regardless. Alert on rate(.. |
krabka_ |
counter | group |
- | Barrier epochs the coordinator started. |
krabka_ |
counter | group |
- | Epochs whose marker reached every partition of the group. |
krabka_ |
counter | group |
- | Epochs whose cut names a partition that got no marker. Alert on rate(.. Runbook. |
krabka_ |
histogram | group |
- | Seconds from the injection-start record to the published cut. Graph the p99 against barrier_. |
krabka_ |
gauge | group |
- | Epoch of the newest published cut. Flat beside a live injection interval means injection stopped. |
krabka_ |
counter | topic |
- | Barrier markers this broker appended. Markers survive compaction. |
krabka_ |
gauge | - | - | Barrier groups this broker coordinates. |
krabka_ |
gauge | topic, partition |
- | KFC-1 first offset not yet visible on a delivery. partition. Only scheduled partitions report. |
krabka_ |
gauge | topic, partition |
- | KFC-1 records durable but not visible: log end minus the watermark. |
krabka_ |
histogram | - | - | KFC-1 seconds past a batch’s activation deadline before it became visible. A healthy broker reports zero. A rising tail says the bound is not honest, or that the scheduler is starved of CPU. Runbook. |
krabka_ |
counter | - | - | KFC-1 scheduler wakeups. Separates “never ran” from “ran late”. |
krabka_ |
gauge | - | - | KFC-8 clock bound the broker declares and adds before a batch activates. Compare a measured clock error against it. |
Policies and audit
| Series | Type | Labels | Replaces | Meaning |
|---|---|---|---|---|
krabka_ |
counter | topic, reason |
- | KFC-7 records rejected, one per record. reason is one of unframed, unknown_, wrong_, body_, registry_. Alert on rate(.: with the default fail_ those produces are refused. Runbook. |
krabka_ |
counter | - | - | KFC-7 schema lookups answered from the local cache. |
krabka_ |
counter | - | - | KFC-7 lookups that cost a registry round trip. |
krabka_ |
counter | topic |
- | KFC-9 Produce partition rows refused by a write freeze, before the batch is parsed. |
krabka_ |
gauge | - | - | KFC-9 live freeze registry entries. One prefix entry covers a namespace. |
krabka_ |
gauge | state |
- | KFC-9 proposals by state: pending, approved, expired, consumed. |
krabka_ |
counter | action |
- | KFC-9 privileged transitions refused for want of an approved proposal. A steady rate is normal. |
krabka_ |
counter | action |
- | KFC-9 privileged transitions that ran without an approved proposal. Alert on rate(.. Runbook. |
krabka_ |
counter | operation, resource_ |
the Principal . line on the kafka. log4j logger; Kafka exports no metric |
Authorization decisions that came back Deny. Both labels are the Acl / Resource spelling, so cardinality is bounded. Counted whether or not audit is enabled, so it is the denial signal a cluster with audit. still has. Alert on rate(. sustained. Runbook. |
krabka_ |
counter | - | - | Audit records written to _. |
krabka_ |
counter | - | - | Audit records that failed to write. Alert on rate(.. Runbook. |
krabka_ |
gauge | - | - | Audit records buffered in the durable spool. |
krabka_ |
gauge | - | - | Bytes buffered in the durable spool. |
krabka_ |
counter | - | - | Records diverted to the spool on a write failure. |
krabka_ |
counter | - | - | Records drained from the spool back to the topic. |
krabka_ |
counter | - | - | Records lost because the channel or the spool was full. Alert on rate(.. |
The action label on the break-glass families is one of thaw_topic_freeze,
unclean_elect_leaders, unclean_recovery, unregister_broker,
cancel_reassignment, delete_topic and delete_records.
The contract check
grafana-dashboard.json and
alert-rules.yaml name only series in this table. Two
checks enforce that:
crates/broker/tests/metrics_contract.rsbuilds the registry, gives every family one label set, encodes the body the way/metricsdoes, and checks everykrabka_broker_*token in the two files against it. It also checks thatmetrics-body.txtequals that body, so the checked-in copy cannot go stale.bazel test //crates/broker:metrics_contract_testruns it.aspect check-metrics-contractdoes the same name check in the CI docs job, which has no Rust toolchain, against the checked-in copy.
When a family is added or renamed, run the suite with
KRABKA_METRICS_BODY_OUT=docs/operations/metrics-body.txt to regenerate the
copy, then update this table and the two files.