Monitor RabbitMQ running in Kubernetes clusters using the OpenTelemetry Collector with automatic pod discovery. This guide walks you through deploying the collector via Helm with dynamic broker detection powered by the Kubernetes observer.
Dica
Running RabbitMQ on Linux hosts? See the self-hosted installation guide for virtual machine or bare metal deployments.
How the integration works
This Kubernetes-native deployment provides automatic discovery and monitoring:
Key components:
- Kubernetes observer: Continuously watches for RabbitMQ pods based on label selectors
- Receiver creator: Dynamically creates RabbitMQ receivers for each discovered pod
- Resource attribution: Automatically enriches metrics with Kubernetes metadata:
k8s.cluster.name- Your cluster identifierk8s.namespace.name- Pod namespacek8s.pod.name- Individual pod namerabbitmq.deployment.name- Derived from pod name
Deployment model: The collector runs as a Kubernetes deployment (single replica) with RBAC permissions to list and watch pods across namespaces. When new RabbitMQ pods are created or existing ones are removed, the observer automatically updates the collector's configuration.
Importante
The collector requires get, list, and watch permissions on pods to discover RabbitMQ instances automatically.
Installation steps
Follow these steps to deploy the OpenTelemetry Collector with RabbitMQ monitoring.
Before you begin
Ensure your environment meets these requirements:
Verify the management endpoint
Ensure RabbitMQ pods have the management plugin enabled:
$kubectl exec deploy/<your-rabbitmq-deployment> -n <rabbitmq-namespace> -- curl -I -u admin:password http://localhost:15672/api/overviewYou should see HTTP/1.1 200 OK in the response.
Create Helm values file
Create a file named otel-collector-values.yaml. This configuration uses the receiver_creator with k8s_observer to automatically discover RabbitMQ pods.
Update these placeholders:
my-rabbitmq-cluster: Your Kubernetes cluster namerabbitmq: The value of theapplabel for your RabbitMQ podsadmin/password: Your RabbitMQ credentials15672: The management API port
opentelemetry-collector: mode: deployment
image: repository: otel/opentelemetry-collector-contrib pullPolicy: IfNotPresent
command: name: otelcol-contrib
resources: limits: cpu: 500m memory: 300Mi requests: cpu: 100m memory: 100Mi
extraEnvs: - name: NEWRELIC_LICENSE_KEY valueFrom: secretKeyRef: name: newrelic-licenses key: NEWRELIC_LICENSE_KEY - name: NEWRELIC_OTLP_ENDPOINT valueFrom: secretKeyRef: name: newrelic-licenses key: NEWRELIC_OTLP_ENDPOINT - name: K8S_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: K8S_CLUSTER_NAME value: my-rabbitmq-cluster - name: RABBITMQ_USERNAME value: admin - name: RABBITMQ_PASSWORD value: password
clusterRole: create: true rules: - apiGroups: [""] resources: ["pods", "nodes", "nodes/stats", "nodes/proxy"] verbs: ["get", "list", "watch"] - apiGroups: ["apps"] resources: ["replicasets", "deployments", "statefulsets"] verbs: ["get", "list", "watch"]
clusterRoleBinding: name: ""
config: extensions: health_check: endpoint: 0.0.0.0:13133
k8s_observer: auth_type: serviceAccount observe_pods: true observe_nodes: false
receivers: receiver_creator/rabbitmq: watch_observers: [k8s_observer] receivers: rabbitmq: # Discover pods with label "app=rabbitmq" # Adjust the label selector to match your RabbitMQ pods rule: type == "pod" && labels["app"] == "rabbitmq" config: endpoint: 'http://`endpoint`:15672' username: ${env:RABBITMQ_USERNAME} password: ${env:RABBITMQ_PASSWORD} collection_interval: 30s metrics: # Queue Metrics (essential for message flow and backlog) rabbitmq.consumer.count: enabled: true rabbitmq.message.delivered: enabled: true rabbitmq.message.published: enabled: true rabbitmq.message.acknowledged: enabled: true rabbitmq.message.dropped: enabled: true rabbitmq.message.current: enabled: true # Crucial for monitoring queue backlog, includes 'ready' and 'unacknowledged' states
# Node Health Metrics (critical for server resource monitoring) rabbitmq.node.disk_free: enabled: true rabbitmq.node.disk_free_limit: enabled: true rabbitmq.node.disk_free_alarm: enabled: true rabbitmq.node.mem_used: enabled: true rabbitmq.node.mem_limit: enabled: true rabbitmq.node.mem_alarm: enabled: true rabbitmq.node.mem_used_details.rate: enabled: true rabbitmq.node.fd_used: enabled: true rabbitmq.node.fd_total: enabled: true rabbitmq.node.sockets_used: enabled: true rabbitmq.node.sockets_total: enabled: true rabbitmq.node.proc_used: enabled: true rabbitmq.node.proc_total: enabled: true rabbitmq.node.uptime: enabled: true rabbitmq.node.run_queue: enabled: true rabbitmq.node.processors: enabled: true rabbitmq.node.context_switches_details.rate: enabled: true rabbitmq.node.gc_num_details.rate: enabled: true rabbitmq.node.gc_bytes_reclaimed_details.rate: enabled: true
# I/O Metrics (important for understanding disk and network activity) rabbitmq.node.io_read_count_details.rate: enabled: true rabbitmq.node.io_read_bytes_details.rate: enabled: true rabbitmq.node.io_read_avg_time_details.rate: enabled: true rabbitmq.node.io_write_count_details.rate: enabled: true rabbitmq.node.io_write_bytes_details.rate: enabled: true rabbitmq.node.io_write_avg_time_details.rate: enabled: true rabbitmq.node.io_sync_count_details.rate: enabled: true rabbitmq.node.io_sync_avg_time_details.rate: enabled: true rabbitmq.node.io_seek_count_details.rate: enabled: true rabbitmq.node.io_seek_avg_time_details.rate: enabled: true rabbitmq.node.io_reopen_count_details.rate: enabled: true
# Mnesia and Store Metrics (for internal database and message storage) rabbitmq.node.mnesia_ram_tx_count_details.rate: enabled: true rabbitmq.node.mnesia_disk_tx_count_details.rate: enabled: true rabbitmq.node.msg_store_read_count_details.rate: enabled: true rabbitmq.node.msg_store_write_count_details.rate: enabled: true rabbitmq.node.queue_index_write_count_details.rate: enabled: true rabbitmq.node.queue_index_read_count_details.rate: enabled: true
# Connection/Channel/Queue Lifecycle Metrics rabbitmq.node.connection_created_details.rate: enabled: true rabbitmq.node.connection_closed_details.rate: enabled: true rabbitmq.node.channel_created_details.rate: enabled: true rabbitmq.node.channel_closed_details.rate: enabled: true rabbitmq.node.queue_declared_details.rate: enabled: true rabbitmq.node.queue_created_details.rate: enabled: true rabbitmq.node.queue_deleted_details.rate: enabled: true
resource_attributes: rabbitmq.server.endpoint: 'http://`endpoint`:15672' rabbitmq.port: '15672'
processors: batch: send_batch_size: 1024 timeout: 30s
resource/cluster: attributes: - key: k8s.cluster.name value: ${env:K8S_CLUSTER_NAME} action: upsert
transform/rabbitmq: metric_statements: - context: resource statements: # Create a display name combining Kubernetes metadata - set(attributes["rabbitmq.display.name"], Concat([ "server", "k8s", attributes["k8s.cluster.name"], attributes["k8s.namespace.name"], "pod", attributes["k8s.pod.name"], "rabbitmq", attributes["rabbitmq.port"] ], ":")) # Use pod name as deployment name - set(attributes["rabbitmq.deployment.name"], attributes["k8s.pod.name"])
exporters: otlphttp: endpoint: "${NEWRELIC_OTLP_ENDPOINT}" headers: api-key: "${NEWRELIC_LICENSE_KEY}" compression: gzip
service: extensions: [health_check, k8s_observer] pipelines: metrics/rabbitmq: receivers: [receiver_creator/rabbitmq] processors: [batch, resource/cluster, transform/rabbitmq] exporters: [otlphttp]Dica
Label selector customization:
If your RabbitMQ pods use different labels, update the rule line. For example:
- StatefulSet pods:
type == "pod" && labels["app.kubernetes.io/name"] == "rabbitmq" - Operator deployments:
type == "pod" && labels["app.kubernetes.io/component"] == "rabbitmq"
Run kubectl get pods --show-labels -n <namespace> to view your pod labels.
Create Kubernetes secret
Store your New Relic credentials in a Kubernetes secret.
Select the region that matches your New Relic account (check your browser URL when logged into New Relic):
$kubectl create secret generic newrelic-licenses \> --from-literal=NEWRELIC_LICENSE_KEY=YOUR_LICENSE_KEY \> --from-literal=NEWRELIC_OTLP_ENDPOINT=https://otlp.nr-data.net:4318 \> --namespace newrelicReplace YOUR_LICENSE_KEY with your New Relic license key.
$kubectl create secret generic newrelic-licenses \> --from-literal=NEWRELIC_LICENSE_KEY=YOUR_LICENSE_KEY \> --from-literal=NEWRELIC_OTLP_ENDPOINT=https://otlp.eu01.nr-data.net:4318 \> --namespace newrelicReplace YOUR_LICENSE_KEY with your New Relic license key.
Deploy with Helm
Add the OpenTelemetry Helm repository:
$helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts$helm repo updateInstall or upgrade the collector:
$helm upgrade --install rabbitmq-otel-collector \> open-telemetry/opentelemetry-collector \> --namespace newrelic \> --create-namespace \> --values otel-collector-values.yamlThis creates:
- A deployment named
rabbitmq-otel-collectorin thenewrelicnamespace - A Serviceaccount with RBAC permissions to watch pods
- ConfigMaps containing the collector configuration
Verify the deployment and data flow
Check that the collector pod is running:
$kubectl get pods -n newrelic -l app.kubernetes.io/name=opentelemetry-collectorExpected output:
NAME READY STATUS RESTARTS AGErabbitmq-otel-collector-6d8c5c5d8d-abc12 1/1 Running 0 2mView collector logs to verify pod discovery:
$kubectl logs deploy/rabbitmq-otel-collector -n newrelic --tail=50Look for messages indicating successful pod discovery and metric collection:
INFO k8sobserver/extension.go:150 Discovered pod {"kind": "pod", "name": "rabbitmq-0", "namespace": "default"}INFO RabbitmqReceiver Successfully scraped rabbitmq metrics from pod rabbitmq-0Verify your data in New Relic:
Wait 2-3 minutes for data to appear, then run this query in the query builder:
SELECT count(*)FROM MetricWHERE metricName LIKE 'rabbitmq.%' AND instrumentation.provider = 'opentelemetry' AND k8s.cluster.name = 'my-rabbitmq-cluster'FACET k8s.pod.name, metricNameSINCE 10 minutes agoYou should see metrics from each RabbitMQ pod with Kubernetes attributes:
k8s.cluster.name- Your cluster identifierk8s.namespace.name- Pod namespacek8s.pod.name- Individual pod namerabbitmq.deployment.name- Derived from pod name
Dica
If you don't see data after 5 minutes, check the troubleshooting section below.
Troubleshooting
What's next?
Now that you have RabbitMQ monitoring set up, you can enhance your observability:
Explore your data:
- Explore RabbitMQ metrics - Complete list of metrics with NRQL query examples
Enhance monitoring:
- Create alerts - Set up alerts for queue depths and pod health
- Build dashboards - Create custom dashboards to visualize your RabbitMQ metrics