• /
  • EnglishEspañolFrançais日本語한국어Português
  • Inicia sesiónComenzar ahora

Te ofrecemos esta traducción automática para facilitar la lectura.

En caso de que haya discrepancias entre la versión en inglés y la versión traducida, se entiende que prevalece la versión en inglés. Visita esta página para obtener más información.

Crea una propuesta

Monitorear Kafka en Kubernetes (Strimzi) con OpenTelemetry

Monitorea tu clúster de Kafka que se ejecuta en Kubernetes con el operador Strimzi implementando el recopilador de OpenTelemetry. El recopilador descubre automáticamente los pods del broker de Kafka y recopila métricas completas.

Arquitectura

El siguiente diagrama ilustra la arquitectura de monitoreo y el flujo de datos hacia New Relic.

Kubernetes Strimzi Kafka monitoring architecture with OpenTelemetry

Pasos de instalación

Siga estos pasos para configurar el monitoreo de su clúster de Kafka:

Antes de que empieces

Asegúrese de tener:

Configurar el clúster de Kafka para las métricas JMX de Kafka

Configure su clúster Strimzi Kafka para exponer las métricas JMX de Kafka mediante el Prometheus JMX Exporter. Esta configuración se desplegará como un ConfigMap y será referenciada por su clúster de Kafka.

Step 1. Create JMX metrics ConfigMap

Cree un ConfigMap con patrones de JMX Exporter que definan qué métricas de Kafka recolectar. Guardar como kafka-jmx-config.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
name: kafka-jmx-metrics
namespace: newrelic
data:
kafka-metrics-config.yml: |
startDelaySeconds: 0
lowercaseOutputName: true
lowercaseOutputLabelNames: true
rules:
# Cluster-level controller metrics
- pattern: 'kafka.controller<type=KafkaController, name=GlobalTopicCount><>Value'
name: kafka_cluster_topic_count
type: GAUGE
- pattern: 'kafka.controller<type=KafkaController, name=GlobalPartitionCount><>Value'
name: kafka_cluster_partition_count
type: GAUGE
- pattern: 'kafka.controller<type=KafkaController, name=FencedBrokerCount><>Value'
name: kafka_broker_fenced_count
type: GAUGE
- pattern: 'kafka.controller<type=KafkaController, name=PreferredReplicaImbalanceCount><>Value'
name: kafka_partition_non_preferred_leader
type: GAUGE
- pattern: 'kafka.controller<type=KafkaController, name=OfflinePartitionsCount><>Value'
name: kafka_partition_offline
type: GAUGE
- pattern: 'kafka.controller<type=KafkaController, name=ActiveControllerCount><>Value'
name: kafka_controller_active_count
type: GAUGE
# Broker-level replica metrics
- pattern: 'kafka.server<type=ReplicaManager, name=UnderMinIsrPartitionCount><>Value'
name: kafka_partition_under_min_isr
type: GAUGE
- pattern: 'kafka.server<type=ReplicaManager, name=LeaderCount><>Value'
name: kafka_broker_leader_count
type: GAUGE
- pattern: 'kafka.server<type=ReplicaManager, name=PartitionCount><>Value'
name: kafka_partition_count
type: GAUGE
- pattern: 'kafka.server<type=ReplicaManager, name=UnderReplicatedPartitions><>Value'
name: kafka_partition_under_replicated
type: GAUGE
- pattern: 'kafka.server<type=ReplicaManager, name=IsrShrinksPerSec><>Count'
name: kafka_isr_operation_count
type: COUNTER
labels:
operation: "shrink"
- pattern: 'kafka.server<type=ReplicaManager, name=IsrExpandsPerSec><>Count'
name: kafka_isr_operation_count
type: COUNTER
labels:
operation: "expand"
- pattern: 'kafka.server<type=ReplicaFetcherManager, name=MaxLag, clientId=Replica><>Value'
name: kafka_max_lag
type: GAUGE
# Broker topic metrics (totals)
- pattern: 'kafka.server<type=BrokerTopicMetrics, name=MessagesInPerSec><>Count'
name: kafka_message_count
type: COUNTER
- pattern: 'kafka.server<type=BrokerTopicMetrics, name=TotalFetchRequestsPerSec><>Count'
name: kafka_request_count
type: COUNTER
labels:
type: "fetch"
- pattern: 'kafka.server<type=BrokerTopicMetrics, name=TotalProduceRequestsPerSec><>Count'
name: kafka_request_count
type: COUNTER
labels:
type: "produce"
- pattern: 'kafka.server<type=BrokerTopicMetrics, name=FailedFetchRequestsPerSec><>Count'
name: kafka_request_failed
type: COUNTER
labels:
type: "fetch"
- pattern: 'kafka.server<type=BrokerTopicMetrics, name=FailedProduceRequestsPerSec><>Count'
name: kafka_request_failed
type: COUNTER
labels:
type: "produce"
- pattern: 'kafka.server<type=BrokerTopicMetrics, name=BytesInPerSec><>Count'
name: kafka_network_io
type: COUNTER
labels:
direction: "in"
- pattern: 'kafka.server<type=BrokerTopicMetrics, name=BytesOutPerSec><>Count'
name: kafka_network_io
type: COUNTER
labels:
direction: "out"
# Per-topic metrics (only appear after traffic flows)
- pattern: 'kafka.server<type=BrokerTopicMetrics, name=MessagesInPerSec, topic=(.+)><>Count'
name: kafka_prod_msg_count
type: COUNTER
labels:
topic: "$1"
- pattern: 'kafka.server<type=BrokerTopicMetrics, name=BytesInPerSec, topic=(.+)><>Count'
name: kafka_topic_io
type: COUNTER
labels:
topic: "$1"
direction: "in"
- pattern: 'kafka.server<type=BrokerTopicMetrics, name=BytesOutPerSec, topic=(.+)><>Count'
name: kafka_topic_io
type: COUNTER
labels:
topic: "$1"
direction: "out"
# Request metrics
- pattern: 'kafka.network<type=RequestMetrics, name=TotalTimeMs, request=(Produce|FetchConsumer|FetchFollower)><>99thPercentile'
name: kafka_request_time_99p
type: GAUGE
labels:
type: "$1"
- pattern: 'kafka.network<type=RequestChannel, name=RequestQueueSize><>Value'
name: kafka_request_queue
type: GAUGE
- pattern: 'kafka.server<type=DelayedOperationPurgatory, name=PurgatorySize, delayedOperation=(.+)><>Value'
name: kafka_purgatory_size
type: GAUGE
labels:
type: "$1"
# Controller stats
- pattern: 'kafka.controller<type=ControllerStats, name=LeaderElectionRateAndTimeMs><>Count'
name: kafka_leader_election_rate
type: COUNTER
- pattern: 'kafka.controller<type=ControllerStats, name=UncleanLeaderElectionsPerSec><>Count'
name: kafka_unclean_election_rate
type: COUNTER
# JVM Garbage Collection
- pattern: 'java.lang<name=(.+), type=GarbageCollector><>CollectionCount'
name: jvm_gc_collections_count
type: COUNTER
labels:
name: "$1"
# JVM Memory
- pattern: 'java.lang<type=Memory><HeapMemoryUsage>max'
name: jvm_memory_heap_max
type: GAUGE
- pattern: 'java.lang<type=Memory><HeapMemoryUsage>used'
name: jvm_memory_heap_used
type: GAUGE
# JVM Threading and System
- pattern: 'java.lang<type=Threading><>ThreadCount'
name: jvm_thread_count
type: GAUGE
- pattern: 'java.lang<type=OperatingSystem><>SystemCpuLoad'
name: jvm_system_cpu_utilization
type: GAUGE
# Broker uptime
- pattern: 'java.lang<type=Runtime><>Uptime'
name: kafka_broker_uptime
type: GAUGE
# Additional metrics — remove this section to reduce data ingest
# Request latency: total count, 50th percentile, and average (99p kept above)
- pattern: 'kafka.network<type=RequestMetrics, name=TotalTimeMs, request=(Produce|FetchConsumer|FetchFollower)><>Count'
name: kafka_request_time_total
type: COUNTER
labels:
type: "$1"
- pattern: 'kafka.network<type=RequestMetrics, name=TotalTimeMs, request=(Produce|FetchConsumer|FetchFollower)><>50thPercentile'
name: kafka_request_time_50p
type: GAUGE
labels:
type: "$1"
- pattern: 'kafka.network<type=RequestMetrics, name=TotalTimeMs, request=(Produce|FetchConsumer|FetchFollower)><>Mean'
name: kafka_request_time_avg
type: GAUGE
labels:
type: "$1"
# Log flush metrics
- pattern: 'kafka.log<type=LogFlushStats, name=LogFlushRateAndTimeMs><>Count'
name: kafka_logs_flush_count
type: COUNTER
- pattern: 'kafka.log<type=LogFlushStats, name=LogFlushRateAndTimeMs><>50thPercentile'
name: kafka_logs_flush_time_50p
type: GAUGE
- pattern: 'kafka.log<type=LogFlushStats, name=LogFlushRateAndTimeMs><>99thPercentile'
name: kafka_logs_flush_time_99p
type: GAUGE
# JVM GC elapsed time
- pattern: 'java.lang<name=(.+), type=GarbageCollector><>CollectionTime'
name: jvm_gc_collections_elapsed
type: COUNTER
labels:
name: "$1"
# JVM Memory heap committed
- pattern: 'java.lang<type=Memory><HeapMemoryUsage>committed'
name: jvm_memory_heap_committed
type: GAUGE
# JVM class loading
- pattern: 'java.lang<type=ClassLoading><>LoadedClassCount'
name: jvm_class_count
type: GAUGE
# Additional JVM OS metrics
- pattern: 'java.lang<type=OperatingSystem><>SystemLoadAverage'
name: jvm_system_cpu_load_1m
type: GAUGE
- pattern: 'java.lang<type=OperatingSystem><>AvailableProcessors'
name: jvm_cpu_count
type: GAUGE
- pattern: 'java.lang<type=OperatingSystem><>ProcessCpuLoad'
name: jvm_cpu_recent_utilization
type: GAUGE
- pattern: 'java.lang<type=OperatingSystem><>OpenFileDescriptorCount'
name: jvm_file_descriptor_count
type: GAUGE
# JVM Memory Pool
- pattern: 'java.lang<type=MemoryPool, name=(.+)><Usage>used'
name: jvm_memory_pool_used
type: GAUGE
labels:
name: "$1"
- pattern: 'java.lang<type=MemoryPool, name=(.+)><Usage>max'
name: jvm_memory_pool_max
type: GAUGE
labels:
name: "$1"
- pattern: 'java.lang<type=MemoryPool, name=(.+)><CollectionUsage>used'
name: jvm_memory_pool_used_after_last_gc
type: GAUGE
labels:
name: "$1"

Sugerencia

Personalizar métricas: Este ConfigMap incluye métricas completas de brokers, temas, solicitudes, controladores y JVM de Kafka. Puede agregar o modificar patrones consultando los ejemplos de Prometheus JMX Exporter y la documentación de Kafka MBean. Consulte la documentación de reglas de JMX Exporter para configuraciones adicionales.

Importante

Requisito de espacio de nombres: El ConfigMap de métricas JMX y su clúster de Kafka deben estar en el mismo espacio de nombres. En esta guía, ambos se despliegan en el espacio de nombres newrelic.

Aplique el ConfigMap:

bash
$
kubectl apply -f kafka-jmx-config.yaml

Step 2. Update Kafka cluster to use JMX Exporter

Actualice su recurso Strimzi Kafka para hacer referencia al ConfigMap de métricas:

apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
name: my-cluster
namespace: newrelic
spec:
kafka:
version: X.X.X
metricsConfig:
type: jmxPrometheusExporter
valueFrom:
configMapKeyRef:
name: kafka-jmx-metrics
key: kafka-metrics-config.yml
# ...rest of your Kafka configuration

Aplicar los cambios. Strimzi realizará un reinicio escalonado de sus brokers de Kafka:

bash
$
kubectl apply -f kafka-cluster.yaml

Después de que se complete el reinicio gradual, cada broker de Kafka expondrá métricas de Prometheus en el puerto 9404.

Desplegar OpenTelemetry Collector

Despliegue el OpenTelemetry Collector para monitorear su clúster de Kafka. Seleccione su método de instalación preferido:

El método de instalación con Helm es el enfoque recomendado para desplegar OpenTelemetry Collector en Kubernetes.

Step 1. Create New Relic credentials secret

Crea un secreto de Kubernetes que contenga tu clave de licencia de New Relic y el endpoint OTLP. Selecciona el endpoint para tu región de New Relic:

Sugerencia

Para otras configuraciones de endpoints, consulte Configure su endpoint OTLP.

Step 2. Create values.yaml with collector configuration

Cree un archivo values.yaml que contenga la configuración completa del OpenTelemetry Collector. Tanto los recopiladores NRDOT como los de OpenTelemetry utilizan una configuración idéntica y proporcionan las mismas capacidades de monitoreo de Kafka. Seleccione su imagen de colector preferida:

Para opciones de configuración avanzadas, consulte estas páginas de documentación del receptor:

  • Documentación del receptor Prometheus - Opciones adicionales de configuración del receptor

  • Documentación del receptor de métricas de Kafka - Configuración adicional de métricas de Kafka

    Step 3. Install OpenTelemetry Collector with Helm

    Agregue el repositorio de Helm e instale el OpenTelemetry Collector utilizando el archivo values.yaml:

    bash
    $
    helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
    $
    helm upgrade kafka-monitoring open-telemetry/opentelemetry-collector \
    >
    --install \
    >
    --namespace newrelic \
    >
    --create-namespace \
    >
    -f values.yaml

    Step 4. Verify the deployment:

    bash
    $
    # Check pod status
    $
    kubectl get pods -n newrelic -l app.kubernetes.io/name=opentelemetry-collector
    $
    $
    # View logs to verify metrics collection
    $
    kubectl logs -n newrelic -l app.kubernetes.io/name=opentelemetry-collector --tail=50

    Debería ver logs que indiquen un scraping exitoso de los brokers de Kafka en el puerto 9404.

El método de instalación de manifiesto proporciona control directo sobre los recursos de Kubernetes sin usar Helm.

Step 1. Create New Relic credentials secret

Crea un secreto de Kubernetes que contenga tu clave de licencia de New Relic y el endpoint OTLP. Selecciona el endpoint para tu región de New Relic:

Sugerencia

Para otras configuraciones de endpoints, consulte Configure su endpoint OTLP.

Step 2. Create manifest files

Cree los archivos de manifiesto de Kubernetes para su recopilador preferido. Ambos colectores usan una configuración idéntica; solo la imagen difiere.

Elija su opción de colector y cree los tres archivos requeridos:

Para opciones de configuración avanzadas, consulte estas páginas de documentación del receptor:

  • Documentación del receptor Prometheus - Opciones adicionales de configuración del receptor

  • Documentación del receptor de métricas de Kafka - Configuración adicional de métricas de Kafka

    Step 3. Deploy the manifests

    Aplique los manifiestos de Kubernetes para desplegar el OpenTelemetry Collector:

    bash
    $
    # Create namespace if it doesn't exist
    $
    kubectl create namespace newrelic --dry-run=client -o yaml | kubectl apply -f -
    $
    $
    # Apply RBAC configuration
    $
    kubectl apply -f collector-rbac.yaml
    $
    $
    # Apply ConfigMap
    $
    kubectl apply -f collector-configmap.yaml
    $
    $
    # Apply Deployment
    $
    kubectl apply -f collector-deployment.yaml

    Step 4. Verify the deployment:

    bash
    $
    # Check pod status
    $
    kubectl get pods -n newrelic -l app=otel-collector
    $
    $
    # View logs to verify metrics collection
    $
    kubectl logs -n newrelic -l app=otel-collector --tail=50

    Debería ver logs que indiquen un scraping exitoso de los brokers de Kafka en el puerto 9404.

(Opcional) Instrumentar aplicaciones productoras o consumidoras

Importante

Language support: Java applications support out-of-the-box Kafka client instrumentation using the OpenTelemetry Java agent.

To collect application-level telemetry from your Kafka producer and consumer applications, use the OpenTelemetry Java agent.

Instrumente su aplicación Kafka

Use an init container to download the OpenTelemetry Java agent at runtime:

apiVersion: apps/v1
kind: Deployment
metadata:
name: kafka-producer-app
spec:
template:
spec:
initContainers:
- name: download-java-agent
image: busybox:latest
command:
- sh
- -c
- |
wget -O /otel-auto-instrumentation/opentelemetry-javaagent.jar \
https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
volumeMounts:
- name: otel-auto-instrumentation
mountPath: /otel-auto-instrumentation
containers:
- name: app
image: your-kafka-app:latest
env:
- name: JAVA_TOOL_OPTIONS
value: >-
-javaagent:/otel-auto-instrumentation/opentelemetry-javaagent.jar
-Dotel.service.name=order-process-service
-Dotel.resource.attributes=kafka.cluster.name=my-cluster
-Dotel.exporter.otlp.endpoint=http://localhost:4317
-Dotel.exporter.otlp.protocol=grpc
-Dotel.metrics.exporter=otlp
-Dotel.traces.exporter=otlp
-Dotel.logs.exporter=otlp
-Dotel.instrumentation.kafka.experimental-span-attributes=true
-Dotel.instrumentation.messaging.experimental.receive-telemetry.enabled=true
-Dotel.instrumentation.kafka.producer-propagation.enabled=true
-Dotel.instrumentation.kafka.enabled=true
volumeMounts:
- name: otel-auto-instrumentation
mountPath: /otel-auto-instrumentation
volumes:
- name: otel-auto-instrumentation
emptyDir: {}

Parámetro de configuración

La siguiente tabla describe los parámetros de configuración clave:

ParámetroDescripción
service.nameReemplace order-process-service con un nombre único para su aplicación productora o consumidora
kafka.cluster.nameReemplace my-cluster con el mismo nombre de clúster utilizado en la configuración de su colector
otlp.endpointEl endpoint http://localhost:4317 asume que el colector se ejecuta como un sidecar en el mismo pod o que es accesible a través de localhost

Sugerencia

La configuración anterior envía telemetría a un OpenTelemetry Collector. Si necesita enviar telemetría al colector, impleméntelo como se describe en el Paso 3 con esta configuración:

The Java agent provides out-of-the-box Kafka instrumentation with zero code changes, capturing:

  • Latencias de solicitud
  • Métricas de rendimiento
  • Tasas de error
  • Rastreo distribuido

Para una configuración avanzada, consulte la documentación de instrumentación de Kafka.

(Opcional) Enviar logs del broker de Kafka

To collect Kafka broker logs and send them to New Relic, add a filelog receiver to your collector configuration.

Encuentra tus datos

After a few minutes, your Kafka data should appear in New Relic. See Find your data for detailed instructions on exploring your Kafka data across different views in the New Relic UI.

The following table summarizes where each signal type is stored. Replace my-kafka-cluster with your KAFKA_CLUSTER_NAME value in all queries below:

SignalTipo de eventoQué incluye
MétricaMetricBroker, topic, partition, consumer group, and JVM metrics
LogsLogLogs from producer and consumer applications (via OTel Java agent) and broker logs collected via the optional log forwarding step
TrazaSpanProducer and consumer spans, including per-message publish and receive operations across topics

Métrica

Broker, topic, partition, consumer group, and JVM metrics are stored in the Metric event type. Replace my-kafka-cluster with your KAFKA_CLUSTER_NAME value:

FROM Metric SELECT * WHERE kafka.cluster.name = 'my-kafka-cluster' SINCE 30 minutes ago

Logs

Logs from producer and consumer applications instrumented with the OpenTelemetry Java agent, and broker logs collected via the optional log forwarding step, are stored in the Log event type:

FROM Log SELECT * WHERE kafka.cluster.name = 'my-kafka-cluster' SINCE 30 minutes ago

Traza

If you deploy producer or consumer applications instrumented with the OpenTelemetry Java agent, producer and consumer spans are stored in the Span event type:

FROM Span SELECT * WHERE kafka.cluster.name = 'my-kafka-cluster' SINCE 30 minutes ago

Ejemplo

A complete working example with Strimzi Kafka custom resources, JMX Exporter configuration, OTel Collector setup, and sample producer/consumer applications is available in the New Relic OpenTelemetry Examples repository.

Resolución de problemas

Próximos pasos

Copyright © 2026 New Relic Inc.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.