• /
  • EnglishEspañolFrançais日本語한국어Português
  • Se connecterDémarrer

Cette traduction automatique est fournie pour votre commodité.

En cas d'incohérence entre la version anglaise et la version traduite, la version anglaise prévaudra. Veuillez visiter cette page pour plus d'informations.

Créer un problème

Monitorer Kafka sur Kubernetes (Strimzi) avec OpenTelemetry

Monitorez votre cluster Kafka fonctionnant sur Kubernetes avec l'opérateur Strimzi en déployant l'OpenTelemetry Collector. Le collecteur découvre automatiquement les pods de broker Kafka et collecte des métriques complètes.

Architecture

Le diagramme suivant illustre l'architecture de monitoring et le flux de données vers New Relic.

Kubernetes Strimzi Kafka monitoring architecture with OpenTelemetry

Étapes d'installation

Suivez ces étapes pour configurer la surveillance de votre cluster Kafka :

Avant de commencer

Assurez-vous d'avoir :

Configurer le cluster Kafka pour les métriques JMX Kafka

Configurez votre cluster Strimzi Kafka pour exposer les métriques JMX Kafka via le Prometheus JMX Exporter. Cette configuration sera déployée en tant que ConfigMap et référencée par votre cluster Kafka.

Step 1. Create JMX metrics ConfigMap

Créez une ConfigMap avec des patterns JMX Exporter qui définissent les métriques Kafka à collecter. Enregistrer sous 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"

Conseil

Personnaliser les métriques: cette ConfigMap inclut des métriques complètes sur les brokers Kafka, les topics, les requêtes, les contrôleurs et la JVM. Vous pouvez ajouter ou modifier des motifs en consultant les exemples Prometheus JMX Exporter et la documentation des MBeans Kafka. Consultez la documentation des règles de JMX Exporter pour des configurations supplémentaires.

Important

Exigence relative à l'espace de noms: La ConfigMap des métriques JMX et votre cluster Kafka doivent se trouver dans le même espace de noms. Dans ce guide, les deux sont déployés dans l'espace de noms newrelic.

Appliquer la ConfigMap :

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

Step 2. Update Kafka cluster to use JMX Exporter

Mettez à jour votre ressource Strimzi Kafka pour référencer la ConfigMap des métriques :

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

Appliquer les modifications. Strimzi effectuera un redémarrage progressif de vos brokers Kafka :

bash
$
kubectl apply -f kafka-cluster.yaml

Une fois le redémarrage progressif terminé, chaque broker Kafka exposera des métriques Prometheus sur le port 9404.

Déployer le Collecteur OpenTelemetry

Déployez le Collecteur OpenTelemetry pour monitorer votre cluster Kafka. Choisissez votre méthode d'installation préférée :

La méthode d'installation Helm est l'approche recommandée pour déployer OpenTelemetry Collector dans Kubernetes.

Step 1. Create New Relic credentials secret

Créez un secret Kubernetes contenant votre clé de licence New Relic et votre point de terminaison OTLP. Choisissez le point de terminaison pour votre région New Relic :

Conseil

Pour d'autres configurations de point de terminaison, consultez Configurer votre point de terminaison OTLP.

Step 2. Create values.yaml with collector configuration

Créez un fichier values.yaml contenant la configuration complète du collecteur OpenTelemetry. Les collecteurs NRDOT et OpenTelemetry utilisent une configuration identique et offrent les mêmes capacités du monitoring Kafka. Choisissez votre image de collecteur préférée :

Pour des options de configuration avancées, reportez-vous aux pages de documentation de ces récepteurs :

  • Documentation du récepteur Prometheus - Options de configuration supplémentaires du récepteur

  • Documentation du récepteur de métriques Kafka - Configuration de métriques Kafka supplémentaires

    Step 3. Install OpenTelemetry Collector with Helm

    Ajoutez le dépôt Helm et installez le collecteur OpenTelemetry à l'aide du fichier 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

    Vous devriez voir des logs indiquant un scraping réussi des brokers Kafka sur le port 9404.

La méthode d'installation par manifeste offre un contrôle direct sur les ressources Kubernetes sans utiliser Helm.

Step 1. Create New Relic credentials secret

Créez un secret Kubernetes contenant votre clé de licence New Relic et votre point de terminaison OTLP. Choisissez le point de terminaison pour votre région New Relic :

Conseil

Pour d'autres configurations de point de terminaison, consultez Configurer votre point de terminaison OTLP.

Step 2. Create manifest files

Créez les fichiers manifestes Kubernetes pour votre collecteur préféré. Les deux collecteurs utilisent une configuration identique - seule l'image diffère.

Choisissez votre option de collecteur et créez les trois fichiers requis :

Pour des options de configuration avancées, reportez-vous aux pages de documentation de ces récepteurs :

  • Documentation du récepteur Prometheus - Options de configuration supplémentaires du récepteur

  • Documentation du récepteur de métriques Kafka - Configuration de métriques Kafka supplémentaires

    Step 3. Deploy the manifests

    Appliquez les manifestes Kubernetes pour déployer le Collecteur OpenTelemetry :

    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

    Vous devriez voir des logs indiquant un scraping réussi des brokers Kafka sur le port 9404.

(Facultatif) Instrumenter les applications productrices ou consommatrices

Important

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.

Instrumentez votre application 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: {}

Paramètres de configuration

Le tableau suivant décrit les principaux paramètres de configuration :

paramètresDescription
service.nameRemplacez order-process-service par un nom unique pour votre application producteur ou consommateur
kafka.cluster.nameRemplacez my-cluster par le même nom de cluster utilisé dans la configuration de votre collecteur.
otlp.endpointLe point de terminaison http://localhost:4317 suppose que le collecteur s'exécute en tant que sidecar dans le même pod ou est accessible via localhost

Conseil

La configuration ci-dessus envoie la télémétrie à un Collecteur OpenTelemetry. Si vous devez envoyer des données de télémétrie au collecteur, déployez-le comme décrit à l'étape 3 avec cette configuration :

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

  • Latences des requêtes
  • Métriques de débit
  • Taux d'erreur
  • traces distribuées

Pour une configuration avancée, consultez la documentation d'instrumentation Kafka.

(Facultatif) Transmettre les logs du broker Kafka

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

Trouvez vos données

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:

SignalType d'événementCe qui est inclus
MétriquesMetricBroker, 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
TracesSpanProducer and consumer spans, including per-message publish and receive operations across topics

Métriques

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

Traces

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

Exemple

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.

Dépannage

Prochaines étapes

Droits d'auteur © 2026 New Relic Inc.

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