diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 55c9053daec0..2f4048839671 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -119,6 +119,7 @@ https://github.com/elastic/beats/compare/v6.0.0-beta2...master[Check the HEAD di - Fix system process metricset for kernel processes. {issue}5700[5700] - Fix panic in http dependent modules when invalid config was used. - Fix system.filesystem.used.pct value to match what df reports. {issue}5494[5494] +- Fix namespace disambiguation in Kubernetes state_* metricsets. {issue}6281[6281] *Packetbeat* diff --git a/metricbeat/module/kubernetes/_meta/test/kube-state-metrics b/metricbeat/module/kubernetes/_meta/test/kube-state-metrics index 4a1ba3005d30..80624f18f27b 100644 --- a/metricbeat/module/kubernetes/_meta/test/kube-state-metrics +++ b/metricbeat/module/kubernetes/_meta/test/kube-state-metrics @@ -82,91 +82,114 @@ go_memstats_sys_bytes 2.6564856e+07 # HELP kube_deployment_metadata_generation Sequence number representing a specific generation of the desired state. # TYPE kube_deployment_metadata_generation gauge kube_deployment_metadata_generation{deployment="jumpy-owl-redis",namespace="default"} 1 +kube_deployment_metadata_generation{deployment="jumpy-owl-redis",namespace="test"} 2 kube_deployment_metadata_generation{deployment="kube-state-metrics",namespace="kube-system"} 1 kube_deployment_metadata_generation{deployment="tiller-deploy",namespace="kube-system"} 1 kube_deployment_metadata_generation{deployment="wise-lynx-jenkins",namespace="jenkins"} 1 # HELP kube_deployment_spec_paused Whether the deployment is paused and will not be processed by the deployment controller. # TYPE kube_deployment_spec_paused gauge kube_deployment_spec_paused{deployment="jumpy-owl-redis",namespace="default"} 0 +kube_deployment_spec_paused{deployment="jumpy-owl-redis",namespace="test"} 1 kube_deployment_spec_paused{deployment="kube-state-metrics",namespace="kube-system"} 0 kube_deployment_spec_paused{deployment="tiller-deploy",namespace="kube-system"} 0 kube_deployment_spec_paused{deployment="wise-lynx-jenkins",namespace="jenkins"} 0 # HELP kube_deployment_spec_replicas Number of desired pods for a deployment. # TYPE kube_deployment_spec_replicas gauge kube_deployment_spec_replicas{deployment="jumpy-owl-redis",namespace="default"} 1 +kube_deployment_spec_replicas{deployment="jumpy-owl-redis",namespace="test"} 2 kube_deployment_spec_replicas{deployment="kube-state-metrics",namespace="kube-system"} 2 kube_deployment_spec_replicas{deployment="tiller-deploy",namespace="kube-system"} 1 kube_deployment_spec_replicas{deployment="wise-lynx-jenkins",namespace="jenkins"} 1 # HELP kube_deployment_spec_strategy_rollingupdate_max_unavailable Maximum number of unavailable replicas during a rolling update of a deployment. # TYPE kube_deployment_spec_strategy_rollingupdate_max_unavailable gauge kube_deployment_spec_strategy_rollingupdate_max_unavailable{deployment="jumpy-owl-redis",namespace="default"} 1 +kube_deployment_spec_strategy_rollingupdate_max_unavailable{deployment="jumpy-owl-redis",namespace="test"} 3 kube_deployment_spec_strategy_rollingupdate_max_unavailable{deployment="kube-state-metrics",namespace="kube-system"} 1 kube_deployment_spec_strategy_rollingupdate_max_unavailable{deployment="tiller-deploy",namespace="kube-system"} 1 kube_deployment_spec_strategy_rollingupdate_max_unavailable{deployment="wise-lynx-jenkins",namespace="jenkins"} 1 # HELP kube_deployment_status_observed_generation The generation observed by the deployment controller. # TYPE kube_deployment_status_observed_generation gauge kube_deployment_status_observed_generation{deployment="jumpy-owl-redis",namespace="default"} 1 +kube_deployment_status_observed_generation{deployment="jumpy-owl-redis",namespace="test"} 4 kube_deployment_status_observed_generation{deployment="kube-state-metrics",namespace="kube-system"} 1 kube_deployment_status_observed_generation{deployment="tiller-deploy",namespace="kube-system"} 1 kube_deployment_status_observed_generation{deployment="wise-lynx-jenkins",namespace="jenkins"} 1 # HELP kube_deployment_status_replicas The number of replicas per deployment. # TYPE kube_deployment_status_replicas gauge kube_deployment_status_replicas{deployment="jumpy-owl-redis",namespace="default"} 1 +kube_deployment_status_replicas{deployment="jumpy-owl-redis",namespace="test"} 5 kube_deployment_status_replicas{deployment="kube-state-metrics",namespace="kube-system"} 2 kube_deployment_status_replicas{deployment="tiller-deploy",namespace="kube-system"} 1 kube_deployment_status_replicas{deployment="wise-lynx-jenkins",namespace="jenkins"} 1 # HELP kube_deployment_status_replicas_available The number of available replicas per deployment. # TYPE kube_deployment_status_replicas_available gauge kube_deployment_status_replicas_available{deployment="jumpy-owl-redis",namespace="default"} 0 +kube_deployment_status_replicas_available{deployment="jumpy-owl-redis",namespace="test"} 6 kube_deployment_status_replicas_available{deployment="kube-state-metrics",namespace="kube-system"} 1 kube_deployment_status_replicas_available{deployment="tiller-deploy",namespace="kube-system"} 1 kube_deployment_status_replicas_available{deployment="wise-lynx-jenkins",namespace="jenkins"} 1 # HELP kube_deployment_status_replicas_unavailable The number of unavailable replicas per deployment. # TYPE kube_deployment_status_replicas_unavailable gauge kube_deployment_status_replicas_unavailable{deployment="jumpy-owl-redis",namespace="default"} 1 +kube_deployment_status_replicas_unavailable{deployment="jumpy-owl-redis",namespace="test"} 7 kube_deployment_status_replicas_unavailable{deployment="kube-state-metrics",namespace="kube-system"} 1 kube_deployment_status_replicas_unavailable{deployment="tiller-deploy",namespace="kube-system"} 0 kube_deployment_status_replicas_unavailable{deployment="wise-lynx-jenkins",namespace="jenkins"} 0 # HELP kube_deployment_status_replicas_updated The number of updated replicas per deployment. # TYPE kube_deployment_status_replicas_updated gauge kube_deployment_status_replicas_updated{deployment="jumpy-owl-redis",namespace="default"} 1 +kube_deployment_status_replicas_updated{deployment="jumpy-owl-redis",namespace="test"} 8 kube_deployment_status_replicas_updated{deployment="kube-state-metrics",namespace="kube-system"} 2 kube_deployment_status_replicas_updated{deployment="tiller-deploy",namespace="kube-system"} 1 kube_deployment_status_replicas_updated{deployment="wise-lynx-jenkins",namespace="jenkins"} 1 # HELP kube_node_info Information about a cluster node. # TYPE kube_node_info gauge kube_node_info{container_runtime_version="docker://1.11.1",kernel_version="4.7.2",kubelet_version="v1.5.3",kubeproxy_version="v1.5.3",node="minikube",os_image="Buildroot 2016.08"} 1 +kube_node_info{container_runtime_version="docker://1.11.1",kernel_version="4.7.2",kubelet_version="v1.5.3",kubeproxy_version="v1.5.3",node="minikube-test",os_image="Buildroot 2016.08"} 1 # HELP kube_node_spec_unschedulable Whether a node can schedule new pods. # TYPE kube_node_spec_unschedulable gauge kube_node_spec_unschedulable{node="minikube"} 0 +kube_node_spec_unschedulable{node="minikube-test"} 1 # HELP kube_node_status_allocatable_cpu_cores The CPU resources of a node that are available for scheduling. # TYPE kube_node_status_allocatable_cpu_cores gauge kube_node_status_allocatable_cpu_cores{node="minikube"} 2 +kube_node_status_allocatable_cpu_cores{node="minikube-test"} 3 # HELP kube_node_status_allocatable_memory_bytes The memory resources of a node that are available for scheduling. # TYPE kube_node_status_allocatable_memory_bytes gauge kube_node_status_allocatable_memory_bytes{node="minikube"} 2.09778688e+09 +kube_node_status_allocatable_memory_bytes{node="minikube-test"} 3.09778688e+09 # HELP kube_node_status_allocatable_pods The pod resources of a node that are available for scheduling. # TYPE kube_node_status_allocatable_pods gauge kube_node_status_allocatable_pods{node="minikube"} 110 +kube_node_status_allocatable_pods{node="minikube-test"} 210 # HELP kube_node_status_capacity_cpu_cores The total CPU resources of the node. # TYPE kube_node_status_capacity_cpu_cores gauge kube_node_status_capacity_cpu_cores{node="minikube"} 2 +kube_node_status_capacity_cpu_cores{node="minikube-test"} 4 # HELP kube_node_status_capacity_memory_bytes The total memory resources of the node. # TYPE kube_node_status_capacity_memory_bytes gauge kube_node_status_capacity_memory_bytes{node="minikube"} 2.09778688e+09 +kube_node_status_capacity_memory_bytes{node="minikube-test"} 4.09778688e+09 # HELP kube_node_status_capacity_pods The total pod resources of the node. # TYPE kube_node_status_capacity_pods gauge kube_node_status_capacity_pods{node="minikube"} 110 +kube_node_status_capacity_pods{node="minikube-test"} 310 # HELP kube_node_status_out_of_disk Whether the node is out of disk space # TYPE kube_node_status_out_of_disk gauge kube_node_status_out_of_disk{condition="false",node="minikube"} 1 kube_node_status_out_of_disk{condition="true",node="minikube"} 0 kube_node_status_out_of_disk{condition="unknown",node="minikube"} 0 +kube_node_status_out_of_disk{condition="false",node="minikube-test"} 1 +kube_node_status_out_of_disk{condition="true",node="minikube-test"} 0 +kube_node_status_out_of_disk{condition="unknown",node="minikube-test"} 0 # HELP kube_node_status_ready The ready status of a cluster node. # TYPE kube_node_status_ready gauge kube_node_status_ready{condition="false",node="minikube"} 0 kube_node_status_ready{condition="true",node="minikube"} 1 kube_node_status_ready{condition="unknown",node="minikube"} 0 +kube_node_status_ready{condition="false",node="minikube-test"} 0 +kube_node_status_ready{condition="true",node="minikube-test"} 1 +kube_node_status_ready{condition="unknown",node="minikube-test"} 0 # HELP kube_pod_container_info Information about a container in a pod. # TYPE kube_pod_container_info gauge kube_pod_container_info{container="dnsmasq",container_id="docker://9a4c9462cd078d7be4f0a9b94bcfeb69d5fdd76bff67142df3f58367ac7e8d61",image="gcr.io/google_containers/kube-dnsmasq-amd64:1.4",image_id="docker://sha256:3ec65756a89b70b4095e43a340a6e2d5696cac7a93a29619ff5c4b6be9af2773",namespace="kube-system",pod="kube-dns-v20-5g5cb"} 1 @@ -175,6 +198,7 @@ kube_pod_container_info{container="jumpy-owl-redis",container_id="docker://4fa22 kube_pod_container_info{container="kube-addon-manager",container_id="docker://91fdd43f6b1b4c3dd133cfca53e0b1210bc557c2ae56006026b5ccdb5f52826f",image="gcr.io/google-containers/kube-addon-manager:v6.3",image_id="docker://sha256:79eb64bc98df10a9af7e39f70df817e1862f8a5ec7657714df68439a617ee9ec",namespace="kube-system",pod="kube-addon-manager-minikube"} 1 kube_pod_container_info{container="kube-state-metrics",container_id="docker://973cbe45982c5126a5caf8c58d964c0ab1d5bb2c165ccc59715fcc1ebd58ab3d",image="gcr.io/google_containers/kube-state-metrics:v0.4.1",image_id="docker://sha256:be329a05c2e77e7d067b4e1dbefa1567a91d0487d3500d608171489369bfd945",namespace="kube-system",pod="kube-state-metrics-1303537707-7ncd1"} 1 kube_pod_container_info{container="kubedns",container_id="docker://fa3d83f648de42492b38fa3e8501d109376f391c50f2bd210c895c8477ae4b62",image="gcr.io/google_containers/kubedns-amd64:1.9",image_id="docker://sha256:26cf1ed9b14486b93acd70c060a17fea13620393d3aa8e76036b773197c47a05",namespace="kube-system",pod="kube-dns-v20-5g5cb"} 1 +kube_pod_container_info{container="kubedns",container_id="docker://fa3d83f648de42492b38fa3e8501d109376f391c50f2bd210c895c8477ae4b62-test",image="gcr.io/google_containers/kubedns-amd64:1.9-test",image_id="docker://sha256:26cf1ed9b14486b93acd70c060a17fea13620393d3aa8e76036b773197c47a05",namespace="test",pod="kube-dns-v20-5g5cb-test"} 0 kube_pod_container_info{container="kubernetes-dashboard",container_id="docker://3aaee8bdd311c015240e99fa2a5a5f2f26b11b51236a683b39d8c1902e423978",image="gcr.io/google_containers/kubernetes-dashboard-amd64:v1.5.1",image_id="docker://sha256:1180413103fdfd00a7882d3d8653a220d88c6ea4466fb860e98376c45ee1a1d0",namespace="kube-system",pod="kubernetes-dashboard-vw0l6"} 1 kube_pod_container_info{container="tiller",container_id="docker://469f5d2b7854eb52e5d13dc0cd3e664c1b682b157aabaf596ffe4984f1516902",image="gcr.io/kubernetes-helm/tiller:v2.3.1",image_id="docker://sha256:38527daf791dbe472c37ecb1e8b13a62e31c00d9ff4c8a1f019d7022a96a43da",namespace="kube-system",pod="tiller-deploy-3067024529-9lpmb"} 1 kube_pod_container_info{container="wise-lynx-jenkins",container_id="docker://e2ee1c2c7b8d4e5fd8c834b83cba8377d6b0e39da18157688ccc1a06b7c53117",image="jenkinsci/jenkins:2.46.1",image_id="docker://sha256:36023b9defd066ee53c03e33ba3add7225aee8447cb3154133012b1e152153c0",namespace="jenkins",pod="wise-lynx-jenkins-1616735317-svn6k"} 1 @@ -188,6 +212,7 @@ kube_pod_container_resource_limits_memory_bytes{container="healthz",namespace="k kube_pod_container_resource_limits_memory_bytes{container="kube-state-metrics",namespace="kube-system",node="",pod="kube-state-metrics-1303537707-mnzbp"} 5.24288e+07 kube_pod_container_resource_limits_memory_bytes{container="kube-state-metrics",namespace="kube-system",node="minikube",pod="kube-state-metrics-1303537707-7ncd1"} 5.24288e+07 kube_pod_container_resource_limits_memory_bytes{container="kubedns",namespace="kube-system",node="minikube",pod="kube-dns-v20-5g5cb"} 1.7825792e+08 +kube_pod_container_resource_limits_memory_bytes{container="kubedns",namespace="test",node="minikube-test",pod="kube-dns-v20-5g5cb-test"} 2.7825792e+08 # HELP kube_pod_container_resource_requests_cpu_cores The number of requested cpu cores by a container. # TYPE kube_pod_container_resource_requests_cpu_cores gauge kube_pod_container_resource_requests_cpu_cores{container="healthz",namespace="kube-system",node="minikube",pod="kube-dns-v20-5g5cb"} 0.01 @@ -196,6 +221,7 @@ kube_pod_container_resource_requests_cpu_cores{container="kube-addon-manager",na kube_pod_container_resource_requests_cpu_cores{container="kube-state-metrics",namespace="kube-system",node="",pod="kube-state-metrics-1303537707-mnzbp"} 0.1 kube_pod_container_resource_requests_cpu_cores{container="kube-state-metrics",namespace="kube-system",node="minikube",pod="kube-state-metrics-1303537707-7ncd1"} 0.1 kube_pod_container_resource_requests_cpu_cores{container="kubedns",namespace="kube-system",node="minikube",pod="kube-dns-v20-5g5cb"} 0.1 +kube_pod_container_resource_requests_cpu_cores{container="kubedns",namespace="test",node="minikube-test",pod="kube-dns-v20-5g5cb-test"} 0.2 kube_pod_container_resource_requests_cpu_cores{container="wise-lynx-jenkins",namespace="jenkins",node="minikube",pod="wise-lynx-jenkins-1616735317-svn6k"} 0.2 # HELP kube_pod_container_resource_requests_memory_bytes The number of requested memory bytes by a container. # TYPE kube_pod_container_resource_requests_memory_bytes gauge @@ -205,6 +231,7 @@ kube_pod_container_resource_requests_memory_bytes{container="kube-addon-manager" kube_pod_container_resource_requests_memory_bytes{container="kube-state-metrics",namespace="kube-system",node="",pod="kube-state-metrics-1303537707-mnzbp"} 3.145728e+07 kube_pod_container_resource_requests_memory_bytes{container="kube-state-metrics",namespace="kube-system",node="minikube",pod="kube-state-metrics-1303537707-7ncd1"} 3.145728e+07 kube_pod_container_resource_requests_memory_bytes{container="kubedns",namespace="kube-system",node="minikube",pod="kube-dns-v20-5g5cb"} 7.340032e+07 +kube_pod_container_resource_requests_memory_bytes{container="kubedns",namespace="test",node="minikube-test",pod="kube-dns-v20-5g5cb-test"} 8.340032e+07 kube_pod_container_resource_requests_memory_bytes{container="wise-lynx-jenkins",namespace="jenkins",node="minikube",pod="wise-lynx-jenkins-1616735317-svn6k"} 2.68435456e+08 # HELP kube_pod_container_status_ready Describes whether the containers readiness check succeeded. # TYPE kube_pod_container_status_ready gauge @@ -214,6 +241,7 @@ kube_pod_container_status_ready{container="jumpy-owl-redis",namespace="default", kube_pod_container_status_ready{container="kube-addon-manager",namespace="kube-system",pod="kube-addon-manager-minikube"} 1 kube_pod_container_status_ready{container="kube-state-metrics",namespace="kube-system",pod="kube-state-metrics-1303537707-7ncd1"} 1 kube_pod_container_status_ready{container="kubedns",namespace="kube-system",pod="kube-dns-v20-5g5cb"} 1 +kube_pod_container_status_ready{container="kubedns",namespace="test",pod="kube-dns-v20-5g5cb-test"} 0 kube_pod_container_status_ready{container="kubernetes-dashboard",namespace="kube-system",pod="kubernetes-dashboard-vw0l6"} 1 kube_pod_container_status_ready{container="tiller",namespace="kube-system",pod="tiller-deploy-3067024529-9lpmb"} 1 kube_pod_container_status_ready{container="wise-lynx-jenkins",namespace="jenkins",pod="wise-lynx-jenkins-1616735317-svn6k"} 1 @@ -225,6 +253,7 @@ kube_pod_container_status_restarts{container="jumpy-owl-redis",namespace="defaul kube_pod_container_status_restarts{container="kube-addon-manager",namespace="kube-system",pod="kube-addon-manager-minikube"} 2 kube_pod_container_status_restarts{container="kube-state-metrics",namespace="kube-system",pod="kube-state-metrics-1303537707-7ncd1"} 1 kube_pod_container_status_restarts{container="kubedns",namespace="kube-system",pod="kube-dns-v20-5g5cb"} 2 +kube_pod_container_status_restarts{container="kubedns",namespace="test",pod="kube-dns-v20-5g5cb-test"} 3 kube_pod_container_status_restarts{container="kubernetes-dashboard",namespace="kube-system",pod="kubernetes-dashboard-vw0l6"} 2 kube_pod_container_status_restarts{container="tiller",namespace="kube-system",pod="tiller-deploy-3067024529-9lpmb"} 1 kube_pod_container_status_restarts{container="wise-lynx-jenkins",namespace="jenkins",pod="wise-lynx-jenkins-1616735317-svn6k"} 1 @@ -236,6 +265,7 @@ kube_pod_container_status_running{container="jumpy-owl-redis",namespace="default kube_pod_container_status_running{container="kube-addon-manager",namespace="kube-system",pod="kube-addon-manager-minikube"} 1 kube_pod_container_status_running{container="kube-state-metrics",namespace="kube-system",pod="kube-state-metrics-1303537707-7ncd1"} 1 kube_pod_container_status_running{container="kubedns",namespace="kube-system",pod="kube-dns-v20-5g5cb"} 1 +kube_pod_container_status_running{container="kubedns",namespace="test",pod="kube-dns-v20-5g5cb-test"} 0 kube_pod_container_status_running{container="kubernetes-dashboard",namespace="kube-system",pod="kubernetes-dashboard-vw0l6"} 1 kube_pod_container_status_running{container="tiller",namespace="kube-system",pod="tiller-deploy-3067024529-9lpmb"} 1 kube_pod_container_status_running{container="wise-lynx-jenkins",namespace="jenkins",pod="wise-lynx-jenkins-1616735317-svn6k"} 1 @@ -247,6 +277,7 @@ kube_pod_container_status_terminated{container="jumpy-owl-redis",namespace="defa kube_pod_container_status_terminated{container="kube-addon-manager",namespace="kube-system",pod="kube-addon-manager-minikube"} 0 kube_pod_container_status_terminated{container="kube-state-metrics",namespace="kube-system",pod="kube-state-metrics-1303537707-7ncd1"} 0 kube_pod_container_status_terminated{container="kubedns",namespace="kube-system",pod="kube-dns-v20-5g5cb"} 0 +kube_pod_container_status_terminated{container="kubedns",namespace="test",pod="kube-dns-v20-5g5cb-test"} 1 kube_pod_container_status_terminated{container="kubernetes-dashboard",namespace="kube-system",pod="kubernetes-dashboard-vw0l6"} 0 kube_pod_container_status_terminated{container="tiller",namespace="kube-system",pod="tiller-deploy-3067024529-9lpmb"} 0 kube_pod_container_status_terminated{container="wise-lynx-jenkins",namespace="jenkins",pod="wise-lynx-jenkins-1616735317-svn6k"} 0 @@ -258,6 +289,7 @@ kube_pod_container_status_waiting{container="jumpy-owl-redis",namespace="default kube_pod_container_status_waiting{container="kube-addon-manager",namespace="kube-system",pod="kube-addon-manager-minikube"} 0 kube_pod_container_status_waiting{container="kube-state-metrics",namespace="kube-system",pod="kube-state-metrics-1303537707-7ncd1"} 0 kube_pod_container_status_waiting{container="kubedns",namespace="kube-system",pod="kube-dns-v20-5g5cb"} 0 +kube_pod_container_status_waiting{container="kubedns",namespace="test",pod="kube-dns-v20-5g5cb"} 0 kube_pod_container_status_waiting{container="kubernetes-dashboard",namespace="kube-system",pod="kubernetes-dashboard-vw0l6"} 0 kube_pod_container_status_waiting{container="tiller",namespace="kube-system",pod="tiller-deploy-3067024529-9lpmb"} 0 kube_pod_container_status_waiting{container="wise-lynx-jenkins",namespace="jenkins",pod="wise-lynx-jenkins-1616735317-svn6k"} 0 @@ -265,6 +297,7 @@ kube_pod_container_status_waiting{container="wise-lynx-jenkins",namespace="jenki # TYPE kube_pod_info gauge kube_pod_info{host_ip="",namespace="kube-system",node="",pod="kube-state-metrics-1303537707-mnzbp",pod_ip=""} 1 kube_pod_info{host_ip="192.168.99.100",namespace="default",node="minikube",pod="jumpy-owl-redis-3481028193-s78x9",pod_ip="172.17.0.4"} 1 +kube_pod_info{host_ip="192.168.99.200",namespace="test",node="minikube-test",pod="jumpy-owl-redis-3481028193-s78x9",pod_ip="172.17.0.5"} 1 kube_pod_info{host_ip="192.168.99.100",namespace="jenkins",node="minikube",pod="wise-lynx-jenkins-1616735317-svn6k",pod_ip="172.17.0.7"} 1 kube_pod_info{host_ip="192.168.99.100",namespace="kube-system",node="minikube",pod="kube-addon-manager-minikube",pod_ip="192.168.99.100"} 1 kube_pod_info{host_ip="192.168.99.100",namespace="kube-system",node="minikube",pod="kube-dns-v20-5g5cb",pod_ip="172.17.0.6"} 1 @@ -276,6 +309,9 @@ kube_pod_info{host_ip="192.168.99.100",namespace="kube-system",node="minikube",p kube_pod_status_phase{namespace="default",phase="Running",pod="jumpy-owl-redis-3481028193-s78x9"} 0 kube_pod_status_phase{namespace="default",phase="Succeeded",pod="jumpy-owl-redis-3481028193-s78x9"} 1 kube_pod_status_phase{namespace="default",phase="Unknown",pod="jumpy-owl-redis-3481028193-s78x9"} 0 +kube_pod_status_phase{namespace="test",phase="Running",pod="jumpy-owl-redis-3481028193-s78x9"} 1 +kube_pod_status_phase{namespace="test",phase="Succeeded",pod="jumpy-owl-redis-3481028193-s78x9"} 0 +kube_pod_status_phase{namespace="test",phase="Unknown",pod="jumpy-owl-redis-3481028193-s78x9"} 0 kube_pod_status_phase{namespace="jenkins",phase="Running",pod="wise-lynx-jenkins-1616735317-svn6k"} 1 kube_pod_status_phase{namespace="kube-system",phase="Pending",pod="kube-state-metrics-1303537707-mnzbp"} 1 kube_pod_status_phase{namespace="kube-system",phase="Running",pod="kube-addon-manager-minikube"} 1 @@ -286,6 +322,7 @@ kube_pod_status_phase{namespace="kube-system",phase="Running",pod="tiller-deploy # HELP kube_pod_status_ready Describes whether the pod is ready to serve requests. # TYPE kube_pod_status_ready gauge kube_pod_status_ready{condition="false",namespace="default",pod="jumpy-owl-redis-3481028193-s78x9"} 1 +kube_pod_status_ready{condition="false",namespace="test",pod="jumpy-owl-redis-3481028193-s78x9"} 0 kube_pod_status_ready{condition="false",namespace="jenkins",pod="wise-lynx-jenkins-1616735317-svn6k"} 0 kube_pod_status_ready{condition="false",namespace="kube-system",pod="kube-addon-manager-minikube"} 0 kube_pod_status_ready{condition="false",namespace="kube-system",pod="kube-dns-v20-5g5cb"} 0 @@ -293,6 +330,7 @@ kube_pod_status_ready{condition="false",namespace="kube-system",pod="kube-state- kube_pod_status_ready{condition="false",namespace="kube-system",pod="kubernetes-dashboard-vw0l6"} 0 kube_pod_status_ready{condition="false",namespace="kube-system",pod="tiller-deploy-3067024529-9lpmb"} 0 kube_pod_status_ready{condition="true",namespace="default",pod="jumpy-owl-redis-3481028193-s78x9"} 0 +kube_pod_status_ready{condition="true",namespace="test",pod="jumpy-owl-redis-3481028193-s78x9"} 1 kube_pod_status_ready{condition="true",namespace="jenkins",pod="wise-lynx-jenkins-1616735317-svn6k"} 1 kube_pod_status_ready{condition="true",namespace="kube-system",pod="kube-addon-manager-minikube"} 1 kube_pod_status_ready{condition="true",namespace="kube-system",pod="kube-dns-v20-5g5cb"} 1 @@ -300,6 +338,7 @@ kube_pod_status_ready{condition="true",namespace="kube-system",pod="kube-state-m kube_pod_status_ready{condition="true",namespace="kube-system",pod="kubernetes-dashboard-vw0l6"} 1 kube_pod_status_ready{condition="true",namespace="kube-system",pod="tiller-deploy-3067024529-9lpmb"} 1 kube_pod_status_ready{condition="unknown",namespace="default",pod="jumpy-owl-redis-3481028193-s78x9"} 0 +kube_pod_status_ready{condition="unknown",namespace="test",pod="jumpy-owl-redis-3481028193-s78x9"} 0 kube_pod_status_ready{condition="unknown",namespace="jenkins",pod="wise-lynx-jenkins-1616735317-svn6k"} 0 kube_pod_status_ready{condition="unknown",namespace="kube-system",pod="kube-addon-manager-minikube"} 0 kube_pod_status_ready{condition="unknown",namespace="kube-system",pod="kube-dns-v20-5g5cb"} 0 @@ -309,6 +348,7 @@ kube_pod_status_ready{condition="unknown",namespace="kube-system",pod="tiller-de # HELP kube_pod_status_scheduled Describes the status of the scheduling process for the pod. # TYPE kube_pod_status_scheduled gauge kube_pod_status_scheduled{condition="false",namespace="default",pod="jumpy-owl-redis-3481028193-s78x9"} 0 +kube_pod_status_scheduled{condition="false",namespace="test",pod="jumpy-owl-redis-3481028193-s78x9"} 1 kube_pod_status_scheduled{condition="false",namespace="jenkins",pod="wise-lynx-jenkins-1616735317-svn6k"} 0 kube_pod_status_scheduled{condition="false",namespace="kube-system",pod="kube-addon-manager-minikube"} 0 kube_pod_status_scheduled{condition="false",namespace="kube-system",pod="kube-dns-v20-5g5cb"} 0 @@ -337,36 +377,42 @@ kube_pod_status_scheduled{condition="unknown",namespace="kube-system",pod="tille kube_replicaset_metadata_generation{namespace="default",replicaset="jumpy-owl-redis-3481028193"} 1 kube_replicaset_metadata_generation{namespace="jenkins",replicaset="wise-lynx-jenkins-1616735317"} 1 kube_replicaset_metadata_generation{namespace="kube-system",replicaset="kube-state-metrics-1303537707"} 1 +kube_replicaset_metadata_generation{namespace="test",replicaset="kube-state-metrics-1303537707"} 1 kube_replicaset_metadata_generation{namespace="kube-system",replicaset="tiller-deploy-3067024529"} 1 # HELP kube_replicaset_spec_replicas Number of desired pods for a ReplicaSet. # TYPE kube_replicaset_spec_replicas gauge kube_replicaset_spec_replicas{namespace="default",replicaset="jumpy-owl-redis-3481028193"} 1 kube_replicaset_spec_replicas{namespace="jenkins",replicaset="wise-lynx-jenkins-1616735317"} 1 kube_replicaset_spec_replicas{namespace="kube-system",replicaset="kube-state-metrics-1303537707"} 2 +kube_replicaset_spec_replicas{namespace="test",replicaset="kube-state-metrics-1303537707"} 3 kube_replicaset_spec_replicas{namespace="kube-system",replicaset="tiller-deploy-3067024529"} 1 # HELP kube_replicaset_status_fully_labeled_replicas The number of fully labeled replicas per ReplicaSet. # TYPE kube_replicaset_status_fully_labeled_replicas gauge kube_replicaset_status_fully_labeled_replicas{namespace="default",replicaset="jumpy-owl-redis-3481028193"} 1 kube_replicaset_status_fully_labeled_replicas{namespace="jenkins",replicaset="wise-lynx-jenkins-1616735317"} 1 kube_replicaset_status_fully_labeled_replicas{namespace="kube-system",replicaset="kube-state-metrics-1303537707"} 2 +kube_replicaset_status_fully_labeled_replicas{namespace="test",replicaset="kube-state-metrics-1303537707"} 4 kube_replicaset_status_fully_labeled_replicas{namespace="kube-system",replicaset="tiller-deploy-3067024529"} 1 # HELP kube_replicaset_status_observed_generation The generation observed by the ReplicaSet controller. # TYPE kube_replicaset_status_observed_generation gauge kube_replicaset_status_observed_generation{namespace="default",replicaset="jumpy-owl-redis-3481028193"} 1 kube_replicaset_status_observed_generation{namespace="jenkins",replicaset="wise-lynx-jenkins-1616735317"} 1 kube_replicaset_status_observed_generation{namespace="kube-system",replicaset="kube-state-metrics-1303537707"} 1 +kube_replicaset_status_observed_generation{namespace="test",replicaset="kube-state-metrics-1303537707"} 5 kube_replicaset_status_observed_generation{namespace="kube-system",replicaset="tiller-deploy-3067024529"} 1 # HELP kube_replicaset_status_ready_replicas The number of ready replicas per ReplicaSet. # TYPE kube_replicaset_status_ready_replicas gauge kube_replicaset_status_ready_replicas{namespace="default",replicaset="jumpy-owl-redis-3481028193"} 0 kube_replicaset_status_ready_replicas{namespace="jenkins",replicaset="wise-lynx-jenkins-1616735317"} 1 kube_replicaset_status_ready_replicas{namespace="kube-system",replicaset="kube-state-metrics-1303537707"} 1 +kube_replicaset_status_ready_replicas{namespace="test",replicaset="kube-state-metrics-1303537707"} 6 kube_replicaset_status_ready_replicas{namespace="kube-system",replicaset="tiller-deploy-3067024529"} 1 # HELP kube_replicaset_status_replicas The number of replicas per ReplicaSet. # TYPE kube_replicaset_status_replicas gauge kube_replicaset_status_replicas{namespace="default",replicaset="jumpy-owl-redis-3481028193"} 1 kube_replicaset_status_replicas{namespace="jenkins",replicaset="wise-lynx-jenkins-1616735317"} 1 kube_replicaset_status_replicas{namespace="kube-system",replicaset="kube-state-metrics-1303537707"} 2 +kube_replicaset_status_replicas{namespace="test",replicaset="kube-state-metrics-1303537707"} 7 kube_replicaset_status_replicas{namespace="kube-system",replicaset="tiller-deploy-3067024529"} 1 # HELP process_cpu_seconds_total Total user and system CPU time spent in seconds. # TYPE process_cpu_seconds_total counter diff --git a/metricbeat/module/kubernetes/state_container/data.go b/metricbeat/module/kubernetes/state_container/data.go index 3816de256892..7c75e135a57b 100644 --- a/metricbeat/module/kubernetes/state_container/data.go +++ b/metricbeat/module/kubernetes/state_container/data.go @@ -21,11 +21,15 @@ func eventMapping(families []*dto.MetricFamily) ([]common.MapStr, error) { if container == "" { continue } - event, ok := eventsMap[container] + + namespace := util.GetLabel(metric, "namespace") + containerKey := namespace + "::" + container + event, ok := eventsMap[containerKey] if !ok { event = common.MapStr{} - eventsMap[container] = event + eventsMap[containerKey] = event } + switch family.GetName() { case "kube_pod_container_info": event.Put(mb.ModuleDataKey+".pod.name", util.GetLabel(metric, "pod")) @@ -84,7 +88,8 @@ func eventMapping(families []*dto.MetricFamily) ([]common.MapStr, error) { } } - var events []common.MapStr + // initialize, populate events array from values in eventsMap + events := make([]common.MapStr, 0, len(eventsMap)) for _, event := range eventsMap { events = append(events, event) } diff --git a/metricbeat/module/kubernetes/state_container/state_container_test.go b/metricbeat/module/kubernetes/state_container/state_container_test.go index 6adb69bcbf9f..6e49f0332d9f 100644 --- a/metricbeat/module/kubernetes/state_container/state_container_test.go +++ b/metricbeat/module/kubernetes/state_container/state_container_test.go @@ -44,38 +44,91 @@ func TestEventMapping(t *testing.T) { events, err := f.Fetch() assert.NoError(t, err) - assert.Equal(t, 9, len(events), "Wrong number of returned events") - - testCases := map[string]interface{}{ - "_module.namespace": "kube-system", - "_module.node.name": "minikube", - "_module.pod.name": "kube-dns-v20-5g5cb", - - "image": "gcr.io/google_containers/exechealthz-amd64:1.2", - "status.phase": "running", - "status.ready": true, - "status.restarts": 2, - - "memory.limit.bytes": 52428800, - "memory.request.bytes": 52428800, - "cpu.request.nanocores": 10000000, - } + assert.Equal(t, 10, len(events), "Wrong number of returned events") + testCases := testCases() for _, event := range events { name, err := event.GetValue("name") - if err == nil && name == "healthz" { - for k, v := range testCases { - testValue(t, event, k, v) + if err == nil { + namespace, err := event.GetValue("_module.namespace") + if err == nil { + eventKey := namespace.(string) + "@" + name.(string) + oneTestCase, oneTestCaseFound := testCases[eventKey] + if oneTestCaseFound { + for k, v := range oneTestCase { + testValue(eventKey, t, event, k, v) + } + delete(testCases, eventKey) + } } - return } } - t.Error("Test reference event not found") + if len(testCases) > 0 { + t.Errorf("Test reference events not found: %v, \n\ngot: %v", testCases, events) + } } -func testValue(t *testing.T, event common.MapStr, field string, expected interface{}) { +func testValue(eventKey string, t *testing.T, event common.MapStr, field string, expected interface{}) { data, err := event.GetValue(field) - assert.NoError(t, err, "Could not read field "+field) - assert.EqualValues(t, expected, data, "Wrong value for field "+field) + assert.NoError(t, err, eventKey+": Could not read field "+field) + assert.EqualValues(t, expected, data, eventKey+": Wrong value for field "+field) +} + +// Test cases built to match 3 examples in 'module/kubernetes/_meta/test/kube-state-metrics'. +// In particular, test same named containers in different namespaces +func testCases() map[string]map[string]interface{} { + return map[string]map[string]interface{}{ + "kube-system@kubedns": { + "_namespace": "container", + "_module.namespace": "kube-system", + "_module.node.name": "minikube", + "_module.pod.name": "kube-dns-v20-5g5cb", + "name": "kubedns", + "id": "docker://fa3d83f648de42492b38fa3e8501d109376f391c50f2bd210c895c8477ae4b62", + + "image": "gcr.io/google_containers/kubedns-amd64:1.9", + "status.phase": "running", + "status.ready": true, + "status.restarts": 2, + + "memory.limit.bytes": 178257920, + "memory.request.bytes": 73400320, + "cpu.request.nanocores": float64(1e+08), + }, + "test@kubedns": { + "_namespace": "container", + "_module.namespace": "test", + "_module.node.name": "minikube-test", + "_module.pod.name": "kube-dns-v20-5g5cb-test", + "name": "kubedns", + "id": "docker://fa3d83f648de42492b38fa3e8501d109376f391c50f2bd210c895c8477ae4b62-test", + + "image": "gcr.io/google_containers/kubedns-amd64:1.9-test", + "status.phase": "terminate", + "status.ready": false, + "status.restarts": 3, + + "memory.limit.bytes": 278257920, + "memory.request.bytes": 83400320, + "cpu.request.nanocores": float64(2e+08), + }, + "kube-system@healthz": { + "_namespace": "container", + "_module.namespace": "kube-system", + "_module.node.name": "minikube", + "_module.pod.name": "kube-dns-v20-5g5cb", + "name": "healthz", + "id": "docker://52fa55e051dc5b68e44c027588685b7edd85aaa03b07f7216d399249ff4fc821", + + "image": "gcr.io/google_containers/exechealthz-amd64:1.2", + "status.phase": "running", + "status.ready": true, + "status.restarts": 2, + + "memory.limit.bytes": 52428800, + "memory.request.bytes": 52428800, + "cpu.request.nanocores": float64(1e+07), + }, + } } diff --git a/metricbeat/module/kubernetes/state_deployment/data.go b/metricbeat/module/kubernetes/state_deployment/data.go index 9634de2dbbb1..a9b21660e198 100644 --- a/metricbeat/module/kubernetes/state_deployment/data.go +++ b/metricbeat/module/kubernetes/state_deployment/data.go @@ -21,11 +21,14 @@ func eventMapping(families []*dto.MetricFamily) ([]common.MapStr, error) { if deployment == "" { continue } - event, ok := eventsMap[deployment] + namespace := util.GetLabel(metric, "namespace") + deploymentKey := namespace + "::" + deployment + event, ok := eventsMap[deploymentKey] if !ok { event = common.MapStr{} - eventsMap[deployment] = event + eventsMap[deploymentKey] = event } + switch family.GetName() { case "kube_deployment_metadata_generation": event.Put(mb.ModuleDataKey+".namespace", util.GetLabel(metric, "namespace")) @@ -54,7 +57,8 @@ func eventMapping(families []*dto.MetricFamily) ([]common.MapStr, error) { } } - var events []common.MapStr + // initialize, populate events array from values in eventsMap + events := make([]common.MapStr, 0, len(eventsMap)) for _, event := range eventsMap { events = append(events, event) } diff --git a/metricbeat/module/kubernetes/state_deployment/state_deployment_test.go b/metricbeat/module/kubernetes/state_deployment/state_deployment_test.go index 69f2cd7336d6..3a2761a3efe4 100644 --- a/metricbeat/module/kubernetes/state_deployment/state_deployment_test.go +++ b/metricbeat/module/kubernetes/state_deployment/state_deployment_test.go @@ -44,35 +44,76 @@ func TestEventMapping(t *testing.T) { events, err := f.Fetch() assert.NoError(t, err) - assert.Equal(t, 4, len(events), "Wrong number of returned events") - - testCases := map[string]interface{}{ - "_module.namespace": "default", - - "name": "jumpy-owl-redis", - "paused": false, - - "replicas.available": 0, - "replicas.desired": 1, - "replicas.unavailable": 1, - "replicas.updated": 1, - } + assert.Equal(t, 5, len(events), "Wrong number of returned events") + testCases := testCases() for _, event := range events { name, err := event.GetValue("name") - if err == nil && name == "jumpy-owl-redis" { - for k, v := range testCases { - testValue(t, event, k, v) + if err == nil { + namespace, err := event.GetValue("_module.namespace") + if err == nil { + eventKey := namespace.(string) + "@" + name.(string) + oneTestCase, oneTestCaseFound := testCases[eventKey] + if oneTestCaseFound { + for k, v := range oneTestCase { + testValue(eventKey, t, event, k, v) + } + delete(testCases, eventKey) + } } - return } } - t.Error("Test reference event not found") + if len(testCases) > 0 { + t.Errorf("Test reference events not found: %v, \n\ngot: %v", testCases, events) + } } -func testValue(t *testing.T, event common.MapStr, field string, expected interface{}) { +func testValue(eventKey string, t *testing.T, event common.MapStr, field string, expected interface{}) { data, err := event.GetValue(field) - assert.NoError(t, err, "Could not read field "+field) - assert.EqualValues(t, expected, data, "Wrong value for field "+field) + assert.NoError(t, err, eventKey+": Could not read field "+field) + assert.EqualValues(t, expected, data, eventKey+": Wrong value for field "+field) +} + +// Test cases built to match 3 examples in 'module/kubernetes/_meta/test/kube-state-metrics'. +// In particular, test same named deployments in different namespaces +func testCases() map[string]map[string]interface{} { + return map[string]map[string]interface{}{ + "default@jumpy-owl-redis": { + "_namespace": "deployment", + "_module.namespace": "default", + + "name": "jumpy-owl-redis", + "paused": false, + + "replicas.available": 0, + "replicas.desired": 1, + "replicas.unavailable": 1, + "replicas.updated": 1, + }, + "test@jumpy-owl-redis": { + "_namespace": "deployment", + "_module.namespace": "test", + + "name": "jumpy-owl-redis", + "paused": true, + + "replicas.available": 6, + "replicas.desired": 2, + "replicas.unavailable": 7, + "replicas.updated": 8, + }, + "kube-system@tiller-deploy": { + "_namespace": "deployment", + "_module.namespace": "kube-system", + + "name": "tiller-deploy", + "paused": false, + + "replicas.available": 1, + "replicas.desired": 1, + "replicas.unavailable": 0, + "replicas.updated": 1, + }, + } } diff --git a/metricbeat/module/kubernetes/state_node/state_node_test.go b/metricbeat/module/kubernetes/state_node/state_node_test.go index 321b05669a51..ed282bbc868a 100644 --- a/metricbeat/module/kubernetes/state_node/state_node_test.go +++ b/metricbeat/module/kubernetes/state_node/state_node_test.go @@ -44,32 +44,67 @@ func TestEventMapping(t *testing.T) { events, err := f.Fetch() assert.NoError(t, err) - assert.Equal(t, 1, len(events), "Wrong number of returned events") + assert.Equal(t, 2, len(events), "Wrong number of returned events") + + testCases := testCases() + for _, event := range events { + name, err := event.GetValue("name") + if err == nil { + eventKey := name.(string) + oneTestCase, oneTestCaseFound := testCases[eventKey] + if oneTestCaseFound { + for k, v := range oneTestCase { + testValue(eventKey, t, event, k, v) + } + delete(testCases, eventKey) + } + } + } - testCases := map[string]interface{}{ - "_namespace": "node", - "name": "minikube", + if len(testCases) > 0 { + t.Errorf("Test reference events not found: %v, \n\ngot: %v", testCases, events) + } +} - "status.ready": "true", - "status.unschedulable": false, +func testValue(eventKey string, t *testing.T, event common.MapStr, field string, expected interface{}) { + data, err := event.GetValue(field) + assert.NoError(t, err, eventKey+": Could not read field "+field) + assert.EqualValues(t, expected, data, eventKey+": Wrong value for field "+field) +} - "cpu.allocatable.cores": 2, - "cpu.capacity.cores": 2, +func testCases() map[string]map[string]interface{} { + return map[string]map[string]interface{}{ + "minikube": { + "_namespace": "node", + "name": "minikube", - "memory.allocatable.bytes": 2097786880, - "memory.capacity.bytes": 2097786880, + "status.ready": "true", + "status.unschedulable": false, - "pod.allocatable.total": 110, - "pod.capacity.total": 110, - } + "cpu.allocatable.cores": 2, + "cpu.capacity.cores": 2, - for k, v := range testCases { - testValue(t, events[0], k, v) - } -} + "memory.allocatable.bytes": 2097786880, + "memory.capacity.bytes": 2097786880, -func testValue(t *testing.T, event common.MapStr, field string, expected interface{}) { - data, err := event.GetValue(field) - assert.NoError(t, err, "Could not read field "+field) - assert.EqualValues(t, expected, data, "Wrong value for field "+field) + "pod.allocatable.total": 110, + "pod.capacity.total": 110, + }, + "minikube-test": { + "_namespace": "node", + "name": "minikube-test", + + "status.ready": "true", + "status.unschedulable": true, + + "cpu.allocatable.cores": 3, + "cpu.capacity.cores": 4, + + "memory.allocatable.bytes": 3097786880, + "memory.capacity.bytes": 4097786880, + + "pod.allocatable.total": 210, + "pod.capacity.total": 310, + }, + } } diff --git a/metricbeat/module/kubernetes/state_pod/data.go b/metricbeat/module/kubernetes/state_pod/data.go index 6bd7693711cf..7a2790c555a3 100644 --- a/metricbeat/module/kubernetes/state_pod/data.go +++ b/metricbeat/module/kubernetes/state_pod/data.go @@ -18,11 +18,14 @@ func eventMapping(families []*dto.MetricFamily) ([]common.MapStr, error) { if pod == "" { continue } - event, ok := eventsMap[pod] + namespace := util.GetLabel(metric, "namespace") + podKey := namespace + "::" + pod + event, ok := eventsMap[podKey] if !ok { event = common.MapStr{} - eventsMap[pod] = event + eventsMap[podKey] = event } + switch family.GetName() { case "kube_pod_info": event.Put(mb.ModuleDataKey+".node.name", util.GetLabel(metric, "node")) @@ -62,7 +65,8 @@ func eventMapping(families []*dto.MetricFamily) ([]common.MapStr, error) { } } - var events []common.MapStr + // initialize, populate events array from values in eventsMap + events := make([]common.MapStr, 0, len(eventsMap)) for _, event := range eventsMap { events = append(events, event) } diff --git a/metricbeat/module/kubernetes/state_pod/state_pod_test.go b/metricbeat/module/kubernetes/state_pod/state_pod_test.go index 7035a491d27d..39fa60fcab0a 100644 --- a/metricbeat/module/kubernetes/state_pod/state_pod_test.go +++ b/metricbeat/module/kubernetes/state_pod/state_pod_test.go @@ -44,36 +44,79 @@ func TestEventMapping(t *testing.T) { events, err := f.Fetch() assert.NoError(t, err) - assert.Equal(t, 8, len(events), "Wrong number of returned events") - - testCases := map[string]interface{}{ - "_module.namespace": "default", - "_module.node.name": "minikube", - "name": "jumpy-owl-redis-3481028193-s78x9", - - "host_ip": "192.168.99.100", - "ip": "172.17.0.4", - - "status.phase": "succeeded", - "status.ready": "false", - "status.scheduled": "true", - } + assert.Equal(t, 11, len(events), "Wrong number of returned events") + testCases := testCases() for _, event := range events { name, err := event.GetValue("name") - if err == nil && name == "jumpy-owl-redis-3481028193-s78x9" { - for k, v := range testCases { - testValue(t, event, k, v) + if err == nil { + namespace, err := event.GetValue("_module.namespace") + if err == nil { + eventKey := namespace.(string) + "@" + name.(string) + oneTestCase, oneTestCaseFound := testCases[eventKey] + if oneTestCaseFound { + for k, v := range oneTestCase { + testValue(eventKey, t, event, k, v) + } + delete(testCases, eventKey) + } } - return } } - t.Error("Test reference event not found") + if len(testCases) > 0 { + t.Errorf("Test reference events not found: %v\n\n got: %v", testCases, events) + } } -func testValue(t *testing.T, event common.MapStr, field string, expected interface{}) { +func testValue(eventKey string, t *testing.T, event common.MapStr, field string, expected interface{}) { data, err := event.GetValue(field) - assert.NoError(t, err, "Could not read field "+field) - assert.EqualValues(t, expected, data, "Wrong value for field "+field) + assert.NoError(t, err, eventKey+": Could not read field "+field) + assert.EqualValues(t, expected, data, eventKey+": Wrong value for field "+field) +} + +// Test cases built to match 3 examples in 'module/kubernetes/_meta/test/kube-state-metrics'. +// In particular, test same named pods in different namespaces +func testCases() map[string]map[string]interface{} { + return map[string]map[string]interface{}{ + "default@jumpy-owl-redis-3481028193-s78x9": { + "_namespace": "pod", + "_module.namespace": "default", + "_module.node.name": "minikube", + "name": "jumpy-owl-redis-3481028193-s78x9", + + "host_ip": "192.168.99.100", + "ip": "172.17.0.4", + + "status.phase": "succeeded", + "status.ready": "false", + "status.scheduled": "true", + }, + "test@jumpy-owl-redis-3481028193-s78x9": { + "_namespace": "pod", + "_module.namespace": "test", + "_module.node.name": "minikube-test", + "name": "jumpy-owl-redis-3481028193-s78x9", + + "host_ip": "192.168.99.200", + "ip": "172.17.0.5", + + "status.phase": "running", + "status.ready": "true", + "status.scheduled": "false", + }, + "jenkins@wise-lynx-jenkins-1616735317-svn6k": { + "_namespace": "pod", + "_module.namespace": "jenkins", + "_module.node.name": "minikube", + "name": "wise-lynx-jenkins-1616735317-svn6k", + + "host_ip": "192.168.99.100", + "ip": "172.17.0.7", + + "status.phase": "running", + "status.ready": "true", + "status.scheduled": "true", + }, + } } diff --git a/metricbeat/module/kubernetes/state_replicaset/data.go b/metricbeat/module/kubernetes/state_replicaset/data.go index 16bddcd9fa1e..b4e82bcf0d04 100644 --- a/metricbeat/module/kubernetes/state_replicaset/data.go +++ b/metricbeat/module/kubernetes/state_replicaset/data.go @@ -16,11 +16,14 @@ func eventMapping(families []*dto.MetricFamily) ([]common.MapStr, error) { if replicaset == "" { continue } - event, ok := eventsMap[replicaset] + namespace := util.GetLabel(metric, "namespace") + replicasetKey := namespace + "::" + replicaset + event, ok := eventsMap[replicasetKey] if !ok { event = common.MapStr{} - eventsMap[replicaset] = event + eventsMap[replicasetKey] = event } + switch family.GetName() { case "kube_replicaset_metadata_generation": event.Put(mb.ModuleDataKey+".namespace", util.GetLabel(metric, "namespace")) @@ -50,7 +53,8 @@ func eventMapping(families []*dto.MetricFamily) ([]common.MapStr, error) { } } - var events []common.MapStr + // initialize, populate events array from values in eventsMap + events := make([]common.MapStr, 0, len(eventsMap)) for _, event := range eventsMap { events = append(events, event) } diff --git a/metricbeat/module/kubernetes/state_replicaset/state_replicaset_test.go b/metricbeat/module/kubernetes/state_replicaset/state_replicaset_test.go index 802419e932ba..1cef891aa6c5 100644 --- a/metricbeat/module/kubernetes/state_replicaset/state_replicaset_test.go +++ b/metricbeat/module/kubernetes/state_replicaset/state_replicaset_test.go @@ -44,34 +44,70 @@ func TestEventMapping(t *testing.T) { events, err := f.Fetch() assert.NoError(t, err) - assert.Equal(t, 4, len(events), "Wrong number of returned events") - - testCases := map[string]interface{}{ - "_module.namespace": "kube-system", - "name": "kube-state-metrics-1303537707", - - "replicas.labeled": 2, - "replicas.observed": 1, - "replicas.ready": 1, - "replicas.available": 2, - "replicas.desired": 2, - } + assert.Equal(t, 5, len(events), "Wrong number of returned events") + testCases := testCases() for _, event := range events { name, err := event.GetValue("name") - if err == nil && name == "kube-state-metrics-1303537707" { - for k, v := range testCases { - testValue(t, event, k, v) + if err == nil { + namespace, err := event.GetValue("_module.namespace") + if err == nil { + eventKey := namespace.(string) + "@" + name.(string) + oneTestCase, oneTestCaseFound := testCases[eventKey] + if oneTestCaseFound { + for k, v := range oneTestCase { + testValue(eventKey, t, event, k, v) + } + delete(testCases, eventKey) + } } - return } } - t.Error("Test reference event not found") + if len(testCases) > 0 { + t.Errorf("Test reference events not found: %v", testCases) + } } -func testValue(t *testing.T, event common.MapStr, field string, expected interface{}) { +func testValue(eventKey string, t *testing.T, event common.MapStr, field string, expected interface{}) { data, err := event.GetValue(field) - assert.NoError(t, err, "Could not read field "+field) - assert.EqualValues(t, expected, data, "Wrong value for field "+field) + assert.NoError(t, err, eventKey+": Could not read field "+field) + assert.EqualValues(t, expected, data, eventKey+": Wrong value for field "+field) +} + +// Test cases built to match 3 examples in 'module/kubernetes/_meta/test/kube-state-metrics'. +// In particular, test same named replica sets in different namespaces +func testCases() map[string]map[string]interface{} { + return map[string]map[string]interface{}{ + "kube-system@kube-state-metrics-1303537707": { + "_module.namespace": "kube-system", + "name": "kube-state-metrics-1303537707", + + "replicas.labeled": 2, + "replicas.observed": 1, + "replicas.ready": 1, + "replicas.available": 2, + "replicas.desired": 2, + }, + "test@kube-state-metrics-1303537707": { + "_module.namespace": "test", + "name": "kube-state-metrics-1303537707", + + "replicas.labeled": 4, + "replicas.observed": 5, + "replicas.ready": 6, + "replicas.available": 7, + "replicas.desired": 3, + }, + "kube-system@tiller-deploy-3067024529": { + "_module.namespace": "kube-system", + "name": "tiller-deploy-3067024529", + + "replicas.labeled": 1, + "replicas.observed": 1, + "replicas.ready": 1, + "replicas.available": 1, + "replicas.desired": 1, + }, + } }