# JMX Exporter 规则示例（Kafka 3.x）
# 用法：
#   export KAFKA_OPTS="-javaagent:/opt/jmx_exporter/jmx_prometheus_javaagent.jar=7071:$(pwd)/jmx_exporter_config.yml"
#   bin/kafka-server-start.sh config/server.properties
# 然后访问 http://broker:7071/metrics 即可看到 Prometheus 文本格式

lowercaseOutputName: true
lowercaseOutputLabelNames: true

# 不要把所有 MBean 都暴露，只取关键的，体积才合理
whitelistObjectNames:
  - "kafka.server:type=BrokerTopicMetrics,*"
  - "kafka.server:type=ReplicaManager,*"
  - "kafka.server:type=ReplicaFetcherManager,*"
  - "kafka.server:type=KafkaRequestHandlerPool,*"
  - "kafka.network:type=SocketServer,*"
  - "kafka.network:type=RequestMetrics,*"
  - "kafka.controller:type=KafkaController,*"
  - "kafka.controller:type=ControllerStats,*"
  - "kafka.log:type=LogManager,*"
  - "kafka.log:type=LogCleanerManager,*"
  - "kafka.cluster:type=Partition,*"
  - "java.lang:type=GarbageCollector,name=*"
  - "java.lang:type=Memory"
  - "java.lang:type=OperatingSystem"

rules:
  # ========== Broker 健康 ==========
  - pattern: 'kafka.server<type=ReplicaManager, name=(.+)><>Value'
    name: kafka_server_replicamanager_$1
    type: GAUGE

  - pattern: 'kafka.controller<type=KafkaController, name=(.+)><>Value'
    name: kafka_controller_kafkacontroller_$1
    type: GAUGE

  - pattern: 'kafka.controller<type=ControllerStats, name=(.+)><>(Count|MeanRate|OneMinuteRate|FiveMinuteRate)'
    name: kafka_controller_controllerstats_$1_$2
    type: GAUGE

  # ========== 流量 ==========
  - pattern: 'kafka.server<type=BrokerTopicMetrics, name=(.+), topic=(.+)><>(Count|OneMinuteRate)'
    name: kafka_server_brokertopicmetrics_$1_$3
    type: GAUGE
    labels:
      topic: "$2"

  - pattern: 'kafka.server<type=BrokerTopicMetrics, name=(.+)><>(Count|OneMinuteRate)'
    name: kafka_server_brokertopicmetrics_$1_$2
    type: GAUGE

  # ========== 请求队列 / 处理 ==========
  - pattern: 'kafka.network<type=RequestMetrics, name=(.+), request=(.+)><>(Count|Mean|99thPercentile|999thPercentile)'
    name: kafka_network_requestmetrics_$1_$3
    type: GAUGE
    labels:
      request: "$2"

  - pattern: 'kafka.server<type=KafkaRequestHandlerPool, name=RequestHandlerAvgIdlePercent><>OneMinuteRate'
    name: kafka_server_kafkarequesthandlerpool_requesthandleravgidlepercent
    type: GAUGE

  - pattern: 'kafka.network<type=SocketServer, name=NetworkProcessorAvgIdlePercent><>Value'
    name: kafka_network_socketserver_networkprocessoravgidlepercent
    type: GAUGE

  # ========== 副本 / Fetcher ==========
  - pattern: 'kafka.server<type=ReplicaFetcherManager, name=MaxLag, clientId=(.+)><>Value'
    name: kafka_server_replicafetchermanager_maxlag
    type: GAUGE
    labels:
      client: "$1"

  - pattern: 'kafka.cluster<type=Partition, name=UnderReplicated, topic=(.+), partition=(.+)><>Value'
    name: kafka_cluster_partition_underreplicated
    type: GAUGE
    labels:
      topic: "$1"
      partition: "$2"

  # ========== 日志 / Compaction ==========
  - pattern: 'kafka.log<type=LogManager, name=LogDirectoryOffline, logDirectory=(.+)><>Value'
    name: kafka_log_logmanager_offline_logdir
    type: GAUGE
    labels:
      logdir: "$1"

  - pattern: 'kafka.log<type=Log, name=Size, topic=(.+), partition=(.+)><>Value'
    name: kafka_log_log_size
    type: GAUGE
    labels:
      topic: "$1"
      partition: "$2"

  # ========== JVM ==========
  - pattern: 'java.lang<type=Memory><HeapMemoryUsage>used'
    name: jvm_memory_heap_used_bytes
    type: GAUGE

  - pattern: 'java.lang<type=GarbageCollector, name=(.+)><>CollectionCount'
    name: jvm_gc_collection_count
    type: COUNTER
    labels:
      gc: "$1"

  - pattern: 'java.lang<type=GarbageCollector, name=(.+)><>CollectionTime'
    name: jvm_gc_collection_time_ms
    type: COUNTER
    labels:
      gc: "$1"

  - pattern: 'java.lang<type=OperatingSystem><>(SystemCpuLoad|ProcessCpuLoad|FreePhysicalMemorySize)'
    name: jvm_os_$1
    type: GAUGE
