From 65bc62af5c3c4571d9f4910d60a9c1d613464740 Mon Sep 17 00:00:00 2001 From: Sylvain Rabot Date: Thu, 29 Apr 2021 15:38:59 +0200 Subject: [PATCH 1/9] Add kube_*_annotations metrics Signed-off-by: Sylvain Rabot --- docs/certificatessigningrequest-metrics.md | 1 + docs/cli-arguments.md | 1 + docs/cronjob-metrics.md | 1 + docs/daemonset-metrics.md | 1 + docs/deployment-metrics.md | 1 + docs/endpoint-metrics.md | 1 + docs/horizontalpodautoscaler-metrics.md | 1 + docs/ingress-metrics.md | 1 + docs/job-metrics.md | 1 + docs/networkpolicy-metrics.md | 1 + docs/node-metrics.md | 1 + docs/persistentvolume-metrics.md | 1 + docs/persistentvolumeclaim-metrics.md | 1 + docs/pod-metrics.md | 1 + docs/replicaset-metrics.md | 1 + docs/secret-metrics.md | 1 + docs/service-metrics.md | 1 + docs/statefulset-metrics.md | 1 + docs/storageclass-metrics.md | 1 + docs/verticalpodautoscaler-metrics.md | 1 + internal/store/builder.go | 72 ++++++++++--------- internal/store/certificatesigningrequest.go | 22 +++++- .../store/certificatesigningrequest_test.go | 4 +- internal/store/cronjob.go | 22 +++++- internal/store/cronjob_test.go | 4 +- internal/store/daemonset.go | 22 +++++- internal/store/daemonset_test.go | 4 +- internal/store/deployment.go | 22 +++++- internal/store/deployment_test.go | 14 +++- internal/store/endpoint.go | 22 +++++- internal/store/endpoint_test.go | 20 ++++-- internal/store/horizontalpodautoscaler.go | 22 +++++- .../store/horizontalpodautoscaler_test.go | 4 +- internal/store/ingress.go | 22 +++++- internal/store/ingress_test.go | 4 +- internal/store/job.go | 22 +++++- internal/store/job_test.go | 10 ++- internal/store/namespace.go | 22 +++++- internal/store/namespace_test.go | 11 ++- internal/store/networkpolicy.go | 28 +++++++- internal/store/networkpolicy_test.go | 2 +- internal/store/node.go | 26 ++++++- internal/store/node_test.go | 4 +- internal/store/persistentvolume.go | 22 +++++- internal/store/persistentvolume_test.go | 4 +- internal/store/persistentvolumeclaim.go | 10 +-- internal/store/persistentvolumeclaim_test.go | 4 +- internal/store/pod.go | 23 +++++- internal/store/pod_test.go | 28 +++++++- internal/store/replicaset.go | 22 +++++- internal/store/replicaset_test.go | 10 ++- internal/store/secret.go | 23 +++++- internal/store/secret_test.go | 4 +- internal/store/service.go | 19 ++++- internal/store/service_test.go | 15 +++- internal/store/statefulset.go | 22 +++++- internal/store/statefulset_test.go | 4 +- internal/store/storageclass.go | 22 +++++- internal/store/storageclass_test.go | 4 +- internal/store/testutils.go | 13 ++-- internal/store/utils.go | 24 +++++++ internal/store/verticalpodautoscaler.go | 22 +++++- internal/store/verticalpodautoscaler_test.go | 4 +- main.go | 1 + main_test.go | 6 +- pkg/options/options.go | 47 ++++++------ 66 files changed, 648 insertions(+), 130 deletions(-) diff --git a/docs/certificatessigningrequest-metrics.md b/docs/certificatessigningrequest-metrics.md index 52548ab535..a5f195464e 100644 --- a/docs/certificatessigningrequest-metrics.md +++ b/docs/certificatessigningrequest-metrics.md @@ -2,6 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | +| kube_certificatesigningrequest_annotations | Gauge | `certificatesigningrequest`=<certificatesigningrequest-name>| STABLE | | kube_certificatesigningrequest_created| Gauge | `certificatesigningrequest`=<certificatesigningrequest-name>| STABLE | | kube_certificatesigningrequest_condition | Gauge | `certificatesigningrequest`=<certificatesigningrequest-name>
`condition`=<approved\|denied> | STABLE | | kube_certificatesigningrequest_labels | Gauge | `certificatesigningrequest`=<certificatesigningrequest-name>| STABLE | diff --git a/docs/cli-arguments.md b/docs/cli-arguments.md index 5ace27edd5..efcd0bd903 100644 --- a/docs/cli-arguments.md +++ b/docs/cli-arguments.md @@ -39,6 +39,7 @@ Usage of ./kube-state-metrics: --logtostderr log to standard error instead of files (default true) --metric-allowlist string Comma-separated list of metrics to be exposed. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive. --metric-denylist string Comma-separated list of metrics not to be enabled. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive. + --metric-annotations-allowlist string Comma-separated list of additional Kubernetes annotations keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional annotations provide a list of resource names in their plural form and Kubernetes annotations keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any annotation, but that has severe performance implications (Example: '=pods=[*]'). --metric-labels-allowlist string Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional labels provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any labels, but that has severe performance implications (Example: '=pods=[*]'). --namespaces string Comma-separated list of namespaces to be enabled. Defaults to "" --one_output If true, only write logs to their native severity level (vs also writing to each lower severity level) diff --git a/docs/cronjob-metrics.md b/docs/cronjob-metrics.md index b7d4d5b07e..3d5100cd3b 100644 --- a/docs/cronjob-metrics.md +++ b/docs/cronjob-metrics.md @@ -2,6 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | +| kube_cronjob_annotations | Gauge | `cronjob`=<cronjob-name>
`namespace`=<cronjob-namespace>
`annotation_CRONJOB_LABEL`=<CRONJOB_ANNOTATION> | STABLE | kube_cronjob_info | Gauge | `cronjob`=<cronjob-name>
`namespace`=<cronjob-namespace>
`schedule`=<schedule>
`concurrency_policy`=<concurrency-policy> | STABLE | kube_cronjob_labels | Gauge | `cronjob`=<cronjob-name>
`namespace`=<cronjob-namespace>
`label_CRONJOB_LABEL`=<CRONJOB_LABEL> | STABLE | kube_cronjob_created | Gauge | `cronjob`=<cronjob-name>
`namespace`=<cronjob-namespace> | STABLE diff --git a/docs/daemonset-metrics.md b/docs/daemonset-metrics.md index d95f63101f..bb80159650 100644 --- a/docs/daemonset-metrics.md +++ b/docs/daemonset-metrics.md @@ -2,6 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | +| kube_daemonset_annotations | Gauge | `daemonset`=<daemonset-name>
`namespace`=<daemonset-namespace>
`annotation_DAEMONSET_ANNOTATION`=<DAEMONSET_ANNOTATION> | STABLE | | kube_daemonset_created | Gauge | `daemonset`=<daemonset-name>
`namespace`=<daemonset-namespace> | STABLE | | kube_daemonset_status_current_number_scheduled | Gauge | `daemonset`=<daemonset-name>
`namespace`=<daemonset-namespace> | STABLE | | kube_daemonset_status_desired_number_scheduled | Gauge | `daemonset`=<daemonset-name>
`namespace`=<daemonset-namespace> | STABLE | diff --git a/docs/deployment-metrics.md b/docs/deployment-metrics.md index 4c7ca99339..8b3ef5810f 100644 --- a/docs/deployment-metrics.md +++ b/docs/deployment-metrics.md @@ -2,6 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | +| kube_deployment_annotations | Gauge | `deployment`=<deployment-name>
`namespace`=<deployment-namespace>
`annotation_DEPLOYMENT_ANNOTATION`=<DEPLOYMENT_ANNOTATION> | STABLE | | kube_deployment_status_replicas | Gauge | `deployment`=<deployment-name>
`namespace`=<deployment-namespace> | STABLE | | kube_deployment_status_replicas_available | Gauge | `deployment`=<deployment-name>
`namespace`=<deployment-namespace> | STABLE | | kube_deployment_status_replicas_unavailable | Gauge | `deployment`=<deployment-name>
`namespace`=<deployment-namespace> | STABLE | diff --git a/docs/endpoint-metrics.md b/docs/endpoint-metrics.md index 2e0b416030..746c832681 100644 --- a/docs/endpoint-metrics.md +++ b/docs/endpoint-metrics.md @@ -2,6 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | +| kube_endpoint_annotations | Gauge | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace>
`annotation_ENDPOINT_LABEL`=<ENDPOINT_ANNOTATION> | STABLE | | kube_endpoint_address_not_ready | Gauge | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace> | STABLE | | kube_endpoint_address_available | Gauge | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace> | STABLE | | kube_endpoint_info | Gauge | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace> | STABLE | diff --git a/docs/horizontalpodautoscaler-metrics.md b/docs/horizontalpodautoscaler-metrics.md index 5c603598ff..d8116f8691 100644 --- a/docs/horizontalpodautoscaler-metrics.md +++ b/docs/horizontalpodautoscaler-metrics.md @@ -2,6 +2,7 @@ | Metric name | Metric type | Labels/tags | Status | | -------------------------------- | ----------- | ------------------------------------------------------------- | ------ | +| kube_horizontalpodautoscaler_annotations | Gauge | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | STABLE | | kube_horizontalpodautoscaler_labels | Gauge | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | STABLE | | kube_horizontalpodautoscaler_metadata_generation | Gauge | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | STABLE | | kube_horizontalpodautoscaler_spec_max_replicas | Gauge | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | STABLE | diff --git a/docs/ingress-metrics.md b/docs/ingress-metrics.md index cfd9643d6a..e00fc05aa5 100644 --- a/docs/ingress-metrics.md +++ b/docs/ingress-metrics.md @@ -2,6 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | +| kube_ingress_annotations | Gauge | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`annotation_INGRESS_LABEL`=<ANNOTATION_LABEL> | STABLE | | kube_ingress_info | Gauge | `ingress`=<ingress-name>
`namespace`=<ingress-namespace> | STABLE | | kube_ingress_labels | Gauge | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`label_INGRESS_LABEL`=<INGRESS_LABEL> | STABLE | | kube_ingress_created | Gauge | `ingress`=<ingress-name>
`namespace`=<ingress-namespace> | STABLE | diff --git a/docs/job-metrics.md b/docs/job-metrics.md index d0ec58ce60..9d28610881 100644 --- a/docs/job-metrics.md +++ b/docs/job-metrics.md @@ -2,6 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | +| kube_job_annotations | Gauge | `job_name`=<job-name>
`namespace`=<job-namespace>
`annotation_JOB_LABEL`=<JOB_ANNOTATION> | STABLE | | kube_job_info | Gauge | `job_name`=<job-name>
`namespace`=<job-namespace> | STABLE | | kube_job_labels | Gauge | `job_name`=<job-name>
`namespace`=<job-namespace>
`label_JOB_LABEL`=<JOB_LABEL> | STABLE | | kube_job_owner | Gauge | `job_name`=<job-name>
`namespace`=<job-namespace>
`owner_kind`=<owner kind>
`owner_name`=<owner name>
`owner_is_controller`=<whether owner is controller> | STABLE | diff --git a/docs/networkpolicy-metrics.md b/docs/networkpolicy-metrics.md index 2a023d46c7..c5fa1f64f0 100644 --- a/docs/networkpolicy-metrics.md +++ b/docs/networkpolicy-metrics.md @@ -3,6 +3,7 @@ | Metric name | Metric type | Labels/tags | Status | | ------------------------------------- | ----------- | ------------------------------------------------------------------------------ | ------------ | +| kube_networkpolicy_annotations | Gauge | `namespace`=<namespace name> `networkpolicy`=<networkpolicy name> | EXPERIMENTAL | | kube_networkpolicy_created | Gauge | `namespace`=<namespace name> `networkpolicy`=<networkpolicy name> | EXPERIMENTAL | | kube_networkpolicy_labels | Gauge | `namespace`=<namespace name> `networkpolicy`=<networkpolicy name> | EXPERIMENTAL | | kube_networkpolicy_spec_egress_rules | Gauge | `namespace`=<namespace name> `networkpolicy`=<networkpolicy name> | EXPERIMENTAL | diff --git a/docs/node-metrics.md b/docs/node-metrics.md index 448e836f41..a4b7c9a11d 100644 --- a/docs/node-metrics.md +++ b/docs/node-metrics.md @@ -2,6 +2,7 @@ | Metric name| Metric type | Description | Unit (where applicable) | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------------------- | ----------- | ------ | +| kube_node_annotations | Gauge | Kubernetes annotations converted to Prometheus labels | | `node`=<node-address>
`annotation_NODE_LABEL`=<NODE_ANNOTATION> | STABLE | | kube_node_info | Gauge | Information about a cluster node| |`node`=<node-address>
`kernel_version`=<kernel-version>
`os_image`=<os-image-name>
`container_runtime_version`=<container-runtime-and-version-combination>
`kubelet_version`=<kubelet-version>
`kubeproxy_version`=<kubeproxy-version>
`pod_cidr`=<pod-cidr>
`provider_id`=<provider-id>
`internal_ip`=<internal-ip> | STABLE | | kube_node_labels | Gauge | Kubernetes labels converted to Prometheus labels | | `node`=<node-address>
`label_NODE_LABEL`=<NODE_LABEL> | STABLE | | kube_node_role | Gauge | The role of a cluster node | | `node`=<node-address>
`role`=<NODE_ROLE> | EXPERIMENTAL | diff --git a/docs/persistentvolume-metrics.md b/docs/persistentvolume-metrics.md index 18624cf76a..b16fccc483 100644 --- a/docs/persistentvolume-metrics.md +++ b/docs/persistentvolume-metrics.md @@ -2,6 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | +| kube_persistentvolume_annotations | Gauge | `persistentvolume`=<persistentvolume-name>
`annotation_PERSISTENTVOLUME_LABEL`=<PERSISTENTVOLUME_ANNOTATION> | STABLE | | kube_persistentvolume_capacity_bytes | Gauge | `persistentvolume`=<pv-name> | STABLE | | kube_persistentvolume_status_phase | Gauge | `persistentvolume`=<pv-name>
`phase`=<Bound\|Failed\|Pending\|Available\|Released>| STABLE | | kube_persistentvolume_claim_ref | Gauge | `persistentvolume`=<pv-name>
`claim_namespace`=<>
`name`=<> | STABLE | diff --git a/docs/persistentvolumeclaim-metrics.md b/docs/persistentvolumeclaim-metrics.md index 40025b2ca2..14a367c4fc 100644 --- a/docs/persistentvolumeclaim-metrics.md +++ b/docs/persistentvolumeclaim-metrics.md @@ -2,6 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | +| kube_persistentvolumeclaim_annotations | Gauge | `persistentvolumeclaim`=<persistentvolumeclaim-name>
`namespace`=<persistentvolumeclaim-namespace>
`annotation_PERSISTENTVOLUMECLAIM_LABEL`=<PERSISTENTVOLUMECLAIM_ANNOATION> | STABLE | | kube_persistentvolumeclaim_access_mode | Gauge | `access_mode`=<persistentvolumeclaim-access-mode>
`namespace`=<persistentvolumeclaim-namespace>
`persistentvolumeclaim`=<persistentvolumeclaim-name> | STABLE | | kube_persistentvolumeclaim_info | Gauge | `namespace`=<persistentvolumeclaim-namespace>
`persistentvolumeclaim`=<persistentvolumeclaim-name>
`storageclass`=<persistentvolumeclaim-storageclassname>
`volumename`=<volumename> | STABLE | | kube_persistentvolumeclaim_labels | Gauge | `persistentvolumeclaim`=<persistentvolumeclaim-name>
`namespace`=<persistentvolumeclaim-namespace>
`label_PERSISTENTVOLUMECLAIM_LABEL`=<PERSISTENTVOLUMECLAIM_LABEL> | STABLE | diff --git a/docs/pod-metrics.md b/docs/pod-metrics.md index 1d1db19d0d..e5a0ce1090 100644 --- a/docs/pod-metrics.md +++ b/docs/pod-metrics.md @@ -2,6 +2,7 @@ | Metric name| Metric type | Description | Unit (where applicable) | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------------------- | ----------- | ------ | +| kube_pod_annotations | Gauge | Kubernetes annotations converted to Prometheus labels | | `pod`=<pod-name>
`namespace`=<pod-namespace>
`annotation_POD_LABEL`=<POD_ANNOTATION>
`uid`=<pod-uid> | STABLE | | kube_pod_info | Gauge | Information about pod | | `pod`=<pod-name>
`namespace`=<pod-namespace>
`host_ip`=<host-ip>
`pod_ip`=<pod-ip>
`node`=<node-name>
`created_by_kind`=<created_by_kind>
`created_by_name`=<created_by_name>
`uid`=<pod-uid>
`priority_class`=<priority_class>
`host_network`=<host_network>| STABLE | | kube_pod_start_time | Gauge | Start time in unix timestamp for a pod | seconds | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | STABLE | | kube_pod_completion_time | Gauge | Completion time in unix timestamp for a pod | seconds | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | STABLE | diff --git a/docs/replicaset-metrics.md b/docs/replicaset-metrics.md index ab2e3d16f0..744a7aca4e 100644 --- a/docs/replicaset-metrics.md +++ b/docs/replicaset-metrics.md @@ -2,6 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | +| kube_replicaset_annotations | Gauge | `replicaset`=<replicaset-name>
`namespace`=<replicaset-namespace>
`annotation_REPLICASET_LABEL`=<REPLICASET_ANNOTATION> | STABLE | | kube_replicaset_status_replicas | Gauge | `replicaset`=<replicaset-name>
`namespace`=<replicaset-namespace> | STABLE | | kube_replicaset_status_fully_labeled_replicas | Gauge | `replicaset`=<replicaset-name>
`namespace`=<replicaset-namespace> | STABLE | | kube_replicaset_status_ready_replicas | Gauge | `replicaset`=<replicaset-name>
`namespace`=<replicaset-namespace> | STABLE | diff --git a/docs/secret-metrics.md b/docs/secret-metrics.md index 780df876de..16716faa04 100644 --- a/docs/secret-metrics.md +++ b/docs/secret-metrics.md @@ -2,6 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | +| kube_secret_annotations | Gauge | `secret`=<secret-name>
`namespace`=<secret-namespace>
`annotations_SECRET_LABEL`=<SECRET_ANNOTATION> | STABLE | | kube_secret_info | Gauge | `secret`=<secret-name>
`namespace`=<secret-namespace> | STABLE | | kube_secret_type | Gauge | `secret`=<secret-name>
`namespace`=<secret-namespace>
`type`=<secret-type> | STABLE | | kube_secret_labels | Gauge | `secret`=<secret-name>
`namespace`=<secret-namespace>
`label_SECRET_LABEL`=<SECRET_LABEL> | STABLE | diff --git a/docs/service-metrics.md b/docs/service-metrics.md index fa2044e657..1883ac55d3 100644 --- a/docs/service-metrics.md +++ b/docs/service-metrics.md @@ -2,6 +2,7 @@ | Metric name| Metric type | Description | Unit (where applicable) | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------------------- | ----------- | ------ | +| kube_service_annoations | Gauge | Kubernetes annotations converted to Prometheus labels | |`service`=<service-name>
`namespace`=<service-namespace>
`annotation_SERVICE_LABEL`=<SERVICE_ANNOTATION> | STABLE | | kube_service_info | Gauge | Information about service | |`service`=<service-name>
`namespace`=<service-namespace>
`cluster_ip`=<service cluster ip>
`external_name`=<service external name>
`load_balancer_ip`=<service load balancer ip> | STABLE | | kube_service_labels | Gauge | Kubernetes labels converted to Prometheus labels | |`service`=<service-name>
`namespace`=<service-namespace>
`label_SERVICE_LABEL`=<SERVICE_LABEL> | STABLE | | kube_service_created | Gauge | Unix creation timestamp | seconds |`service`=<service-name>
`namespace`=<service-namespace> | STABLE | diff --git a/docs/statefulset-metrics.md b/docs/statefulset-metrics.md index a1ac97196c..0054144a56 100644 --- a/docs/statefulset-metrics.md +++ b/docs/statefulset-metrics.md @@ -2,6 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | +| kube_statefulset_annotations | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace>
`annotation_STATEFULSET_LABEL`=<STATEFULSET_ANNOTATION> | STABLE | | kube_statefulset_status_replicas | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace> | STABLE | | kube_statefulset_status_replicas_current | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace> | STABLE | | kube_statefulset_status_replicas_ready | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace> | STABLE | diff --git a/docs/storageclass-metrics.md b/docs/storageclass-metrics.md index 184a92fa48..843330280f 100644 --- a/docs/storageclass-metrics.md +++ b/docs/storageclass-metrics.md @@ -2,6 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | +| kube_storageclass_annotations | Gauge | `storageclass`=<storageclass-name>
`annotation_STORAGECLASS_LABEL`=<STORAGECLASS_ANNOTATION> | STABLE | | kube_storageclass_info | Gauge | `storageclass`=<storageclass-name>
`provisioner`=<storageclass-provisioner>
`reclaim_policy`=<storageclass-reclaimPolicy>
`volume_binding_mode`=<storageclass-volumeBindingMode> | STABLE | | kube_storageclass_labels | Gauge | `storageclass`=<storageclass-name>
`label_STORAGECLASS_LABEL`=<STORAGECLASS_LABEL> | STABLE | | kube_storageclass_created | Gauge | `storageclass`=<storageclass-name> | STABLE | diff --git a/docs/verticalpodautoscaler-metrics.md b/docs/verticalpodautoscaler-metrics.md index 143d671e78..3077c2395c 100644 --- a/docs/verticalpodautoscaler-metrics.md +++ b/docs/verticalpodautoscaler-metrics.md @@ -2,6 +2,7 @@ | Metric name | Metric type | Labels/tags | Status | | -------------------------------- | ----------- | ------------------------------------------------------------- | ------ | +| kube_verticalpodautoscaler_annotations | Gauge | `annotation_app`=<foo>
`namespace`=<namespace>
`target_api_version`=<api version>
`target_kind`=<target kind>
`target_name`=<target name>
`verticalpodautoscaler`=<vertical pod autoscaler name> | EXPERIMENTAL | | kube_verticalpodautoscaler_spec_resourcepolicy_container_policies_minallowed | Gauge | `container`=<container name>
`namespace`=<namespace>
`resource`=<cpu memory>
`target_api_version`=<api version>
`target_kind`=<target kind>
`target_name`=<target name>
`unit`=<core byte>
`verticalpodautoscaler`=<vertical pod autoscaler name> | EXPERIMENTAL | | kube_verticalpodautoscaler_spec_resourcepolicy_container_policies_maxallowed | Gauge | `container`=<container name>
`namespace`=<namespace>
`resource`=<cpu memory>
`target_api_version`=<api version>
`target_kind`=<target kind>
`target_name`=<target name>
`unit`=<core byte>
`verticalpodautoscaler`=<vertical pod autoscaler name> | EXPERIMENTAL | | kube_verticalpodautoscaler_status_recommendation_containerrecommendations_lowerbound | Gauge | `container`=<container name>
`namespace`=<namespace>
`resource`=<cpu memory>
`target_api_version`=<api version>
`target_kind`=<target kind>
`target_name`=<target name>
`unit`=<core byte>
`verticalpodautoscaler`=<vertical pod autoscaler name> | EXPERIMENTAL | diff --git a/internal/store/builder.go b/internal/store/builder.go index 7a5844d870..27d7d1e781 100644 --- a/internal/store/builder.go +++ b/internal/store/builder.go @@ -54,18 +54,19 @@ import ( // Builder helps to build store. It follows the builder pattern // (https://en.wikipedia.org/wiki/Builder_pattern). type Builder struct { - kubeClient clientset.Interface - vpaClient vpaclientset.Interface - namespaces options.NamespaceList - ctx context.Context - enabledResources []string - allowDenyList ksmtypes.AllowDenyLister - listWatchMetrics *watch.ListWatchMetrics - shardingMetrics *sharding.Metrics - shard int32 - totalShards int - buildStoreFunc ksmtypes.BuildStoreFunc - allowLabelsList map[string][]string + kubeClient clientset.Interface + vpaClient vpaclientset.Interface + namespaces options.NamespaceList + ctx context.Context + enabledResources []string + allowDenyList ksmtypes.AllowDenyLister + listWatchMetrics *watch.ListWatchMetrics + shardingMetrics *sharding.Metrics + shard int32 + totalShards int + buildStoreFunc ksmtypes.BuildStoreFunc + allowAnnotationsList map[string][]string + allowLabelsList map[string][]string } // NewBuilder returns a new builder. @@ -143,6 +144,13 @@ func (b *Builder) DefaultGenerateStoreFunc() ksmtypes.BuildStoreFunc { return b.buildStore } +// WithAllowAnnotations configures which annotations can be returned for metrics +func (b *Builder) WithAllowAnnotations(annotations map[string][]string) { + if len(annotations) > 0 { + b.allowAnnotationsList = annotations + } +} + // WithAllowLabels configures which labels can be returned for metrics func (b *Builder) WithAllowLabels(labels map[string][]string) { if len(labels) > 0 { @@ -223,31 +231,31 @@ func (b *Builder) buildConfigMapStore() cache.Store { } func (b *Builder) buildCronJobStore() cache.Store { - return b.buildStoreFunc(cronJobMetricFamilies(b.allowLabelsList["cronjobs"]), &batchv1beta1.CronJob{}, createCronJobListWatch) + return b.buildStoreFunc(cronJobMetricFamilies(b.allowAnnotationsList["cronjobs"], b.allowLabelsList["cronjobs"]), &batchv1beta1.CronJob{}, createCronJobListWatch) } func (b *Builder) buildDaemonSetStore() cache.Store { - return b.buildStoreFunc(daemonSetMetricFamilies(b.allowLabelsList["daemonsets"]), &appsv1.DaemonSet{}, createDaemonSetListWatch) + return b.buildStoreFunc(daemonSetMetricFamilies(b.allowAnnotationsList["daemonsets"], b.allowLabelsList["daemonsets"]), &appsv1.DaemonSet{}, createDaemonSetListWatch) } func (b *Builder) buildDeploymentStore() cache.Store { - return b.buildStoreFunc(deploymentMetricFamilies(b.allowLabelsList["deployments"]), &appsv1.Deployment{}, createDeploymentListWatch) + return b.buildStoreFunc(deploymentMetricFamilies(b.allowAnnotationsList["deployments"], b.allowLabelsList["deployments"]), &appsv1.Deployment{}, createDeploymentListWatch) } func (b *Builder) buildEndpointsStore() cache.Store { - return b.buildStoreFunc(endpointMetricFamilies(b.allowLabelsList["endpoints"]), &v1.Endpoints{}, createEndpointsListWatch) + return b.buildStoreFunc(endpointMetricFamilies(b.allowAnnotationsList["endpoints"], b.allowLabelsList["endpoints"]), &v1.Endpoints{}, createEndpointsListWatch) } func (b *Builder) buildHPAStore() cache.Store { - return b.buildStoreFunc(hpaMetricFamilies(b.allowLabelsList["horizontalpodautoscalers"]), &autoscaling.HorizontalPodAutoscaler{}, createHPAListWatch) + return b.buildStoreFunc(hpaMetricFamilies(b.allowAnnotationsList["horizontalpodautoscalers"], b.allowLabelsList["horizontalpodautoscalers"]), &autoscaling.HorizontalPodAutoscaler{}, createHPAListWatch) } func (b *Builder) buildIngressStore() cache.Store { - return b.buildStoreFunc(ingressMetricFamilies(b.allowLabelsList["ingresses"]), &networkingv1.Ingress{}, createIngressListWatch) + return b.buildStoreFunc(ingressMetricFamilies(b.allowAnnotationsList["ingresses"], b.allowLabelsList["ingresses"]), &networkingv1.Ingress{}, createIngressListWatch) } func (b *Builder) buildJobStore() cache.Store { - return b.buildStoreFunc(jobMetricFamilies(b.allowLabelsList["jobs"]), &batchv1.Job{}, createJobListWatch) + return b.buildStoreFunc(jobMetricFamilies(b.allowAnnotationsList["jobs"], b.allowLabelsList["jobs"]), &batchv1.Job{}, createJobListWatch) } func (b *Builder) buildLimitRangeStore() cache.Store { @@ -259,23 +267,23 @@ func (b *Builder) buildMutatingWebhookConfigurationStore() cache.Store { } func (b *Builder) buildNamespaceStore() cache.Store { - return b.buildStoreFunc(namespaceMetricFamilies(b.allowLabelsList["namespaces"]), &v1.Namespace{}, createNamespaceListWatch) + return b.buildStoreFunc(namespaceMetricFamilies(b.allowAnnotationsList["namespaces"], b.allowLabelsList["namespaces"]), &v1.Namespace{}, createNamespaceListWatch) } func (b *Builder) buildNetworkPolicyStore() cache.Store { - return b.buildStoreFunc(networkPolicyMetricFamilies(b.allowLabelsList["networkpolicies"]), &networkingv1.NetworkPolicy{}, createNetworkPolicyListWatch) + return b.buildStoreFunc(networkPolicyMetricFamilies(b.allowAnnotationsList["networkpolicies"], b.allowLabelsList["networkpolicies"]), &networkingv1.NetworkPolicy{}, createNetworkPolicyListWatch) } func (b *Builder) buildNodeStore() cache.Store { - return b.buildStoreFunc(nodeMetricFamilies(b.allowLabelsList["nodes"]), &v1.Node{}, createNodeListWatch) + return b.buildStoreFunc(nodeMetricFamilies(b.allowAnnotationsList["nodes"], b.allowLabelsList["nodes"]), &v1.Node{}, createNodeListWatch) } func (b *Builder) buildPersistentVolumeClaimStore() cache.Store { - return b.buildStoreFunc(persistentVolumeClaimMetricFamilies(b.allowLabelsList["persistentvolumeclaims"]), &v1.PersistentVolumeClaim{}, createPersistentVolumeClaimListWatch) + return b.buildStoreFunc(persistentVolumeClaimMetricFamilies(b.allowAnnotationsList["persistentvolumeclaims"], b.allowLabelsList["persistentvolumeclaims"]), &v1.PersistentVolumeClaim{}, createPersistentVolumeClaimListWatch) } func (b *Builder) buildPersistentVolumeStore() cache.Store { - return b.buildStoreFunc(persistentVolumeMetricFamilies(b.allowLabelsList["persistentvolumes"]), &v1.PersistentVolume{}, createPersistentVolumeListWatch) + return b.buildStoreFunc(persistentVolumeMetricFamilies(b.allowAnnotationsList["persistentvolumes"], b.allowLabelsList["persistentvolumes"]), &v1.PersistentVolume{}, createPersistentVolumeListWatch) } func (b *Builder) buildPodDisruptionBudgetStore() cache.Store { @@ -283,7 +291,7 @@ func (b *Builder) buildPodDisruptionBudgetStore() cache.Store { } func (b *Builder) buildReplicaSetStore() cache.Store { - return b.buildStoreFunc(replicaSetMetricFamilies(b.allowLabelsList["replicasets"]), &appsv1.ReplicaSet{}, createReplicaSetListWatch) + return b.buildStoreFunc(replicaSetMetricFamilies(b.allowAnnotationsList["replicasets"], b.allowLabelsList["replicasets"]), &appsv1.ReplicaSet{}, createReplicaSetListWatch) } func (b *Builder) buildReplicationControllerStore() cache.Store { @@ -295,27 +303,27 @@ func (b *Builder) buildResourceQuotaStore() cache.Store { } func (b *Builder) buildSecretStore() cache.Store { - return b.buildStoreFunc(secretMetricFamilies(b.allowLabelsList["secrets"]), &v1.Secret{}, createSecretListWatch) + return b.buildStoreFunc(secretMetricFamilies(b.allowAnnotationsList["secrets"], b.allowLabelsList["secrets"]), &v1.Secret{}, createSecretListWatch) } func (b *Builder) buildServiceStore() cache.Store { - return b.buildStoreFunc(serviceMetricFamilies(b.allowLabelsList["services"]), &v1.Service{}, createServiceListWatch) + return b.buildStoreFunc(serviceMetricFamilies(b.allowAnnotationsList["services"], b.allowLabelsList["services"]), &v1.Service{}, createServiceListWatch) } func (b *Builder) buildStatefulSetStore() cache.Store { - return b.buildStoreFunc(statefulSetMetricFamilies(b.allowLabelsList["statefulsets"]), &appsv1.StatefulSet{}, createStatefulSetListWatch) + return b.buildStoreFunc(statefulSetMetricFamilies(b.allowAnnotationsList["statefulsets"], b.allowLabelsList["statefulsets"]), &appsv1.StatefulSet{}, createStatefulSetListWatch) } func (b *Builder) buildStorageClassStore() cache.Store { - return b.buildStoreFunc(storageClassMetricFamilies(b.allowLabelsList["storageclasses"]), &storagev1.StorageClass{}, createStorageClassListWatch) + return b.buildStoreFunc(storageClassMetricFamilies(b.allowAnnotationsList["storageclasses"], b.allowLabelsList["storageclasses"]), &storagev1.StorageClass{}, createStorageClassListWatch) } func (b *Builder) buildPodStore() cache.Store { - return b.buildStoreFunc(podMetricFamilies(b.allowLabelsList["pods"]), &v1.Pod{}, createPodListWatch) + return b.buildStoreFunc(podMetricFamilies(b.allowAnnotationsList["pods"], b.allowLabelsList["pods"]), &v1.Pod{}, createPodListWatch) } func (b *Builder) buildCsrStore() cache.Store { - return b.buildStoreFunc(csrMetricFamilies(b.allowLabelsList["certificatesigningrequests"]), &certv1.CertificateSigningRequest{}, createCSRListWatch) + return b.buildStoreFunc(csrMetricFamilies(b.allowAnnotationsList["certificatesigningrequests"], b.allowLabelsList["certificatesigningrequests"]), &certv1.CertificateSigningRequest{}, createCSRListWatch) } func (b *Builder) buildValidatingWebhookConfigurationStore() cache.Store { @@ -327,7 +335,7 @@ func (b *Builder) buildVolumeAttachmentStore() cache.Store { } func (b *Builder) buildVPAStore() cache.Store { - return b.buildStoreFunc(vpaMetricFamilies(b.allowLabelsList["verticalpodautoscalers"]), &vpaautoscaling.VerticalPodAutoscaler{}, createVPAListWatchFunc(b.vpaClient)) + return b.buildStoreFunc(vpaMetricFamilies(b.allowAnnotationsList["verticalpodautoscalers"], b.allowLabelsList["verticalpodautoscalers"]), &vpaautoscaling.VerticalPodAutoscaler{}, createVPAListWatchFunc(b.vpaClient)) } func (b *Builder) buildLeases() cache.Store { diff --git a/internal/store/certificatesigningrequest.go b/internal/store/certificatesigningrequest.go index 02452b013d..0583eb6845 100644 --- a/internal/store/certificatesigningrequest.go +++ b/internal/store/certificatesigningrequest.go @@ -31,13 +31,33 @@ import ( ) var ( + descCSRAnnotationsName = "kube_certificatesigningrequest_annotations" + descCSRAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descCSRLabelsName = "kube_certificatesigningrequest_labels" descCSRLabelsHelp = "Kubernetes labels converted to Prometheus labels." descCSRLabelsDefaultLabels = []string{"certificatesigningrequest"} ) -func csrMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func csrMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ + *generator.NewFamilyGenerator( + descCSRAnnotationsName, + descCSRAnnotationsHelp, + metric.Gauge, + "", + wrapCSRFunc(func(j *certv1.CertificateSigningRequest) *metric.Family { + annotationKeys, annotationValues := createAnnotationKeysValues(j.Annotations, allowAnnotationsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + }), + ), *generator.NewFamilyGenerator( descCSRLabelsName, descCSRLabelsHelp, diff --git a/internal/store/certificatesigningrequest_test.go b/internal/store/certificatesigningrequest_test.go index 5e5e7ec3c7..9618e3c3b4 100644 --- a/internal/store/certificatesigningrequest_test.go +++ b/internal/store/certificatesigningrequest_test.go @@ -212,8 +212,8 @@ func TestCsrStore(t *testing.T) { }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(csrMetricFamilies(nil)) - c.Headers = generator.ExtractMetricFamilyHeaders(csrMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(csrMetricFamilies(nil, nil)) + c.Headers = generator.ExtractMetricFamilyHeaders(csrMetricFamilies(nil, nil)) if err := c.run(); err != nil { t.Errorf("unexpected error when collecting result in %vth run:\n%s", i, err) } diff --git a/internal/store/cronjob.go b/internal/store/cronjob.go index ff8f6267cd..955903feba 100644 --- a/internal/store/cronjob.go +++ b/internal/store/cronjob.go @@ -34,13 +34,33 @@ import ( ) var ( + descCronJobAnnotationsName = "kube_cronjob_annotations" + descCronJobAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descCronJobLabelsName = "kube_cronjob_labels" descCronJobLabelsHelp = "Kubernetes labels converted to Prometheus labels." descCronJobLabelsDefaultLabels = []string{"namespace", "cronjob"} ) -func cronJobMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func cronJobMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ + *generator.NewFamilyGenerator( + descCronJobAnnotationsName, + descCronJobAnnotationsHelp, + metric.Gauge, + "", + wrapCronJobFunc(func(j *batchv1beta1.CronJob) *metric.Family { + annotationKeys, annotationValues := createLabelKeysValues(j.Annotations, allowLabelsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + }), + ), *generator.NewFamilyGenerator( descCronJobLabelsName, descCronJobLabelsHelp, diff --git a/internal/store/cronjob_test.go b/internal/store/cronjob_test.go index 919c6b7c94..c767c1d370 100644 --- a/internal/store/cronjob_test.go +++ b/internal/store/cronjob_test.go @@ -255,8 +255,8 @@ func TestCronJobStore(t *testing.T) { }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(cronJobMetricFamilies(nil)) - c.Headers = generator.ExtractMetricFamilyHeaders(cronJobMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(cronJobMetricFamilies(nil, nil)) + c.Headers = generator.ExtractMetricFamilyHeaders(cronJobMetricFamilies(nil, nil)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } diff --git a/internal/store/daemonset.go b/internal/store/daemonset.go index fc5886263b..8a76d58e06 100644 --- a/internal/store/daemonset.go +++ b/internal/store/daemonset.go @@ -31,12 +31,14 @@ import ( ) var ( + descDaemonSetAnnotationsName = "kube_daemonset_annotations" + descDaemonSetAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descDaemonSetLabelsName = "kube_daemonset_labels" descDaemonSetLabelsHelp = "Kubernetes labels converted to Prometheus labels." descDaemonSetLabelsDefaultLabels = []string{"namespace", "daemonset"} ) -func daemonSetMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func daemonSetMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ *generator.NewFamilyGenerator( "kube_daemonset_created", @@ -210,6 +212,24 @@ func daemonSetMetricFamilies(allowLabelsList []string) []generator.FamilyGenerat } }), ), + *generator.NewFamilyGenerator( + descDaemonSetAnnotationsName, + descDaemonSetAnnotationsHelp, + metric.Gauge, + "", + wrapDaemonSetFunc(func(d *v1.DaemonSet) *metric.Family { + annotationKeys, annotationValues := createAnnotationKeysValues(d.Annotations, allowLabelsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + }), + ), *generator.NewFamilyGenerator( descDaemonSetLabelsName, descDaemonSetLabelsHelp, diff --git a/internal/store/daemonset_test.go b/internal/store/daemonset_test.go index 20709f7ae6..5a9bb2faa0 100644 --- a/internal/store/daemonset_test.go +++ b/internal/store/daemonset_test.go @@ -222,8 +222,8 @@ func TestDaemonSetStore(t *testing.T) { }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(daemonSetMetricFamilies(nil)) - c.Headers = generator.ExtractMetricFamilyHeaders(daemonSetMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(daemonSetMetricFamilies(nil, nil)) + c.Headers = generator.ExtractMetricFamilyHeaders(daemonSetMetricFamilies(nil, nil)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } diff --git a/internal/store/deployment.go b/internal/store/deployment.go index 41d17f55c8..6924d275dc 100644 --- a/internal/store/deployment.go +++ b/internal/store/deployment.go @@ -32,12 +32,14 @@ import ( ) var ( + descDeploymentAnnotationsName = "kube_deployment_annotations" + descDeploymentAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descDeploymentLabelsName = "kube_deployment_labels" descDeploymentLabelsHelp = "Kubernetes labels converted to Prometheus labels." descDeploymentLabelsDefaultLabels = []string{"namespace", "deployment"} ) -func deploymentMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func deploymentMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ *generator.NewFamilyGenerator( "kube_deployment_created", @@ -251,6 +253,24 @@ func deploymentMetricFamilies(allowLabelsList []string) []generator.FamilyGenera } }), ), + *generator.NewFamilyGenerator( + descDeploymentAnnotationsName, + descDeploymentAnnotationsHelp, + metric.Gauge, + "", + wrapDeploymentFunc(func(d *v1.Deployment) *metric.Family { + annotationKeys, annotationValues := createAnnotationKeysValues(d.Annotations, allowAnnotationsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + }), + ), *generator.NewFamilyGenerator( descDeploymentLabelsName, descDeploymentLabelsHelp, diff --git a/internal/store/deployment_test.go b/internal/store/deployment_test.go index c4b246fbd6..c59cfe153a 100644 --- a/internal/store/deployment_test.go +++ b/internal/store/deployment_test.go @@ -43,6 +43,8 @@ func TestDeploymentStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` + # HELP kube_deployment_annotations Kubernetes annotations converted to Prometheus labels. + # TYPE kube_deployment_annotations gauge # HELP kube_deployment_created Unix creation timestamp # TYPE kube_deployment_created gauge # HELP kube_deployment_metadata_generation Sequence number representing a specific generation of the desired state. @@ -72,11 +74,15 @@ func TestDeploymentStore(t *testing.T) { ` cases := []generateMetricsTestCase{ { + AllowAnnotationsList: []string{"company.io/team"}, Obj: &v1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: "depl1", CreationTimestamp: metav1.Time{Time: time.Unix(1500000000, 0)}, Namespace: "ns1", + Annotations: map[string]string{ + "company.io/team": "my-brilliant-team", + }, Labels: map[string]string{ "app": "example1", }, @@ -104,6 +110,7 @@ func TestDeploymentStore(t *testing.T) { }, }, Want: metadata + ` + kube_deployment_annotations{annotation_company_io_team="my-brilliant-team",deployment="depl1",namespace="ns1"} 1 kube_deployment_created{deployment="depl1",namespace="ns1"} 1.5e+09 kube_deployment_labels{deployment="depl1",namespace="ns1"} 1 kube_deployment_metadata_generation{deployment="depl1",namespace="ns1"} 21 @@ -158,7 +165,8 @@ func TestDeploymentStore(t *testing.T) { }, }, Want: metadata + ` - kube_deployment_labels{deployment="depl2",namespace="ns2"} 1 + kube_deployment_annotations{deployment="depl2",namespace="ns2"} 1 + kube_deployment_labels{deployment="depl2",namespace="ns2"} 1 kube_deployment_metadata_generation{deployment="depl2",namespace="ns2"} 14 kube_deployment_spec_paused{deployment="depl2",namespace="ns2"} 1 kube_deployment_spec_replicas{deployment="depl2",namespace="ns2"} 5 @@ -183,8 +191,8 @@ func TestDeploymentStore(t *testing.T) { } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(deploymentMetricFamilies(nil)) - c.Headers = generator.ExtractMetricFamilyHeaders(deploymentMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(deploymentMetricFamilies(c.AllowAnnotationsList, nil)) + c.Headers = generator.ExtractMetricFamilyHeaders(deploymentMetricFamilies(c.AllowAnnotationsList, nil)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } diff --git a/internal/store/endpoint.go b/internal/store/endpoint.go index f86ee654a0..a262985a7e 100644 --- a/internal/store/endpoint.go +++ b/internal/store/endpoint.go @@ -31,12 +31,14 @@ import ( ) var ( + descEndpointAnnotationsName = "kube_endpoint_annotations" + descEndpointAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descEndpointLabelsName = "kube_endpoint_labels" descEndpointLabelsHelp = "Kubernetes labels converted to Prometheus labels." descEndpointLabelsDefaultLabels = []string{"namespace", "endpoint"} ) -func endpointMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func endpointMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ *generator.NewFamilyGenerator( "kube_endpoint_info", @@ -73,6 +75,24 @@ func endpointMetricFamilies(allowLabelsList []string) []generator.FamilyGenerato } }), ), + *generator.NewFamilyGenerator( + descEndpointAnnotationsName, + descEndpointAnnotationsHelp, + metric.Gauge, + "", + wrapEndpointFunc(func(e *v1.Endpoints) *metric.Family { + annotationKeys, annotationValues := createAnnotationKeysValues(e.Annotations, allowAnnotationsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + }), + ), *generator.NewFamilyGenerator( descEndpointLabelsName, descEndpointLabelsHelp, diff --git a/internal/store/endpoint_test.go b/internal/store/endpoint_test.go index b1033ff93f..26f3afc933 100644 --- a/internal/store/endpoint_test.go +++ b/internal/store/endpoint_test.go @@ -30,6 +30,8 @@ func TestEndpointStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` + # HELP kube_endpoint_annotations Kubernetes annotations converted to Prometheus labels. + # TYPE kube_endpoint_annotations gauge # HELP kube_endpoint_address_available Number of addresses available in endpoint. # TYPE kube_endpoint_address_available gauge # HELP kube_endpoint_address_not_ready Number of addresses not ready in endpoint @@ -84,6 +86,7 @@ func TestEndpointStore(t *testing.T) { }, }, Want: metadata + ` + kube_endpoint_annotations{endpoint="test-endpoint",namespace="default"} 1 kube_endpoint_address_available{endpoint="test-endpoint",namespace="default"} 6 kube_endpoint_address_not_ready{endpoint="test-endpoint",namespace="default"} 6 kube_endpoint_created{endpoint="test-endpoint",namespace="default"} 1.5e+09 @@ -93,8 +96,8 @@ func TestEndpointStore(t *testing.T) { }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(endpointMetricFamilies(nil)) - c.Headers = generator.ExtractMetricFamilyHeaders(endpointMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(endpointMetricFamilies(nil, nil)) + c.Headers = generator.ExtractMetricFamilyHeaders(endpointMetricFamilies(nil, nil)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } @@ -109,6 +112,8 @@ func TestEndpointStoreWithLabels(t *testing.T) { # TYPE kube_endpoint_address_available gauge # HELP kube_endpoint_address_not_ready Number of addresses not ready in endpoint # TYPE kube_endpoint_address_not_ready gauge + # HELP kube_endpoint_annotations Kubernetes annotations converted to Prometheus labels. + # TYPE kube_endpoint_annotations gauge # HELP kube_endpoint_created Unix creation timestamp # TYPE kube_endpoint_created gauge # HELP kube_endpoint_info Information about endpoint. @@ -123,6 +128,9 @@ func TestEndpointStoreWithLabels(t *testing.T) { Name: "test-endpoint", CreationTimestamp: metav1.Time{Time: time.Unix(1500000000, 0)}, Namespace: "default", + Annotations: map[string]string{ + "app": "foobar", + }, Labels: map[string]string{ "app": "foobar", }, @@ -161,6 +169,7 @@ func TestEndpointStoreWithLabels(t *testing.T) { Want: metadata + ` kube_endpoint_address_available{endpoint="test-endpoint",namespace="default"} 6 kube_endpoint_address_not_ready{endpoint="test-endpoint",namespace="default"} 6 + kube_endpoint_annotations{endpoint="test-endpoint",annotation_app="foobar",namespace="default"} 1 kube_endpoint_created{endpoint="test-endpoint",namespace="default"} 1.5e+09 kube_endpoint_info{endpoint="test-endpoint",namespace="default"} 1 kube_endpoint_labels{endpoint="test-endpoint",label_app="foobar",namespace="default"} 1 @@ -168,11 +177,14 @@ func TestEndpointStoreWithLabels(t *testing.T) { }, } for i, c := range cases { + allowAnnotations := []string{ + "app", + } allowLabels := []string{ "app", } - c.Func = generator.ComposeMetricGenFuncs(endpointMetricFamilies(allowLabels)) - c.Headers = generator.ExtractMetricFamilyHeaders(endpointMetricFamilies(allowLabels)) + c.Func = generator.ComposeMetricGenFuncs(endpointMetricFamilies(allowAnnotations, allowLabels)) + c.Headers = generator.ExtractMetricFamilyHeaders(endpointMetricFamilies(allowAnnotations, allowLabels)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } diff --git a/internal/store/horizontalpodautoscaler.go b/internal/store/horizontalpodautoscaler.go index 55af5bcfb0..9582628af2 100644 --- a/internal/store/horizontalpodautoscaler.go +++ b/internal/store/horizontalpodautoscaler.go @@ -45,6 +45,8 @@ func (m metricTargetType) String() string { } var ( + descHorizontalPodAutoscalerAnnotationsName = "kube_horizontalpodautoscaler_annotations" + descHorizontalPodAutoscalerAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descHorizontalPodAutoscalerLabelsName = "kube_horizontalpodautoscaler_labels" descHorizontalPodAutoscalerLabelsHelp = "Kubernetes labels converted to Prometheus labels." descHorizontalPodAutoscalerLabelsDefaultLabels = []string{"namespace", "horizontalpodautoscaler"} @@ -52,7 +54,7 @@ var ( targetMetricLabels = []string{"metric_name", "metric_target_type"} ) -func hpaMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func hpaMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ *generator.NewFamilyGenerator( "kube_horizontalpodautoscaler_metadata_generation", @@ -192,6 +194,24 @@ func hpaMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { } }), ), + *generator.NewFamilyGenerator( + descHorizontalPodAutoscalerAnnotationsName, + descHorizontalPodAutoscalerAnnotationsHelp, + metric.Gauge, + "", + wrapHPAFunc(func(a *autoscaling.HorizontalPodAutoscaler) *metric.Family { + annotationKeys, annotationValues := createAnnotationKeysValues(a.Annotations, allowLabelsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + }), + ), *generator.NewFamilyGenerator( descHorizontalPodAutoscalerLabelsName, descHorizontalPodAutoscalerLabelsHelp, diff --git a/internal/store/horizontalpodautoscaler_test.go b/internal/store/horizontalpodautoscaler_test.go index 09e20ba468..a26e849f7a 100644 --- a/internal/store/horizontalpodautoscaler_test.go +++ b/internal/store/horizontalpodautoscaler_test.go @@ -309,8 +309,8 @@ func TestHPAStore(t *testing.T) { }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(hpaMetricFamilies(nil)) - c.Headers = generator.ExtractMetricFamilyHeaders(hpaMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(hpaMetricFamilies(nil, nil)) + c.Headers = generator.ExtractMetricFamilyHeaders(hpaMetricFamilies(nil, nil)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } diff --git a/internal/store/ingress.go b/internal/store/ingress.go index 85c0b001ee..137acf88b5 100644 --- a/internal/store/ingress.go +++ b/internal/store/ingress.go @@ -32,12 +32,14 @@ import ( ) var ( + descIngressAnnotationsName = "kube_ingress_annotations" + descIngressAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descIngressLabelsName = "kube_ingress_labels" descIngressLabelsHelp = "Kubernetes labels converted to Prometheus labels." descIngressLabelsDefaultLabels = []string{"namespace", "ingress"} ) -func ingressMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func ingressMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ *generator.NewFamilyGenerator( "kube_ingress_info", @@ -53,6 +55,24 @@ func ingressMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator }} }), ), + *generator.NewFamilyGenerator( + descIngressAnnotationsName, + descIngressAnnotationsHelp, + metric.Gauge, + "", + wrapIngressFunc(func(i *networkingv1.Ingress) *metric.Family { + annotationKeys, annotationValues := createAnnotationKeysValues(i.Annotations, allowLabelsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }} + + }), + ), *generator.NewFamilyGenerator( descIngressLabelsName, descIngressLabelsHelp, diff --git a/internal/store/ingress_test.go b/internal/store/ingress_test.go index 790c04807d..e4871943ab 100644 --- a/internal/store/ingress_test.go +++ b/internal/store/ingress_test.go @@ -169,8 +169,8 @@ func TestIngressStore(t *testing.T) { }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(ingressMetricFamilies(nil)) - c.Headers = generator.ExtractMetricFamilyHeaders(ingressMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(ingressMetricFamilies(nil, nil)) + c.Headers = generator.ExtractMetricFamilyHeaders(ingressMetricFamilies(nil, nil)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } diff --git a/internal/store/job.go b/internal/store/job.go index 5cf2ab74b6..b042f1ffd7 100644 --- a/internal/store/job.go +++ b/internal/store/job.go @@ -32,14 +32,34 @@ import ( ) var ( + descJobAnnotationsName = "kube_job_annotations" + descJobAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descJobLabelsName = "kube_job_labels" descJobLabelsHelp = "Kubernetes labels converted to Prometheus labels." descJobLabelsDefaultLabels = []string{"namespace", "job_name"} jobFailureReasons = []string{"BackoffLimitExceeded", "DeadLineExceeded", "Evicted"} ) -func jobMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func jobMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ + *generator.NewFamilyGenerator( + descJobAnnotationsName, + descJobAnnotationsHelp, + metric.Gauge, + "", + wrapJobFunc(func(j *v1batch.Job) *metric.Family { + annotationKeys, annotationValues := createAnnotationKeysValues(j.Annotations, allowAnnotationsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + }), + ), *generator.NewFamilyGenerator( descJobLabelsName, descJobLabelsHelp, diff --git a/internal/store/job_test.go b/internal/store/job_test.go index c81de4f15a..3cfb68ef70 100644 --- a/internal/store/job_test.go +++ b/internal/store/job_test.go @@ -48,6 +48,8 @@ func TestJobStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` + # HELP kube_job_annotations Kubernetes annotations converted to Prometheus labels. + # TYPE kube_job_annotations gauge # HELP kube_job_created Unix creation timestamp # TYPE kube_job_created gauge # HELP kube_job_owner Information about the Job's owner. @@ -110,6 +112,7 @@ func TestJobStore(t *testing.T) { }, }, Want: metadata + ` + kube_job_annotations{job_name="RunningJob1",namespace="ns1"} 1 kube_job_owner{job_name="RunningJob1",namespace="ns1",owner_is_controller="true",owner_kind="CronJob",owner_name="cronjob-name"} 1 kube_job_created{job_name="RunningJob1",namespace="ns1"} 1.5e+09 kube_job_info{job_name="RunningJob1",namespace="ns1"} 1 @@ -150,6 +153,7 @@ func TestJobStore(t *testing.T) { }, }, Want: metadata + ` + kube_job_annotations{job_name="SuccessfulJob1",namespace="ns1"} 1 kube_job_owner{job_name="SuccessfulJob1",namespace="ns1",owner_is_controller="",owner_kind="",owner_name=""} 1 kube_job_complete{condition="false",job_name="SuccessfulJob1",namespace="ns1"} 0 kube_job_complete{condition="true",job_name="SuccessfulJob1",namespace="ns1"} 1 @@ -193,6 +197,7 @@ func TestJobStore(t *testing.T) { }, }, Want: metadata + ` + kube_job_annotations{job_name="FailedJob1",namespace="ns1"} 1 kube_job_owner{job_name="FailedJob1",namespace="ns1",owner_is_controller="",owner_kind="",owner_name=""} 1 kube_job_failed{condition="false",job_name="FailedJob1",namespace="ns1"} 0 kube_job_failed{condition="true",job_name="FailedJob1",namespace="ns1"} 1 @@ -242,6 +247,7 @@ func TestJobStore(t *testing.T) { kube_job_complete{condition="false",job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 0 kube_job_complete{condition="true",job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 1 + kube_job_annotations{job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 1 kube_job_complete{condition="unknown",job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 0 kube_job_info{job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 1 kube_job_labels{job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 1 @@ -256,8 +262,8 @@ func TestJobStore(t *testing.T) { }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(jobMetricFamilies(nil)) - c.Headers = generator.ExtractMetricFamilyHeaders(jobMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(jobMetricFamilies(nil, nil)) + c.Headers = generator.ExtractMetricFamilyHeaders(jobMetricFamilies(nil, nil)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } diff --git a/internal/store/namespace.go b/internal/store/namespace.go index c1e994f543..5d256c13d8 100644 --- a/internal/store/namespace.go +++ b/internal/store/namespace.go @@ -31,12 +31,14 @@ import ( ) var ( + descNamespaceAnnotationsName = "kube_namespace_annotations" + descNamespaceAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descNamespaceLabelsName = "kube_namespace_labels" descNamespaceLabelsHelp = "Kubernetes labels converted to Prometheus labels." descNamespaceLabelsDefaultLabels = []string{"namespace"} ) -func namespaceMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func namespaceMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ *generator.NewFamilyGenerator( "kube_namespace_created", @@ -56,6 +58,24 @@ func namespaceMetricFamilies(allowLabelsList []string) []generator.FamilyGenerat } }), ), + *generator.NewFamilyGenerator( + descNamespaceAnnotationsName, + descNamespaceAnnotationsHelp, + metric.Gauge, + "", + wrapNamespaceFunc(func(n *v1.Namespace) *metric.Family { + annotationKeys, annotationValues := createAnnotationKeysValues(n.Annotations, allowAnnotationsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + }), + ), *generator.NewFamilyGenerator( descNamespaceLabelsName, descNamespaceLabelsHelp, diff --git a/internal/store/namespace_test.go b/internal/store/namespace_test.go index 1849ff665e..f550ed0e1e 100644 --- a/internal/store/namespace_test.go +++ b/internal/store/namespace_test.go @@ -30,6 +30,8 @@ func TestNamespaceStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` + # HELP kube_namespace_annotations Kubernetes annotations converted to Prometheus labels. + # TYPE kube_namespace_annotations gauge # HELP kube_namespace_created Unix creation timestamp # TYPE kube_namespace_created gauge # HELP kube_namespace_labels Kubernetes labels converted to Prometheus labels. @@ -54,6 +56,7 @@ func TestNamespaceStore(t *testing.T) { }, }, Want: metadata + ` + kube_namespace_annotations{namespace="nsActiveTest"} 1 kube_namespace_labels{namespace="nsActiveTest"} 1 kube_namespace_status_phase{namespace="nsActiveTest",phase="Active"} 1 kube_namespace_status_phase{namespace="nsActiveTest",phase="Terminating"} 0 @@ -72,6 +75,7 @@ func TestNamespaceStore(t *testing.T) { }, }, Want: metadata + ` + kube_namespace_annotations{namespace="nsTerminateTest"} 1 kube_namespace_labels{namespace="nsTerminateTest"} 1 kube_namespace_status_phase{namespace="nsTerminateTest",phase="Active"} 0 kube_namespace_status_phase{namespace="nsTerminateTest",phase="Terminating"} 1 @@ -95,6 +99,7 @@ func TestNamespaceStore(t *testing.T) { }, }, Want: metadata + ` + kube_namespace_annotations{namespace="nsTerminateWithConditionTest"} 1 kube_namespace_labels{namespace="nsTerminateWithConditionTest"} 1 kube_namespace_status_phase{namespace="nsTerminateWithConditionTest",phase="Active"} 0 kube_namespace_status_phase{namespace="nsTerminateWithConditionTest",phase="Terminating"} 1 @@ -127,6 +132,7 @@ func TestNamespaceStore(t *testing.T) { }, }, Want: metadata + ` + kube_namespace_annotations{namespace="ns1"} 1 kube_namespace_created{namespace="ns1"} 1.5e+09 kube_namespace_labels{namespace="ns1"} 1 kube_namespace_status_phase{namespace="ns1",phase="Active"} 1 @@ -150,6 +156,7 @@ func TestNamespaceStore(t *testing.T) { }, }, Want: metadata + ` + kube_namespace_annotations{namespace="ns2"} 1 kube_namespace_labels{namespace="ns2"} 1 kube_namespace_status_phase{namespace="ns2",phase="Active"} 1 kube_namespace_status_phase{namespace="ns2",phase="Terminating"} 0 @@ -158,8 +165,8 @@ func TestNamespaceStore(t *testing.T) { } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(namespaceMetricFamilies(nil)) - c.Headers = generator.ExtractMetricFamilyHeaders(namespaceMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(namespaceMetricFamilies(nil, nil)) + c.Headers = generator.ExtractMetricFamilyHeaders(namespaceMetricFamilies(nil, nil)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } diff --git a/internal/store/networkpolicy.go b/internal/store/networkpolicy.go index 96d095299b..c9ee0df8ff 100644 --- a/internal/store/networkpolicy.go +++ b/internal/store/networkpolicy.go @@ -31,10 +31,14 @@ import ( ) var ( + descNetworkPolicyAnnotationsName = "kube_networkpolicy_annotations" + descNetworkPolicyAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." + descNetworkPolicyLabelsName = "kube_networkpolicy_labels" + descNetworkPolicyLabelsHelp = "Kubernetes labels converted to Prometheus labels." descNetworkPolicyLabelsDefaultLabels = []string{"namespace", "networkpolicy"} ) -func networkPolicyMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func networkPolicyMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ *generator.NewFamilyGenerator( "kube_networkpolicy_created", @@ -54,8 +58,26 @@ func networkPolicyMetricFamilies(allowLabelsList []string) []generator.FamilyGen }), ), *generator.NewFamilyGenerator( - "kube_networkpolicy_labels", - "Kubernetes labels converted to Prometheus labels", + descNetworkPolicyAnnotationsName, + descNetworkPolicyAnnotationsHelp, + metric.Gauge, + "", + wrapNetworkPolicyFunc(func(n *networkingv1.NetworkPolicy) *metric.Family { + annotationKeys, annotationValues := createAnnotationKeysValues(n.Annotations, allowAnnotationsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + }), + ), + *generator.NewFamilyGenerator( + descNetworkPolicyLabelsName, + descNetworkPolicyLabelsHelp, metric.Gauge, "", wrapNetworkPolicyFunc(func(n *networkingv1.NetworkPolicy) *metric.Family { diff --git a/internal/store/networkpolicy_test.go b/internal/store/networkpolicy_test.go index 5a5ef2bb03..22b693c081 100644 --- a/internal/store/networkpolicy_test.go +++ b/internal/store/networkpolicy_test.go @@ -68,7 +68,7 @@ func TestNetworkPolicyStore(t *testing.T) { }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(networkPolicyMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(networkPolicyMetricFamilies(nil, nil)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %dth run:\n%s", i, err) } diff --git a/internal/store/node.go b/internal/store/node.go index efdeb9d831..3162897070 100644 --- a/internal/store/node.go +++ b/internal/store/node.go @@ -33,15 +33,18 @@ import ( ) var ( + descNodeAnnotationsName = "kube_node_annotations" + descNodeAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descNodeLabelsName = "kube_node_labels" descNodeLabelsHelp = "Kubernetes labels converted to Prometheus labels." descNodeLabelsDefaultLabels = []string{"node"} ) -func nodeMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func nodeMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ createNodeCreatedFamilyGenerator(), createNodeInfoFamilyGenerator(), + createNodeAnnotationsGenerator(allowAnnotationsList), createNodeLabelsGenerator(allowLabelsList), createNodeRoleFamilyGenerator(), createNodeSpecTaintFamilyGenerator(), @@ -123,6 +126,27 @@ func createNodeInfoFamilyGenerator() generator.FamilyGenerator { ) } +func createNodeAnnotationsGenerator(allowAnnotationsList []string) generator.FamilyGenerator { + return *generator.NewFamilyGenerator( + descNodeAnnotationsName, + descNodeAnnotationsHelp, + metric.Gauge, + "", + wrapNodeFunc(func(n *v1.Node) *metric.Family { + annotationKeys, annotationValues := createAnnotationKeysValues(n.Annotations, allowAnnotationsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + }), + ) +} + func createNodeLabelsGenerator(allowLabelsList []string) generator.FamilyGenerator { return *generator.NewFamilyGenerator( descNodeLabelsName, diff --git a/internal/store/node_test.go b/internal/store/node_test.go index ce5f00cfbd..73e05f26a6 100644 --- a/internal/store/node_test.go +++ b/internal/store/node_test.go @@ -276,8 +276,8 @@ func TestNodeStore(t *testing.T) { }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(nodeMetricFamilies(nil)) - c.Headers = generator.ExtractMetricFamilyHeaders(nodeMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(nodeMetricFamilies(nil, nil)) + c.Headers = generator.ExtractMetricFamilyHeaders(nodeMetricFamilies(nil, nil)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } diff --git a/internal/store/persistentvolume.go b/internal/store/persistentvolume.go index cfa74943de..a1348732e2 100644 --- a/internal/store/persistentvolume.go +++ b/internal/store/persistentvolume.go @@ -36,12 +36,14 @@ var ( descPersistentVolumeClaimRefHelp = "Information about the Persitant Volume Claim Reference." descPersistentVolumeClaimRefDefaultLabels = []string{"persistentvolume"} + descPersistentVolumeAnnotationsName = "kube_persistentvolume_annotations" + descPersistentVolumeAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descPersistentVolumeLabelsName = "kube_persistentvolume_labels" descPersistentVolumeLabelsHelp = "Kubernetes labels converted to Prometheus labels." descPersistentVolumeLabelsDefaultLabels = []string{"persistentvolume"} ) -func persistentVolumeMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func persistentVolumeMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ *generator.NewFamilyGenerator( descPersistentVolumeClaimRefName, @@ -73,6 +75,24 @@ func persistentVolumeMetricFamilies(allowLabelsList []string) []generator.Family } }), ), + *generator.NewFamilyGenerator( + descPersistentVolumeAnnotationsName, + descPersistentVolumeAnnotationsHelp, + metric.Gauge, + "", + wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { + annotationKeys, annotationValues := createAnnotationKeysValues(p.Annotations, allowAnnotationsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + }), + ), *generator.NewFamilyGenerator( descPersistentVolumeLabelsName, descPersistentVolumeLabelsHelp, diff --git a/internal/store/persistentvolume_test.go b/internal/store/persistentvolume_test.go index 82b40c62c9..c9b3e61f83 100644 --- a/internal/store/persistentvolume_test.go +++ b/internal/store/persistentvolume_test.go @@ -482,8 +482,8 @@ func TestPersistentVolumeStore(t *testing.T) { }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(persistentVolumeMetricFamilies(nil)) - c.Headers = generator.ExtractMetricFamilyHeaders(persistentVolumeMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(persistentVolumeMetricFamilies(nil, nil)) + c.Headers = generator.ExtractMetricFamilyHeaders(persistentVolumeMetricFamilies(nil, nil)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } diff --git a/internal/store/persistentvolumeclaim.go b/internal/store/persistentvolumeclaim.go index e68928898c..eeebaa2bf7 100644 --- a/internal/store/persistentvolumeclaim.go +++ b/internal/store/persistentvolumeclaim.go @@ -31,12 +31,14 @@ import ( ) var ( + descPersistentVolumeClaimAnnotationsName = "kube_persistentvolumeclaim_annotations" + descPersistentVolumeClaimAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descPersistentVolumeClaimLabelsName = "kube_persistentvolumeclaim_labels" descPersistentVolumeClaimLabelsHelp = "Kubernetes labels converted to Prometheus labels." descPersistentVolumeClaimLabelsDefaultLabels = []string{"namespace", "persistentvolumeclaim"} ) -func persistentVolumeClaimMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func persistentVolumeClaimMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ *generator.NewFamilyGenerator( descPersistentVolumeClaimLabelsName, @@ -44,12 +46,12 @@ func persistentVolumeClaimMetricFamilies(allowLabelsList []string) []generator.F metric.Gauge, "", wrapPersistentVolumeClaimFunc(func(p *v1.PersistentVolumeClaim) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(p.Labels, allowLabelsList) + annotationKeys, annotationValues := createAnnotationKeysValues(p.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ { - LabelKeys: labelKeys, - LabelValues: labelValues, + LabelKeys: annotationKeys, + LabelValues: annotationValues, Value: 1, }, }, diff --git a/internal/store/persistentvolumeclaim_test.go b/internal/store/persistentvolumeclaim_test.go index 7a87986553..f2369abb8d 100644 --- a/internal/store/persistentvolumeclaim_test.go +++ b/internal/store/persistentvolumeclaim_test.go @@ -183,8 +183,8 @@ func TestPersistentVolumeClaimStore(t *testing.T) { }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(persistentVolumeClaimMetricFamilies(nil)) - c.Headers = generator.ExtractMetricFamilyHeaders(persistentVolumeClaimMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(persistentVolumeClaimMetricFamilies(nil, nil)) + c.Headers = generator.ExtractMetricFamilyHeaders(persistentVolumeClaimMetricFamilies(nil, nil)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } diff --git a/internal/store/pod.go b/internal/store/pod.go index 1589b7ab14..9d3d46357e 100644 --- a/internal/store/pod.go +++ b/internal/store/pod.go @@ -37,7 +37,7 @@ var ( podStatusReasons = []string{"NodeLost", "Evicted", "UnexpectedAdmissionError"} ) -func podMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func podMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ createPodCompletionTimeFamilyGenerator(), createPodContainerInfoFamilyGenerator(), @@ -74,6 +74,7 @@ func podMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { createPodInitContainerStatusTerminatedReasonFamilyGenerator(), createPodInitContainerStatusWaitingFamilyGenerator(), createPodInitContainerStatusWaitingReasonFamilyGenerator(), + createPodAnnotationsGenerator(allowAnnotationsList), createPodLabelsGenerator(allowLabelsList), createPodOverheadCPUCoresFamilyGenerator(), createPodOverheadMemoryBytesFamilyGenerator(), @@ -1125,6 +1126,26 @@ func createPodInitContainerStatusWaitingReasonFamilyGenerator() generator.Family ) } +func createPodAnnotationsGenerator(allowAnnotations []string) generator.FamilyGenerator { + return *generator.NewFamilyGenerator( + "kube_pod_annotations", + "Kubernetes annotations converted to Prometheus labels.", + metric.Gauge, + "", + wrapPodFunc(func(p *v1.Pod) *metric.Family { + annotationKeys, annotationValues := createAnnotationKeysValues(p.Annotations, allowAnnotations) + m := metric.Metric{ + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + } + return &metric.Family{ + Metrics: []*metric.Metric{&m}, + } + }), + ) +} + func createPodLabelsGenerator(allowLabelsList []string) generator.FamilyGenerator { return *generator.NewFamilyGenerator( "kube_pod_labels", diff --git a/internal/store/pod_test.go b/internal/store/pod_test.go index 949c9134c6..07c9800924 100644 --- a/internal/store/pod_test.go +++ b/internal/store/pod_test.go @@ -1537,11 +1537,33 @@ func TestPodStore(t *testing.T) { "kube_pod_labels", }, }, + { + Obj: &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + Namespace: "ns1", + UID: "uid1", + Annotations: map[string]string{ + "app": "example", + }, + }, + Spec: v1.PodSpec{}, + }, + AllowAnnotationsList: []string{options.LabelWildcard}, + Want: ` + # HELP kube_pod_annotations Kubernetes annotations converted to Prometheus labels. + # TYPE kube_pod_annotations gauge + kube_pod_annotations{annotation_app="example",namespace="ns1",pod="pod1",uid="uid1"} 1 + `, + MetricNames: []string{ + "kube_pod_annotations", + }, + }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(podMetricFamilies(c.AllowLabelsList)) - c.Headers = generator.ExtractMetricFamilyHeaders(podMetricFamilies(c.AllowLabelsList)) + c.Func = generator.ComposeMetricGenFuncs(podMetricFamilies(c.AllowAnnotationsList, c.AllowLabelsList)) + c.Headers = generator.ExtractMetricFamilyHeaders(podMetricFamilies(c.AllowAnnotationsList, c.AllowLabelsList)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } @@ -1551,7 +1573,7 @@ func TestPodStore(t *testing.T) { func BenchmarkPodStore(b *testing.B) { b.ReportAllocs() - f := generator.ComposeMetricGenFuncs(podMetricFamilies(nil)) + f := generator.ComposeMetricGenFuncs(podMetricFamilies(nil, nil)) pod := &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ diff --git a/internal/store/replicaset.go b/internal/store/replicaset.go index 6c8a259365..1159a68388 100644 --- a/internal/store/replicaset.go +++ b/internal/store/replicaset.go @@ -33,11 +33,13 @@ import ( var ( descReplicaSetLabelsDefaultLabels = []string{"namespace", "replicaset"} + descReplicaSetAnnotationsName = "kube_replicaset_annotations" + descReplicaSetAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descReplicaSetLabelsName = "kube_replicaset_labels" descReplicaSetLabelsHelp = "Kubernetes labels converted to Prometheus labels." ) -func replicaSetMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func replicaSetMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ *generator.NewFamilyGenerator( "kube_replicaset_created", @@ -197,6 +199,24 @@ func replicaSetMetricFamilies(allowLabelsList []string) []generator.FamilyGenera } }), ), + *generator.NewFamilyGenerator( + descReplicaSetAnnotationsName, + descReplicaSetAnnotationsHelp, + metric.Gauge, + "", + wrapReplicaSetFunc(func(r *v1.ReplicaSet) *metric.Family { + annotationKeys, annotationValues := createAnnotationKeysValues(r.Annotations, allowAnnotationsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + }), + ), *generator.NewFamilyGenerator( descReplicaSetLabelsName, descReplicaSetLabelsHelp, diff --git a/internal/store/replicaset_test.go b/internal/store/replicaset_test.go index 3972fb8b25..7735c95308 100644 --- a/internal/store/replicaset_test.go +++ b/internal/store/replicaset_test.go @@ -36,9 +36,11 @@ func TestReplicaSetStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` + # HELP kube_replicaset_annotations Kubernetes annotations converted to Prometheus labels. + # TYPE kube_replicaset_annotations gauge # HELP kube_replicaset_created Unix creation timestamp # TYPE kube_replicaset_created gauge - # HELP kube_replicaset_metadata_generation Sequence number representing a specific generation of the desired state. + # HELP kube_replicaset_metadata_generation Sequence number representing a specific generation of the desired state. # TYPE kube_replicaset_metadata_generation gauge # HELP kube_replicaset_status_replicas The number of replicas per ReplicaSet. # TYPE kube_replicaset_status_replicas gauge @@ -85,6 +87,7 @@ func TestReplicaSetStore(t *testing.T) { }, }, Want: metadata + ` + kube_replicaset_annotations{replicaset="rs1",namespace="ns1"} 1 kube_replicaset_labels{replicaset="rs1",namespace="ns1"} 1 kube_replicaset_created{namespace="ns1",replicaset="rs1"} 1.5e+09 kube_replicaset_metadata_generation{namespace="ns1",replicaset="rs1"} 21 @@ -118,6 +121,7 @@ func TestReplicaSetStore(t *testing.T) { }, }, Want: metadata + ` + kube_replicaset_annotations{replicaset="rs2",namespace="ns2"} 1 kube_replicaset_labels{replicaset="rs2",namespace="ns2"} 1 kube_replicaset_metadata_generation{namespace="ns2",replicaset="rs2"} 14 kube_replicaset_status_replicas{namespace="ns2",replicaset="rs2"} 0 @@ -130,8 +134,8 @@ func TestReplicaSetStore(t *testing.T) { }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(replicaSetMetricFamilies(nil)) - c.Headers = generator.ExtractMetricFamilyHeaders(replicaSetMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(replicaSetMetricFamilies(nil, nil)) + c.Headers = generator.ExtractMetricFamilyHeaders(replicaSetMetricFamilies(nil, nil)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } diff --git a/internal/store/secret.go b/internal/store/secret.go index 9b1599798e..f443f9a76f 100644 --- a/internal/store/secret.go +++ b/internal/store/secret.go @@ -31,12 +31,14 @@ import ( ) var ( + descSecretAnnotationsName = "kube_secret_annotations" + descSecretAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descSecretLabelsName = "kube_secret_labels" descSecretLabelsHelp = "Kubernetes labels converted to Prometheus labels." descSecretLabelsDefaultLabels = []string{"namespace", "secret"} ) -func secretMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func secretMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ *generator.NewFamilyGenerator( "kube_secret_info", @@ -70,6 +72,25 @@ func secretMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator } }), ), + *generator.NewFamilyGenerator( + descSecretAnnotationsName, + descSecretAnnotationsHelp, + metric.Gauge, + "", + wrapSecretFunc(func(s *v1.Secret) *metric.Family { + annotationKeys, annotationValues := createAnnotationKeysValues(s.Annotations, allowAnnotationsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + + }), + ), *generator.NewFamilyGenerator( descSecretLabelsName, descSecretLabelsHelp, diff --git a/internal/store/secret_test.go b/internal/store/secret_test.go index 052021ff72..96f88e1753 100644 --- a/internal/store/secret_test.go +++ b/internal/store/secret_test.go @@ -116,8 +116,8 @@ func TestSecretStore(t *testing.T) { }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(secretMetricFamilies(nil)) - c.Headers = generator.ExtractMetricFamilyHeaders(secretMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(secretMetricFamilies(nil, nil)) + c.Headers = generator.ExtractMetricFamilyHeaders(secretMetricFamilies(nil, nil)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } diff --git a/internal/store/service.go b/internal/store/service.go index 15a1393a24..91f170f31c 100644 --- a/internal/store/service.go +++ b/internal/store/service.go @@ -31,12 +31,14 @@ import ( ) var ( + descServiceAnnotationsName = "kube_service_annotations" + descServiceAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descServiceLabelsName = "kube_service_labels" descServiceLabelsHelp = "Kubernetes labels converted to Prometheus labels." descServiceLabelsDefaultLabels = []string{"namespace", "service"} ) -func serviceMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func serviceMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ *generator.NewFamilyGenerator( "kube_service_info", @@ -84,6 +86,21 @@ func serviceMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator return &metric.Family{Metrics: []*metric.Metric{&m}} }), ), + *generator.NewFamilyGenerator( + descServiceAnnotationsName, + descServiceAnnotationsHelp, + metric.Gauge, + "", + wrapSvcFunc(func(s *v1.Service) *metric.Family { + annotationKeys, annotationValues := createAnnotationKeysValues(s.Annotations, allowAnnotationsList) + m := metric.Metric{ + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + } + return &metric.Family{Metrics: []*metric.Metric{&m}} + }), + ), *generator.NewFamilyGenerator( descServiceLabelsName, descServiceLabelsHelp, diff --git a/internal/store/service_test.go b/internal/store/service_test.go index b9545d7ad0..d6f0c1838f 100644 --- a/internal/store/service_test.go +++ b/internal/store/service_test.go @@ -30,6 +30,8 @@ func TestServiceStore(t *testing.T) { // Fixed metadata on type and help text. We prepend this to every expected // output so we only have to modify a single place when doing adjustments. const metadata = ` + # HELP kube_service_annotations Kubernetes annotations converted to Prometheus labels. + # TYPE kube_service_annotations gauge # HELP kube_service_info Information about service. # TYPE kube_service_info gauge # HELP kube_service_created Unix creation timestamp @@ -60,20 +62,24 @@ func TestServiceStore(t *testing.T) { }, }, Want: ` + # HELP kube_service_annotations Kubernetes annotations converted to Prometheus labels. # HELP kube_service_created Unix creation timestamp # HELP kube_service_info Information about service. # HELP kube_service_labels Kubernetes labels converted to Prometheus labels. # HELP kube_service_spec_type Type about service. + # TYPE kube_service_annotations gauge # TYPE kube_service_created gauge # TYPE kube_service_info gauge # TYPE kube_service_labels gauge # TYPE kube_service_spec_type gauge + kube_service_annotations{namespace="default",service="test-service1"} 1 kube_service_created{namespace="default",service="test-service1"} 1.5e+09 kube_service_info{cluster_ip="1.2.3.4",external_name="",load_balancer_ip="",namespace="default",service="test-service1"} 1 kube_service_labels{namespace="default",service="test-service1"} 1 kube_service_spec_type{namespace="default",service="test-service1",type="ClusterIP"} 1 `, MetricNames: []string{ + "kube_service_annotations", "kube_service_created", "kube_service_info", "kube_service_labels", @@ -97,6 +103,7 @@ func TestServiceStore(t *testing.T) { }, }, Want: metadata + ` + kube_service_annotations{namespace="default",service="test-service2"} 1 kube_service_created{namespace="default",service="test-service2"} 1.5e+09 kube_service_info{cluster_ip="1.2.3.5",external_name="",load_balancer_ip="",namespace="default",service="test-service2"} 1 kube_service_labels{namespace="default",service="test-service2"} 1 @@ -120,6 +127,7 @@ func TestServiceStore(t *testing.T) { }, }, Want: metadata + ` + kube_service_annotations{namespace="default",service="test-service3"} 1 kube_service_created{namespace="default",service="test-service3"} 1.5e+09 kube_service_info{cluster_ip="1.2.3.6",external_name="",load_balancer_ip="1.2.3.7",namespace="default",service="test-service3"} 1 kube_service_labels{namespace="default",service="test-service3"} 1 @@ -142,6 +150,7 @@ func TestServiceStore(t *testing.T) { }, }, Want: metadata + ` + kube_service_annotations{namespace="default",service="test-service4"} 1 kube_service_created{namespace="default",service="test-service4"} 1.5e+09 kube_service_info{cluster_ip="",external_name="www.example.com",load_balancer_ip="",namespace="default",service="test-service4"} 1 kube_service_labels{namespace="default",service="test-service4"} 1 @@ -173,6 +182,7 @@ func TestServiceStore(t *testing.T) { }, }, Want: metadata + ` + kube_service_annotations{namespace="default",service="test-service5"} 1 kube_service_created{namespace="default",service="test-service5"} 1.5e+09 kube_service_info{cluster_ip="",external_name="",load_balancer_ip="",namespace="default",service="test-service5"} 1 kube_service_labels{namespace="default",service="test-service5"} 1 @@ -199,6 +209,7 @@ func TestServiceStore(t *testing.T) { }, }, Want: metadata + ` + kube_service_annotations{namespace="default",service="test-service6"} 1 kube_service_created{namespace="default",service="test-service6"} 1.5e+09 kube_service_info{cluster_ip="",external_name="",load_balancer_ip="",namespace="default",service="test-service6"} 1 kube_service_labels{namespace="default",service="test-service6"} 1 @@ -209,8 +220,8 @@ func TestServiceStore(t *testing.T) { }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(serviceMetricFamilies(nil)) - c.Headers = generator.ExtractMetricFamilyHeaders(serviceMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(serviceMetricFamilies(nil, nil)) + c.Headers = generator.ExtractMetricFamilyHeaders(serviceMetricFamilies(nil, nil)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } diff --git a/internal/store/statefulset.go b/internal/store/statefulset.go index 624e5aba96..9d3f096c42 100644 --- a/internal/store/statefulset.go +++ b/internal/store/statefulset.go @@ -31,12 +31,14 @@ import ( ) var ( + descStatefulSetAnnotationsName = "kube_statefulset_annotations" + descStatefulSetAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descStatefulSetLabelsName = "kube_statefulset_labels" descStatefulSetLabelsHelp = "Kubernetes labels converted to Prometheus labels." descStatefulSetLabelsDefaultLabels = []string{"namespace", "statefulset"} ) -func statefulSetMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func statefulSetMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ *generator.NewFamilyGenerator( "kube_statefulset_created", @@ -166,6 +168,24 @@ func statefulSetMetricFamilies(allowLabelsList []string) []generator.FamilyGener } }), ), + *generator.NewFamilyGenerator( + descStatefulSetAnnotationsName, + descStatefulSetAnnotationsHelp, + metric.Gauge, + "", + wrapStatefulSetFunc(func(s *v1.StatefulSet) *metric.Family { + annotationKeys, annotationValues := createAnnotationKeysValues(s.Annotations, allowAnnotationsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + }), + ), *generator.NewFamilyGenerator( descStatefulSetLabelsName, descStatefulSetLabelsHelp, diff --git a/internal/store/statefulset_test.go b/internal/store/statefulset_test.go index d9ef6670ee..eabca452d1 100644 --- a/internal/store/statefulset_test.go +++ b/internal/store/statefulset_test.go @@ -241,8 +241,8 @@ func TestStatefulSetStore(t *testing.T) { }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(statefulSetMetricFamilies(nil)) - c.Headers = generator.ExtractMetricFamilyHeaders(statefulSetMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(statefulSetMetricFamilies(nil, nil)) + c.Headers = generator.ExtractMetricFamilyHeaders(statefulSetMetricFamilies(nil, nil)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } diff --git a/internal/store/storageclass.go b/internal/store/storageclass.go index f4c4538e44..439c6737f5 100644 --- a/internal/store/storageclass.go +++ b/internal/store/storageclass.go @@ -29,6 +29,8 @@ import ( ) var ( + descStorageClassAnnotationsName = "kube_storageclass_annotations" + descStorageClassAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descStorageClassLabelsName = "kube_storageclass_labels" descStorageClassLabelsHelp = "Kubernetes labels converted to Prometheus labels." descStorageClassLabelsDefaultLabels = []string{"storageclass"} @@ -36,7 +38,7 @@ var ( defaultVolumeBindingMode = storagev1.VolumeBindingImmediate ) -func storageClassMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func storageClassMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ *generator.NewFamilyGenerator( "kube_storageclass_info", @@ -79,6 +81,24 @@ func storageClassMetricFamilies(allowLabelsList []string) []generator.FamilyGene } }), ), + *generator.NewFamilyGenerator( + descStorageClassAnnotationsName, + descStorageClassAnnotationsHelp, + metric.Gauge, + "", + wrapStorageClassFunc(func(s *storagev1.StorageClass) *metric.Family { + annotationKeys, annotationValues := createAnnotationKeysValues(s.Annotations, allowAnnotationsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + }), + ), *generator.NewFamilyGenerator( descStorageClassLabelsName, descStorageClassLabelsHelp, diff --git a/internal/store/storageclass_test.go b/internal/store/storageclass_test.go index d3ee764fc8..c1f6866241 100644 --- a/internal/store/storageclass_test.go +++ b/internal/store/storageclass_test.go @@ -108,8 +108,8 @@ func TestStorageClassStore(t *testing.T) { }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(storageClassMetricFamilies(nil)) - c.Headers = generator.ExtractMetricFamilyHeaders(storageClassMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(storageClassMetricFamilies(nil, nil)) + c.Headers = generator.ExtractMetricFamilyHeaders(storageClassMetricFamilies(nil, nil)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } diff --git a/internal/store/testutils.go b/internal/store/testutils.go index 86d3526cfb..fcebf167de 100644 --- a/internal/store/testutils.go +++ b/internal/store/testutils.go @@ -30,12 +30,13 @@ import ( ) type generateMetricsTestCase struct { - Obj interface{} - MetricNames []string - AllowLabelsList []string - Want string - Headers []string - Func func(interface{}) []metric.FamilyInterface + Obj interface{} + MetricNames []string + AllowAnnotationsList []string + AllowLabelsList []string + Want string + Headers []string + Func func(interface{}) []metric.FamilyInterface } func (testCase *generateMetricsTestCase) run() error { diff --git a/internal/store/utils.go b/internal/store/utils.go index e00205ea60..c7d405dcc0 100644 --- a/internal/store/utils.go +++ b/internal/store/utils.go @@ -73,6 +73,10 @@ func addConditionMetrics(cs v1.ConditionStatus) []*metric.Metric { return ms } +func kubeAnnotationssToPrometheusLabels(annotations map[string]string) ([]string, []string) { + return mapToPrometheusLabels(annotations, "annotation") +} + func kubeLabelsToPrometheusLabels(labels map[string]string) ([]string, []string) { return mapToPrometheusLabels(labels, "label") } @@ -172,6 +176,26 @@ func isPrefixedNativeResource(name v1.ResourceName) bool { return strings.Contains(string(name), v1.ResourceDefaultNamespacePrefix) } +// createAnnotationKeysValues takes in passed kubernetes annotations and allowed list in kubernetes label format +// it returns only those allowed annotations that exist in the list converting them to Prometheus labels. +func createAnnotationKeysValues(allKubeAnnotations map[string]string, allowList []string) ([]string, []string) { + allowedKubeAnnotations := make(map[string]string) + + if len(allowList) > 0 { + if allowList[0] == options.LabelWildcard { + return kubeAnnotationssToPrometheusLabels(allKubeAnnotations) + } + + for _, l := range allowList { + v, found := allKubeAnnotations[l] + if found { + allowedKubeAnnotations[l] = v + } + } + } + return kubeAnnotationssToPrometheusLabels(allowedKubeAnnotations) +} + // createLabelKeysValues takes in passed kubernetes labels and allowed list in kubernetes label format // it returns only those allowed labels that exist in the list converting them to Prometheus labels. func createLabelKeysValues(allKubeLabels map[string]string, allowList []string) ([]string, []string) { diff --git a/internal/store/verticalpodautoscaler.go b/internal/store/verticalpodautoscaler.go index 3093a2c13b..1783ef0b77 100644 --- a/internal/store/verticalpodautoscaler.go +++ b/internal/store/verticalpodautoscaler.go @@ -34,13 +34,33 @@ import ( ) var ( + descVerticalPodAutoscalerAnnotationsName = "kube_verticalpodautoscaler_annotations" + descVerticalPodAutoscalerAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels." descVerticalPodAutoscalerLabelsName = "kube_verticalpodautoscaler_labels" descVerticalPodAutoscalerLabelsHelp = "Kubernetes labels converted to Prometheus labels." descVerticalPodAutoscalerLabelsDefaultLabels = []string{"namespace", "verticalpodautoscaler", "target_api_version", "target_kind", "target_name"} ) -func vpaMetricFamilies(allowLabelsList []string) []generator.FamilyGenerator { +func vpaMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { return []generator.FamilyGenerator{ + *generator.NewFamilyGenerator( + descVerticalPodAutoscalerAnnotationsName, + descVerticalPodAutoscalerAnnotationsHelp, + metric.Gauge, + "", + wrapVPAFunc(func(a *autoscaling.VerticalPodAutoscaler) *metric.Family { + annotationKeys, annotationValues := createAnnotationKeysValues(a.Annotations, allowAnnotationsList) + return &metric.Family{ + Metrics: []*metric.Metric{ + { + LabelKeys: annotationKeys, + LabelValues: annotationValues, + Value: 1, + }, + }, + } + }), + ), *generator.NewFamilyGenerator( descVerticalPodAutoscalerLabelsName, descVerticalPodAutoscalerLabelsHelp, diff --git a/internal/store/verticalpodautoscaler_test.go b/internal/store/verticalpodautoscaler_test.go index f3be025bc9..481c689ff3 100644 --- a/internal/store/verticalpodautoscaler_test.go +++ b/internal/store/verticalpodautoscaler_test.go @@ -133,8 +133,8 @@ func TestVPAStore(t *testing.T) { }, } for i, c := range cases { - c.Func = generator.ComposeMetricGenFuncs(vpaMetricFamilies(nil)) - c.Headers = generator.ExtractMetricFamilyHeaders(vpaMetricFamilies(nil)) + c.Func = generator.ComposeMetricGenFuncs(vpaMetricFamilies(nil, nil)) + c.Headers = generator.ExtractMetricFamilyHeaders(vpaMetricFamilies(nil, nil)) if err := c.run(); err != nil { t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) } diff --git a/main.go b/main.go index df7512fccd..3ba6036c18 100644 --- a/main.go +++ b/main.go @@ -150,6 +150,7 @@ func main() { storeBuilder.WithKubeClient(kubeClient) storeBuilder.WithVPAClient(vpaClient) storeBuilder.WithSharding(opts.Shard, opts.TotalShards) + storeBuilder.WithAllowAnnotations(opts.AnnotationsAllowList) storeBuilder.WithAllowLabels(opts.LabelsAllowList) ksmMetricsRegistry.MustRegister( diff --git a/main_test.go b/main_test.go index 278d283a49..2ce85e7263 100644 --- a/main_test.go +++ b/main_test.go @@ -75,6 +75,7 @@ func BenchmarkKubeStateMetrics(b *testing.B) { } builder.WithAllowDenyList(l) + builder.WithAllowAnnotations(map[string][]string{}) builder.WithAllowLabels(map[string][]string{}) // This test is not suitable to be compared in terms of time, as it includes @@ -165,7 +166,8 @@ func TestFullScrapeCycle(t *testing.T) { body, _ := io.ReadAll(resp.Body) - expected := `# HELP kube_pod_completion_time Completion time in unix timestamp for a pod. + expected := `# HELP kube_pod_annotations Kubernetes annotations converted to Prometheus labels. +# HELP kube_pod_completion_time Completion time in unix timestamp for a pod. # HELP kube_pod_container_info Information about a container in a pod. # HELP kube_pod_container_resource_limits The number of requested limit resource by a container. # HELP kube_pod_container_resource_requests The number of requested request resource by a container. @@ -215,6 +217,7 @@ func TestFullScrapeCycle(t *testing.T) { # HELP kube_pod_status_scheduled Describes the status of the scheduling process for the pod. # HELP kube_pod_status_scheduled_time Unix timestamp when pod moved into scheduled status # HELP kube_pod_status_unschedulable Describes the unschedulable status for the pod. +# TYPE kube_pod_annotations gauge # TYPE kube_pod_completion_time gauge # TYPE kube_pod_container_info gauge # TYPE kube_pod_container_resource_limits gauge @@ -265,6 +268,7 @@ func TestFullScrapeCycle(t *testing.T) { # TYPE kube_pod_status_scheduled gauge # TYPE kube_pod_status_scheduled_time gauge # TYPE kube_pod_status_unschedulable gauge +kube_pod_annotations{namespace="default",pod="pod0",uid="abc-0"} 1 kube_pod_container_info{namespace="default",pod="pod0",uid="abc-0",container="container2",image="k8s.gcr.io/hyperkube2",image_id="docker://sha256:bbb",container_id="docker://cd456"} 1 kube_pod_container_info{namespace="default",pod="pod0",uid="abc-0",container="container3",image="k8s.gcr.io/hyperkube3",image_id="docker://sha256:ccc",container_id="docker://ef789"} 1 kube_pod_container_resource_limits{namespace="default",pod="pod0",uid="abc-0",container="pod1_con1",node="node1",resource="cpu",unit="core"} 0.2 diff --git a/pkg/options/options.go b/pkg/options/options.go index 18d4eb3c15..c77f98761a 100644 --- a/pkg/options/options.go +++ b/pkg/options/options.go @@ -28,24 +28,25 @@ import ( // Options are the configurable parameters for kube-state-metrics. type Options struct { - Apiserver string - Kubeconfig string - Help bool - Port int - Host string - TelemetryPort int - TelemetryHost string - TLSConfig string - Resources ResourceSet - Namespaces NamespaceList - Shard int32 - TotalShards int - Pod string - Namespace string - MetricDenylist MetricSet - MetricAllowlist MetricSet - Version bool - LabelsAllowList LabelsAllowList + Apiserver string + Kubeconfig string + Help bool + Port int + Host string + TelemetryPort int + TelemetryHost string + TLSConfig string + Resources ResourceSet + Namespaces NamespaceList + Shard int32 + TotalShards int + Pod string + Namespace string + MetricDenylist MetricSet + MetricAllowlist MetricSet + Version bool + AnnotationsAllowList LabelsAllowList + LabelsAllowList LabelsAllowList EnableGZIPEncoding bool @@ -55,10 +56,11 @@ type Options struct { // NewOptions returns a new instance of `Options`. func NewOptions() *Options { return &Options{ - Resources: ResourceSet{}, - MetricAllowlist: MetricSet{}, - MetricDenylist: MetricSet{}, - LabelsAllowList: LabelsAllowList{}, + Resources: ResourceSet{}, + MetricAllowlist: MetricSet{}, + MetricDenylist: MetricSet{}, + AnnotationsAllowList: LabelsAllowList{}, + LabelsAllowList: LabelsAllowList{}, } } @@ -90,6 +92,7 @@ func (o *Options) AddFlags() { o.flags.Var(&o.Namespaces, "namespaces", fmt.Sprintf("Comma-separated list of namespaces to be enabled. Defaults to %q", &DefaultNamespaces)) o.flags.Var(&o.MetricAllowlist, "metric-allowlist", "Comma-separated list of metrics to be exposed. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive.") o.flags.Var(&o.MetricDenylist, "metric-denylist", "Comma-separated list of metrics not to be enabled. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive.") + o.flags.Var(&o.AnnotationsAllowList, "metric-annotations-allowlist", "Comma-separated list of Kubernetes annotations keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional annotations provide a list of resource names in their plural form and Kubernetes annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. A single '*' can be provided per resource instead to allow any annotations, but that has severe performance implications (Example: '=pods=[*]').") o.flags.Var(&o.LabelsAllowList, "metric-labels-allowlist", "Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional labels provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any labels, but that has severe performance implications (Example: '=pods=[*]').") o.flags.Int32Var(&o.Shard, "shard", int32(0), "The instances shard nominal (zero indexed) within the total number of shards. (default 0)") o.flags.IntVar(&o.TotalShards, "total-shards", 1, "The total number of shards. Sharding is disabled when total shards is set to 1.") From adcf2b42c5cc28d798009d53bec6b10f0d757127 Mon Sep 17 00:00:00 2001 From: Sylvain Rabot Date: Mon, 7 Jun 2021 15:59:06 +0200 Subject: [PATCH 2/9] Regenerate docs/cli-arguments.md Signed-off-by: Sylvain Rabot --- docs/cli-arguments.md | 66 +++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/docs/cli-arguments.md b/docs/cli-arguments.md index efcd0bd903..3cec8e556e 100644 --- a/docs/cli-arguments.md +++ b/docs/cli-arguments.md @@ -25,37 +25,37 @@ spec: ```txt $ kube-state-metrics -h Usage of ./kube-state-metrics: - --add_dir_header If true, adds the file directory to the header of the log messages - --alsologtostderr log to standard error as well as files - --apiserver string The URL of the apiserver to use as a master - --enable-gzip-encoding Gzip responses when requested by clients via 'Accept-Encoding: gzip' header. - -h, --help Print Help text - --host string Host to expose metrics on. (default "::") - --kubeconfig string Absolute path to the kubeconfig file - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) - --log_dir string If non-empty, write log files in this directory - --log_file string If non-empty, use this log file - --log_file_max_size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800) - --logtostderr log to standard error instead of files (default true) - --metric-allowlist string Comma-separated list of metrics to be exposed. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive. - --metric-denylist string Comma-separated list of metrics not to be enabled. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive. - --metric-annotations-allowlist string Comma-separated list of additional Kubernetes annotations keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional annotations provide a list of resource names in their plural form and Kubernetes annotations keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any annotation, but that has severe performance implications (Example: '=pods=[*]'). - --metric-labels-allowlist string Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional labels provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any labels, but that has severe performance implications (Example: '=pods=[*]'). - --namespaces string Comma-separated list of namespaces to be enabled. Defaults to "" - --one_output If true, only write logs to their native severity level (vs also writing to each lower severity level) - --pod string Name of the pod that contains the kube-state-metrics container. When set, it is expected that --pod and --pod-namespace are both set. Most likely this should be passed via the downward API. This is used for auto-detecting sharding. If set, this has preference over statically configured sharding. This is experimental, it may be removed without notice. - --pod-namespace string Name of the namespace of the pod specified by --pod. When set, it is expected that --pod and --pod-namespace are both set. Most likely this should be passed via the downward API. This is used for auto-detecting sharding. If set, this has preference over statically configured sharding. This is experimental, it may be removed without notice. - --port int Port to expose metrics on. (default 8080) - --resources string Comma-separated list of Resources to be enabled. Defaults to "certificatesigningrequests,configmaps,cronjobs,daemonsets,deployments,endpoints,horizontalpodautoscalers,ingresses,jobs,leases,limitranges,mutatingwebhookconfigurations,namespaces,networkpolicies,nodes,persistentvolumeclaims,persistentvolumes,poddisruptionbudgets,pods,replicasets,replicationcontrollers,resourcequotas,secrets,services,statefulsets,storageclasses,validatingwebhookconfigurations,volumeattachments" - --shard int32 The instances shard nominal (zero indexed) within the total number of shards. (default 0) - --skip_headers If true, avoid header prefixes in the log messages - --skip_log_headers If true, avoid headers when opening log files - --stderrthreshold severity logs at or above this threshold go to stderr (default 2) - --telemetry-host string Host to expose kube-state-metrics self metrics on. (default "::") - --telemetry-port int Port to expose kube-state-metrics self metrics on. (default 8081) - --tls-config string Path to the TLS configuration file - --total-shards int The total number of shards. Sharding is disabled when total shards is set to 1. (default 1) - -v, --v Level number for the log level verbosity - --version kube-state-metrics build version information - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --add_dir_header If true, adds the file directory to the header of the log messages + --alsologtostderr log to standard error as well as files + --apiserver string The URL of the apiserver to use as a master + --enable-gzip-encoding Gzip responses when requested by clients via 'Accept-Encoding: gzip' header. + -h, --help Print Help text + --host string Host to expose metrics on. (default "::") + --kubeconfig string Absolute path to the kubeconfig file + --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_dir string If non-empty, write log files in this directory + --log_file string If non-empty, use this log file + --log_file_max_size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800) + --logtostderr log to standard error instead of files (default true) + --metric-allowlist string Comma-separated list of metrics to be exposed. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive. + --metric-annotations-allowlist string Comma-separated list of Kubernetes annotations keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional annotations provide a list of resource names in their plural form and Kubernetes annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. A single '*' can be provided per resource instead to allow any annotations, but that has severe performance implications (Example: '=pods=[*]'). + --metric-denylist string Comma-separated list of metrics not to be enabled. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive. + --metric-labels-allowlist string Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional labels provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any labels, but that has severe performance implications (Example: '=pods=[*]'). + --namespaces string Comma-separated list of namespaces to be enabled. Defaults to "" + --one_output If true, only write logs to their native severity level (vs also writing to each lower severity level) + --pod string Name of the pod that contains the kube-state-metrics container. When set, it is expected that --pod and --pod-namespace are both set. Most likely this should be passed via the downward API. This is used for auto-detecting sharding. If set, this has preference over statically configured sharding. This is experimental, it may be removed without notice. + --pod-namespace string Name of the namespace of the pod specified by --pod. When set, it is expected that --pod and --pod-namespace are both set. Most likely this should be passed via the downward API. This is used for auto-detecting sharding. If set, this has preference over statically configured sharding. This is experimental, it may be removed without notice. + --port int Port to expose metrics on. (default 8080) + --resources string Comma-separated list of Resources to be enabled. Defaults to "certificatesigningrequests,configmaps,cronjobs,daemonsets,deployments,endpoints,horizontalpodautoscalers,ingresses,jobs,leases,limitranges,mutatingwebhookconfigurations,namespaces,networkpolicies,nodes,persistentvolumeclaims,persistentvolumes,poddisruptionbudgets,pods,replicasets,replicationcontrollers,resourcequotas,secrets,services,statefulsets,storageclasses,validatingwebhookconfigurations,volumeattachments" + --shard int32 The instances shard nominal (zero indexed) within the total number of shards. (default 0) + --skip_headers If true, avoid header prefixes in the log messages + --skip_log_headers If true, avoid headers when opening log files + --stderrthreshold severity logs at or above this threshold go to stderr (default 2) + --telemetry-host string Host to expose kube-state-metrics self metrics on. (default "::") + --telemetry-port int Port to expose kube-state-metrics self metrics on. (default 8081) + --tls-config string Path to the TLS configuration file + --total-shards int The total number of shards. Sharding is disabled when total shards is set to 1. (default 1) + -v, --v Level number for the log level verbosity + --version kube-state-metrics build version information + --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging ``` From 1cd06cf4ab963f88f9c213090844d85fc01bfb96 Mon Sep 17 00:00:00 2001 From: Sylvain Rabot Date: Mon, 7 Jun 2021 16:14:56 +0200 Subject: [PATCH 3/9] Fix benchmark test Signed-off-by: Sylvain Rabot --- internal/store/pod_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/store/pod_test.go b/internal/store/pod_test.go index 07c9800924..a96988240c 100644 --- a/internal/store/pod_test.go +++ b/internal/store/pod_test.go @@ -1635,7 +1635,7 @@ func BenchmarkPodStore(b *testing.B) { }, } - expectedFamilies := 50 + expectedFamilies := 51 for n := 0; n < b.N; n++ { families := f(pod) if len(families) != expectedFamilies { From c1d3c87589b605057a80c70b509ef01d7ba4f591 Mon Sep 17 00:00:00 2001 From: Sylvain Rabot Date: Fri, 25 Jun 2021 15:13:05 +0200 Subject: [PATCH 4/9] Fix documentation and tests Signed-off-by: Sylvain Rabot --- docs/cronjob-metrics.md | 2 +- docs/endpoint-metrics.md | 2 +- docs/ingress-metrics.md | 2 +- docs/job-metrics.md | 2 +- docs/namespace-metrics.md | 1 + docs/node-metrics.md | 2 +- docs/persistentvolume-metrics.md | 2 +- docs/persistentvolumeclaim-metrics.md | 2 +- docs/pod-metrics.md | 2 +- docs/replicaset-metrics.md | 2 +- docs/secret-metrics.md | 2 +- docs/service-metrics.md | 2 +- docs/statefulset-metrics.md | 2 +- docs/storageclass-metrics.md | 2 +- 14 files changed, 14 insertions(+), 13 deletions(-) diff --git a/docs/cronjob-metrics.md b/docs/cronjob-metrics.md index 3d5100cd3b..d8e76ffadc 100644 --- a/docs/cronjob-metrics.md +++ b/docs/cronjob-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_cronjob_annotations | Gauge | `cronjob`=<cronjob-name>
`namespace`=<cronjob-namespace>
`annotation_CRONJOB_LABEL`=<CRONJOB_ANNOTATION> | STABLE +| kube_cronjob_annotations | Gauge | `cronjob`=<cronjob-name>
`namespace`=<cronjob-namespace>
`annotation_CRONJOB_ANNOTATION`=<CRONJOB_ANNOTATION> | STABLE | kube_cronjob_info | Gauge | `cronjob`=<cronjob-name>
`namespace`=<cronjob-namespace>
`schedule`=<schedule>
`concurrency_policy`=<concurrency-policy> | STABLE | kube_cronjob_labels | Gauge | `cronjob`=<cronjob-name>
`namespace`=<cronjob-namespace>
`label_CRONJOB_LABEL`=<CRONJOB_LABEL> | STABLE | kube_cronjob_created | Gauge | `cronjob`=<cronjob-name>
`namespace`=<cronjob-namespace> | STABLE diff --git a/docs/endpoint-metrics.md b/docs/endpoint-metrics.md index 746c832681..1006ae6f1d 100644 --- a/docs/endpoint-metrics.md +++ b/docs/endpoint-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_endpoint_annotations | Gauge | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace>
`annotation_ENDPOINT_LABEL`=<ENDPOINT_ANNOTATION> | STABLE | +| kube_endpoint_annotations | Gauge | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace>
`annotation_ENDPOINT_ANNOTATION`=<ENDPOINT_ANNOTATION> | STABLE | | kube_endpoint_address_not_ready | Gauge | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace> | STABLE | | kube_endpoint_address_available | Gauge | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace> | STABLE | | kube_endpoint_info | Gauge | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace> | STABLE | diff --git a/docs/ingress-metrics.md b/docs/ingress-metrics.md index e00fc05aa5..0bbe307dfb 100644 --- a/docs/ingress-metrics.md +++ b/docs/ingress-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_ingress_annotations | Gauge | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`annotation_INGRESS_LABEL`=<ANNOTATION_LABEL> | STABLE | +| kube_ingress_annotations | Gauge | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`annotation_INGRESS_ANNOTATION`=<ANNOTATION_LABEL> | STABLE | | kube_ingress_info | Gauge | `ingress`=<ingress-name>
`namespace`=<ingress-namespace> | STABLE | | kube_ingress_labels | Gauge | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`label_INGRESS_LABEL`=<INGRESS_LABEL> | STABLE | | kube_ingress_created | Gauge | `ingress`=<ingress-name>
`namespace`=<ingress-namespace> | STABLE | diff --git a/docs/job-metrics.md b/docs/job-metrics.md index 9d28610881..dd95d8169e 100644 --- a/docs/job-metrics.md +++ b/docs/job-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_job_annotations | Gauge | `job_name`=<job-name>
`namespace`=<job-namespace>
`annotation_JOB_LABEL`=<JOB_ANNOTATION> | STABLE | +| kube_job_annotations | Gauge | `job_name`=<job-name>
`namespace`=<job-namespace>
`annotation_JOB_ANNOTATION`=<JOB_ANNOTATION> | STABLE | | kube_job_info | Gauge | `job_name`=<job-name>
`namespace`=<job-namespace> | STABLE | | kube_job_labels | Gauge | `job_name`=<job-name>
`namespace`=<job-namespace>
`label_JOB_LABEL`=<JOB_LABEL> | STABLE | | kube_job_owner | Gauge | `job_name`=<job-name>
`namespace`=<job-namespace>
`owner_kind`=<owner kind>
`owner_name`=<owner name>
`owner_is_controller`=<whether owner is controller> | STABLE | diff --git a/docs/namespace-metrics.md b/docs/namespace-metrics.md index 3241d48de2..e46af4edce 100644 --- a/docs/namespace-metrics.md +++ b/docs/namespace-metrics.md @@ -2,6 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | +| kube_namespace_annotations | Gauge | `namespace`=<namespace-name>
`label_NS_ANNOTATION`=<NS_ANNOTATION> | STABLE | | kube_namespace_created | Gauge | `namespace`=<namespace-name> | STABLE | | kube_namespace_labels | Gauge | `namespace`=<namespace-name>
`label_NS_LABEL`=<NS_LABEL> | STABLE | | kube_namespace_status_condition | Gauge | `namespace`=<namespace-name>
`condition`=<NamespaceDeletionDiscoveryFailure\|NamespaceDeletionContentFailure\|NamespaceDeletionGroupVersionParsingFailure>
`status`=<true\|false\|unknown> | EXPERIMENTAL | diff --git a/docs/node-metrics.md b/docs/node-metrics.md index fd6a5d4550..f5761afa4d 100644 --- a/docs/node-metrics.md +++ b/docs/node-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Description | Unit (where applicable) | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------------------- | ----------- | ------ | -| kube_node_annotations | Gauge | Kubernetes annotations converted to Prometheus labels | | `node`=<node-address>
`annotation_NODE_LABEL`=<NODE_ANNOTATION> | STABLE | +| kube_node_annotations | Gauge | Kubernetes annotations converted to Prometheus labels | | `node`=<node-address>
`annotation_NODE_ANNOTATION`=<NODE_ANNOTATION> | STABLE | | kube_node_info | Gauge | Information about a cluster node| |`node`=<node-address>
`kernel_version`=<kernel-version>
`os_image`=<os-image-name>
`container_runtime_version`=<container-runtime-and-version-combination>
`kubelet_version`=<kubelet-version>
`kubeproxy_version`=<kubeproxy-version>
`pod_cidr`=<pod-cidr>
`provider_id`=<provider-id>
`internal_ip`=<internal-ip> | STABLE | | kube_node_labels | Gauge | Kubernetes labels converted to Prometheus labels | | `node`=<node-address>
`label_NODE_LABEL`=<NODE_LABEL> | STABLE | | kube_node_role | Gauge | The role of a cluster node | | `node`=<node-address>
`role`=<NODE_ROLE> | EXPERIMENTAL | diff --git a/docs/persistentvolume-metrics.md b/docs/persistentvolume-metrics.md index b16fccc483..7cef50481e 100644 --- a/docs/persistentvolume-metrics.md +++ b/docs/persistentvolume-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_persistentvolume_annotations | Gauge | `persistentvolume`=<persistentvolume-name>
`annotation_PERSISTENTVOLUME_LABEL`=<PERSISTENTVOLUME_ANNOTATION> | STABLE | +| kube_persistentvolume_annotations | Gauge | `persistentvolume`=<persistentvolume-name>
`annotation_PERSISTENTVOLUME_ANNOTATION`=<PERSISTENTVOLUME_ANNOTATION> | STABLE | | kube_persistentvolume_capacity_bytes | Gauge | `persistentvolume`=<pv-name> | STABLE | | kube_persistentvolume_status_phase | Gauge | `persistentvolume`=<pv-name>
`phase`=<Bound\|Failed\|Pending\|Available\|Released>| STABLE | | kube_persistentvolume_claim_ref | Gauge | `persistentvolume`=<pv-name>
`claim_namespace`=<>
`name`=<> | STABLE | diff --git a/docs/persistentvolumeclaim-metrics.md b/docs/persistentvolumeclaim-metrics.md index 14a367c4fc..6a2f2d16d9 100644 --- a/docs/persistentvolumeclaim-metrics.md +++ b/docs/persistentvolumeclaim-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_persistentvolumeclaim_annotations | Gauge | `persistentvolumeclaim`=<persistentvolumeclaim-name>
`namespace`=<persistentvolumeclaim-namespace>
`annotation_PERSISTENTVOLUMECLAIM_LABEL`=<PERSISTENTVOLUMECLAIM_ANNOATION> | STABLE | +| kube_persistentvolumeclaim_annotations | Gauge | `persistentvolumeclaim`=<persistentvolumeclaim-name>
`namespace`=<persistentvolumeclaim-namespace>
`annotation_PERSISTENTVOLUMECLAIM_ANNOTATION`=<PERSISTENTVOLUMECLAIM_ANNOATION> | STABLE | | kube_persistentvolumeclaim_access_mode | Gauge | `access_mode`=<persistentvolumeclaim-access-mode>
`namespace`=<persistentvolumeclaim-namespace>
`persistentvolumeclaim`=<persistentvolumeclaim-name> | STABLE | | kube_persistentvolumeclaim_info | Gauge | `namespace`=<persistentvolumeclaim-namespace>
`persistentvolumeclaim`=<persistentvolumeclaim-name>
`storageclass`=<persistentvolumeclaim-storageclassname>
`volumename`=<volumename> | STABLE | | kube_persistentvolumeclaim_labels | Gauge | `persistentvolumeclaim`=<persistentvolumeclaim-name>
`namespace`=<persistentvolumeclaim-namespace>
`label_PERSISTENTVOLUMECLAIM_LABEL`=<PERSISTENTVOLUMECLAIM_LABEL> | STABLE | diff --git a/docs/pod-metrics.md b/docs/pod-metrics.md index e5a0ce1090..3b10c7011f 100644 --- a/docs/pod-metrics.md +++ b/docs/pod-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Description | Unit (where applicable) | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------------------- | ----------- | ------ | -| kube_pod_annotations | Gauge | Kubernetes annotations converted to Prometheus labels | | `pod`=<pod-name>
`namespace`=<pod-namespace>
`annotation_POD_LABEL`=<POD_ANNOTATION>
`uid`=<pod-uid> | STABLE | +| kube_pod_annotations | Gauge | Kubernetes annotations converted to Prometheus labels | | `pod`=<pod-name>
`namespace`=<pod-namespace>
`annotation_POD_ANNOTATION`=<POD_ANNOTATION>
`uid`=<pod-uid> | STABLE | | kube_pod_info | Gauge | Information about pod | | `pod`=<pod-name>
`namespace`=<pod-namespace>
`host_ip`=<host-ip>
`pod_ip`=<pod-ip>
`node`=<node-name>
`created_by_kind`=<created_by_kind>
`created_by_name`=<created_by_name>
`uid`=<pod-uid>
`priority_class`=<priority_class>
`host_network`=<host_network>| STABLE | | kube_pod_start_time | Gauge | Start time in unix timestamp for a pod | seconds | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | STABLE | | kube_pod_completion_time | Gauge | Completion time in unix timestamp for a pod | seconds | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | STABLE | diff --git a/docs/replicaset-metrics.md b/docs/replicaset-metrics.md index 744a7aca4e..4c4d9a28a7 100644 --- a/docs/replicaset-metrics.md +++ b/docs/replicaset-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_replicaset_annotations | Gauge | `replicaset`=<replicaset-name>
`namespace`=<replicaset-namespace>
`annotation_REPLICASET_LABEL`=<REPLICASET_ANNOTATION> | STABLE | +| kube_replicaset_annotations | Gauge | `replicaset`=<replicaset-name>
`namespace`=<replicaset-namespace>
`annotation_REPLICASET_ANNOTATION`=<REPLICASET_ANNOTATION> | STABLE | | kube_replicaset_status_replicas | Gauge | `replicaset`=<replicaset-name>
`namespace`=<replicaset-namespace> | STABLE | | kube_replicaset_status_fully_labeled_replicas | Gauge | `replicaset`=<replicaset-name>
`namespace`=<replicaset-namespace> | STABLE | | kube_replicaset_status_ready_replicas | Gauge | `replicaset`=<replicaset-name>
`namespace`=<replicaset-namespace> | STABLE | diff --git a/docs/secret-metrics.md b/docs/secret-metrics.md index 16716faa04..a3e3752e0d 100644 --- a/docs/secret-metrics.md +++ b/docs/secret-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_secret_annotations | Gauge | `secret`=<secret-name>
`namespace`=<secret-namespace>
`annotations_SECRET_LABEL`=<SECRET_ANNOTATION> | STABLE | +| kube_secret_annotations | Gauge | `secret`=<secret-name>
`namespace`=<secret-namespace>
`annotations_SECRET_ANNOTATION`=<SECRET_ANNOTATION> | STABLE | | kube_secret_info | Gauge | `secret`=<secret-name>
`namespace`=<secret-namespace> | STABLE | | kube_secret_type | Gauge | `secret`=<secret-name>
`namespace`=<secret-namespace>
`type`=<secret-type> | STABLE | | kube_secret_labels | Gauge | `secret`=<secret-name>
`namespace`=<secret-namespace>
`label_SECRET_LABEL`=<SECRET_LABEL> | STABLE | diff --git a/docs/service-metrics.md b/docs/service-metrics.md index 1883ac55d3..88b92cc8b2 100644 --- a/docs/service-metrics.md +++ b/docs/service-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Description | Unit (where applicable) | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------------------- | ----------- | ------ | -| kube_service_annoations | Gauge | Kubernetes annotations converted to Prometheus labels | |`service`=<service-name>
`namespace`=<service-namespace>
`annotation_SERVICE_LABEL`=<SERVICE_ANNOTATION> | STABLE | +| kube_service_annotations | Gauge | Kubernetes annotations converted to Prometheus labels | |`service`=<service-name>
`namespace`=<service-namespace>
`annotation_SERVICE_ANNOTATION`=<SERVICE_ANNOTATION> | STABLE | | kube_service_info | Gauge | Information about service | |`service`=<service-name>
`namespace`=<service-namespace>
`cluster_ip`=<service cluster ip>
`external_name`=<service external name>
`load_balancer_ip`=<service load balancer ip> | STABLE | | kube_service_labels | Gauge | Kubernetes labels converted to Prometheus labels | |`service`=<service-name>
`namespace`=<service-namespace>
`label_SERVICE_LABEL`=<SERVICE_LABEL> | STABLE | | kube_service_created | Gauge | Unix creation timestamp | seconds |`service`=<service-name>
`namespace`=<service-namespace> | STABLE | diff --git a/docs/statefulset-metrics.md b/docs/statefulset-metrics.md index 0054144a56..3df474c760 100644 --- a/docs/statefulset-metrics.md +++ b/docs/statefulset-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_statefulset_annotations | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace>
`annotation_STATEFULSET_LABEL`=<STATEFULSET_ANNOTATION> | STABLE | +| kube_statefulset_annotations | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace>
`annotation_STATEFULSET_ANNOTATION`=<STATEFULSET_ANNOTATION> | STABLE | | kube_statefulset_status_replicas | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace> | STABLE | | kube_statefulset_status_replicas_current | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace> | STABLE | | kube_statefulset_status_replicas_ready | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace> | STABLE | diff --git a/docs/storageclass-metrics.md b/docs/storageclass-metrics.md index 843330280f..bc6c686a98 100644 --- a/docs/storageclass-metrics.md +++ b/docs/storageclass-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_storageclass_annotations | Gauge | `storageclass`=<storageclass-name>
`annotation_STORAGECLASS_LABEL`=<STORAGECLASS_ANNOTATION> | STABLE | +| kube_storageclass_annotations | Gauge | `storageclass`=<storageclass-name>
`annotation_STORAGECLASS_ANNOTATION`=<STORAGECLASS_ANNOTATION> | STABLE | | kube_storageclass_info | Gauge | `storageclass`=<storageclass-name>
`provisioner`=<storageclass-provisioner>
`reclaim_policy`=<storageclass-reclaimPolicy>
`volume_binding_mode`=<storageclass-volumeBindingMode> | STABLE | | kube_storageclass_labels | Gauge | `storageclass`=<storageclass-name>
`label_STORAGECLASS_LABEL`=<STORAGECLASS_LABEL> | STABLE | | kube_storageclass_created | Gauge | `storageclass`=<storageclass-name> | STABLE | From b60508b2cf67a44e1a8024e8b0ddaef45d0de186 Mon Sep 17 00:00:00 2001 From: Sylvain Rabot Date: Tue, 13 Jul 2021 11:28:27 +0200 Subject: [PATCH 5/9] Move option in the cli arguments list Signed-off-by: Sylvain Rabot --- docs/cli-arguments.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cli-arguments.md b/docs/cli-arguments.md index 3cec8e556e..d1db671ff6 100644 --- a/docs/cli-arguments.md +++ b/docs/cli-arguments.md @@ -38,8 +38,8 @@ Usage of ./kube-state-metrics: --log_file_max_size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800) --logtostderr log to standard error instead of files (default true) --metric-allowlist string Comma-separated list of metrics to be exposed. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive. - --metric-annotations-allowlist string Comma-separated list of Kubernetes annotations keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional annotations provide a list of resource names in their plural form and Kubernetes annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. A single '*' can be provided per resource instead to allow any annotations, but that has severe performance implications (Example: '=pods=[*]'). --metric-denylist string Comma-separated list of metrics not to be enabled. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive. + --metric-annotations-allowlist string Comma-separated list of Kubernetes annotations keys that will be used in the resource labels metric. By default the metric contains only name and namespace labels. To include additional annotations provide a list of resource names in their plural form and Kubernetes annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. A single '*' can be provided per resource instead to allow any annotations, but that has severe performance implications (Example: '=pods=[*]'). --metric-labels-allowlist string Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional labels provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any labels, but that has severe performance implications (Example: '=pods=[*]'). --namespaces string Comma-separated list of namespaces to be enabled. Defaults to "" --one_output If true, only write logs to their native severity level (vs also writing to each lower severity level) From 0e045365f4c891e109b9ef7d357df323ffb84375 Mon Sep 17 00:00:00 2001 From: Sylvain Rabot Date: Tue, 13 Jul 2021 11:29:10 +0200 Subject: [PATCH 6/9] Factorize some code Signed-off-by: Sylvain Rabot --- docs/cli-arguments.md | 2 +- internal/store/certificatesigningrequest.go | 4 +- internal/store/cronjob.go | 4 +- internal/store/daemonset.go | 4 +- internal/store/deployment.go | 4 +- internal/store/endpoint.go | 4 +- internal/store/horizontalpodautoscaler.go | 4 +- internal/store/ingress.go | 4 +- internal/store/job.go | 4 +- internal/store/namespace.go | 4 +- internal/store/networkpolicy.go | 4 +- internal/store/node.go | 4 +- internal/store/persistentvolume.go | 4 +- internal/store/persistentvolumeclaim.go | 2 +- internal/store/pod.go | 4 +- internal/store/replicaset.go | 4 +- internal/store/secret.go | 4 +- internal/store/service.go | 4 +- internal/store/statefulset.go | 4 +- internal/store/storageclass.go | 4 +- internal/store/utils.go | 45 +++++---------------- internal/store/utils_test.go | 2 +- internal/store/verticalpodautoscaler.go | 4 +- internal/store/volumeattachment.go | 2 +- 24 files changed, 53 insertions(+), 76 deletions(-) diff --git a/docs/cli-arguments.md b/docs/cli-arguments.md index d1db671ff6..3cec8e556e 100644 --- a/docs/cli-arguments.md +++ b/docs/cli-arguments.md @@ -38,8 +38,8 @@ Usage of ./kube-state-metrics: --log_file_max_size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800) --logtostderr log to standard error instead of files (default true) --metric-allowlist string Comma-separated list of metrics to be exposed. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive. + --metric-annotations-allowlist string Comma-separated list of Kubernetes annotations keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional annotations provide a list of resource names in their plural form and Kubernetes annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. A single '*' can be provided per resource instead to allow any annotations, but that has severe performance implications (Example: '=pods=[*]'). --metric-denylist string Comma-separated list of metrics not to be enabled. This list comprises of exact metric names and/or regex patterns. The allowlist and denylist are mutually exclusive. - --metric-annotations-allowlist string Comma-separated list of Kubernetes annotations keys that will be used in the resource labels metric. By default the metric contains only name and namespace labels. To include additional annotations provide a list of resource names in their plural form and Kubernetes annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. A single '*' can be provided per resource instead to allow any annotations, but that has severe performance implications (Example: '=pods=[*]'). --metric-labels-allowlist string Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the metric contains only name and namespace labels. To include additional labels provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any labels, but that has severe performance implications (Example: '=pods=[*]'). --namespaces string Comma-separated list of namespaces to be enabled. Defaults to "" --one_output If true, only write logs to their native severity level (vs also writing to each lower severity level) diff --git a/internal/store/certificatesigningrequest.go b/internal/store/certificatesigningrequest.go index b12e395e16..523d218b46 100644 --- a/internal/store/certificatesigningrequest.go +++ b/internal/store/certificatesigningrequest.go @@ -46,7 +46,7 @@ func csrMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat metric.Gauge, "", wrapCSRFunc(func(j *certv1.CertificateSigningRequest) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(j.Annotations, allowAnnotationsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", j.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ { @@ -64,7 +64,7 @@ func csrMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat metric.Gauge, "", wrapCSRFunc(func(j *certv1.CertificateSigningRequest) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(j.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", j.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/cronjob.go b/internal/store/cronjob.go index 955903feba..ae9abb60a5 100644 --- a/internal/store/cronjob.go +++ b/internal/store/cronjob.go @@ -49,7 +49,7 @@ func cronJobMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gen metric.Gauge, "", wrapCronJobFunc(func(j *batchv1beta1.CronJob) *metric.Family { - annotationKeys, annotationValues := createLabelKeysValues(j.Annotations, allowLabelsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("label", j.Annotations, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { @@ -67,7 +67,7 @@ func cronJobMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gen metric.Gauge, "", wrapCronJobFunc(func(j *batchv1beta1.CronJob) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(j.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", j.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/daemonset.go b/internal/store/daemonset.go index 8a76d58e06..07e3a38f1f 100644 --- a/internal/store/daemonset.go +++ b/internal/store/daemonset.go @@ -218,7 +218,7 @@ func daemonSetMetricFamilies(allowAnnotationsList, allowLabelsList []string) []g metric.Gauge, "", wrapDaemonSetFunc(func(d *v1.DaemonSet) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(d.Annotations, allowLabelsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", d.Annotations, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { @@ -236,7 +236,7 @@ func daemonSetMetricFamilies(allowAnnotationsList, allowLabelsList []string) []g metric.Gauge, "", wrapDaemonSetFunc(func(d *v1.DaemonSet) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(d.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", d.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/deployment.go b/internal/store/deployment.go index 6924d275dc..dd40b866c4 100644 --- a/internal/store/deployment.go +++ b/internal/store/deployment.go @@ -259,7 +259,7 @@ func deploymentMetricFamilies(allowAnnotationsList, allowLabelsList []string) [] metric.Gauge, "", wrapDeploymentFunc(func(d *v1.Deployment) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(d.Annotations, allowAnnotationsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", d.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ { @@ -277,7 +277,7 @@ func deploymentMetricFamilies(allowAnnotationsList, allowLabelsList []string) [] metric.Gauge, "", wrapDeploymentFunc(func(d *v1.Deployment) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(d.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", d.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/endpoint.go b/internal/store/endpoint.go index a262985a7e..7e56c3c516 100644 --- a/internal/store/endpoint.go +++ b/internal/store/endpoint.go @@ -81,7 +81,7 @@ func endpointMetricFamilies(allowAnnotationsList, allowLabelsList []string) []ge metric.Gauge, "", wrapEndpointFunc(func(e *v1.Endpoints) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(e.Annotations, allowAnnotationsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", e.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ { @@ -99,7 +99,7 @@ func endpointMetricFamilies(allowAnnotationsList, allowLabelsList []string) []ge metric.Gauge, "", wrapEndpointFunc(func(e *v1.Endpoints) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(e.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", e.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/horizontalpodautoscaler.go b/internal/store/horizontalpodautoscaler.go index 9582628af2..26bdec00ed 100644 --- a/internal/store/horizontalpodautoscaler.go +++ b/internal/store/horizontalpodautoscaler.go @@ -200,7 +200,7 @@ func hpaMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat metric.Gauge, "", wrapHPAFunc(func(a *autoscaling.HorizontalPodAutoscaler) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(a.Annotations, allowLabelsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", a.Annotations, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { @@ -218,7 +218,7 @@ func hpaMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat metric.Gauge, "", wrapHPAFunc(func(a *autoscaling.HorizontalPodAutoscaler) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(a.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", a.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/ingress.go b/internal/store/ingress.go index 137acf88b5..c05f16f7ce 100644 --- a/internal/store/ingress.go +++ b/internal/store/ingress.go @@ -61,7 +61,7 @@ func ingressMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gen metric.Gauge, "", wrapIngressFunc(func(i *networkingv1.Ingress) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(i.Annotations, allowLabelsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", i.Annotations, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { @@ -79,7 +79,7 @@ func ingressMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gen metric.Gauge, "", wrapIngressFunc(func(i *networkingv1.Ingress) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(i.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", i.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/job.go b/internal/store/job.go index b042f1ffd7..472954c41d 100644 --- a/internal/store/job.go +++ b/internal/store/job.go @@ -48,7 +48,7 @@ func jobMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat metric.Gauge, "", wrapJobFunc(func(j *v1batch.Job) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(j.Annotations, allowAnnotationsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", j.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ { @@ -66,7 +66,7 @@ func jobMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat metric.Gauge, "", wrapJobFunc(func(j *v1batch.Job) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(j.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", j.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/namespace.go b/internal/store/namespace.go index 5d256c13d8..aa6b5d5114 100644 --- a/internal/store/namespace.go +++ b/internal/store/namespace.go @@ -64,7 +64,7 @@ func namespaceMetricFamilies(allowAnnotationsList, allowLabelsList []string) []g metric.Gauge, "", wrapNamespaceFunc(func(n *v1.Namespace) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(n.Annotations, allowAnnotationsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", n.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ { @@ -82,7 +82,7 @@ func namespaceMetricFamilies(allowAnnotationsList, allowLabelsList []string) []g metric.Gauge, "", wrapNamespaceFunc(func(n *v1.Namespace) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(n.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", n.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/networkpolicy.go b/internal/store/networkpolicy.go index c9ee0df8ff..7798b0d98e 100644 --- a/internal/store/networkpolicy.go +++ b/internal/store/networkpolicy.go @@ -63,7 +63,7 @@ func networkPolicyMetricFamilies(allowAnnotationsList, allowLabelsList []string) metric.Gauge, "", wrapNetworkPolicyFunc(func(n *networkingv1.NetworkPolicy) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(n.Annotations, allowAnnotationsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", n.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ { @@ -81,7 +81,7 @@ func networkPolicyMetricFamilies(allowAnnotationsList, allowLabelsList []string) metric.Gauge, "", wrapNetworkPolicyFunc(func(n *networkingv1.NetworkPolicy) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(n.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", n.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/node.go b/internal/store/node.go index 3162897070..f1c3fc4e03 100644 --- a/internal/store/node.go +++ b/internal/store/node.go @@ -133,7 +133,7 @@ func createNodeAnnotationsGenerator(allowAnnotationsList []string) generator.Fam metric.Gauge, "", wrapNodeFunc(func(n *v1.Node) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(n.Annotations, allowAnnotationsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", n.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ { @@ -154,7 +154,7 @@ func createNodeLabelsGenerator(allowLabelsList []string) generator.FamilyGenerat metric.Gauge, "", wrapNodeFunc(func(n *v1.Node) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(n.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", n.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/persistentvolume.go b/internal/store/persistentvolume.go index a1348732e2..1d5b7e8704 100644 --- a/internal/store/persistentvolume.go +++ b/internal/store/persistentvolume.go @@ -81,7 +81,7 @@ func persistentVolumeMetricFamilies(allowAnnotationsList, allowLabelsList []stri metric.Gauge, "", wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(p.Annotations, allowAnnotationsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", p.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ { @@ -99,7 +99,7 @@ func persistentVolumeMetricFamilies(allowAnnotationsList, allowLabelsList []stri metric.Gauge, "", wrapPersistentVolumeFunc(func(p *v1.PersistentVolume) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(p.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", p.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/persistentvolumeclaim.go b/internal/store/persistentvolumeclaim.go index eeebaa2bf7..c29920c831 100644 --- a/internal/store/persistentvolumeclaim.go +++ b/internal/store/persistentvolumeclaim.go @@ -46,7 +46,7 @@ func persistentVolumeClaimMetricFamilies(allowAnnotationsList, allowLabelsList [ metric.Gauge, "", wrapPersistentVolumeClaimFunc(func(p *v1.PersistentVolumeClaim) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(p.Annotations, allowAnnotationsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", p.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/pod.go b/internal/store/pod.go index 9d3d46357e..49bd4a061d 100644 --- a/internal/store/pod.go +++ b/internal/store/pod.go @@ -1133,7 +1133,7 @@ func createPodAnnotationsGenerator(allowAnnotations []string) generator.FamilyGe metric.Gauge, "", wrapPodFunc(func(p *v1.Pod) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(p.Annotations, allowAnnotations) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", p.Annotations, allowAnnotations) m := metric.Metric{ LabelKeys: annotationKeys, LabelValues: annotationValues, @@ -1153,7 +1153,7 @@ func createPodLabelsGenerator(allowLabelsList []string) generator.FamilyGenerato metric.Gauge, "", wrapPodFunc(func(p *v1.Pod) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(p.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", p.Labels, allowLabelsList) m := metric.Metric{ LabelKeys: labelKeys, LabelValues: labelValues, diff --git a/internal/store/replicaset.go b/internal/store/replicaset.go index 1159a68388..027cd62772 100644 --- a/internal/store/replicaset.go +++ b/internal/store/replicaset.go @@ -205,7 +205,7 @@ func replicaSetMetricFamilies(allowAnnotationsList, allowLabelsList []string) [] metric.Gauge, "", wrapReplicaSetFunc(func(r *v1.ReplicaSet) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(r.Annotations, allowAnnotationsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", r.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ { @@ -223,7 +223,7 @@ func replicaSetMetricFamilies(allowAnnotationsList, allowLabelsList []string) [] metric.Gauge, "", wrapReplicaSetFunc(func(r *v1.ReplicaSet) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(r.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", r.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/secret.go b/internal/store/secret.go index f443f9a76f..f63290a1a0 100644 --- a/internal/store/secret.go +++ b/internal/store/secret.go @@ -78,7 +78,7 @@ func secretMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gene metric.Gauge, "", wrapSecretFunc(func(s *v1.Secret) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(s.Annotations, allowAnnotationsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", s.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ { @@ -97,7 +97,7 @@ func secretMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gene metric.Gauge, "", wrapSecretFunc(func(s *v1.Secret) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(s.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", s.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/service.go b/internal/store/service.go index 91f170f31c..e382e89729 100644 --- a/internal/store/service.go +++ b/internal/store/service.go @@ -92,7 +92,7 @@ func serviceMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gen metric.Gauge, "", wrapSvcFunc(func(s *v1.Service) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(s.Annotations, allowAnnotationsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", s.Annotations, allowAnnotationsList) m := metric.Metric{ LabelKeys: annotationKeys, LabelValues: annotationValues, @@ -107,7 +107,7 @@ func serviceMetricFamilies(allowAnnotationsList, allowLabelsList []string) []gen metric.Gauge, "", wrapSvcFunc(func(s *v1.Service) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(s.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", s.Labels, allowLabelsList) m := metric.Metric{ LabelKeys: labelKeys, LabelValues: labelValues, diff --git a/internal/store/statefulset.go b/internal/store/statefulset.go index 9d3f096c42..9f155b8d85 100644 --- a/internal/store/statefulset.go +++ b/internal/store/statefulset.go @@ -174,7 +174,7 @@ func statefulSetMetricFamilies(allowAnnotationsList, allowLabelsList []string) [ metric.Gauge, "", wrapStatefulSetFunc(func(s *v1.StatefulSet) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(s.Annotations, allowAnnotationsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", s.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ { @@ -192,7 +192,7 @@ func statefulSetMetricFamilies(allowAnnotationsList, allowLabelsList []string) [ metric.Gauge, "", wrapStatefulSetFunc(func(s *v1.StatefulSet) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(s.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", s.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/storageclass.go b/internal/store/storageclass.go index 439c6737f5..4918e65e6d 100644 --- a/internal/store/storageclass.go +++ b/internal/store/storageclass.go @@ -87,7 +87,7 @@ func storageClassMetricFamilies(allowAnnotationsList, allowLabelsList []string) metric.Gauge, "", wrapStorageClassFunc(func(s *storagev1.StorageClass) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(s.Annotations, allowAnnotationsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", s.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ { @@ -105,7 +105,7 @@ func storageClassMetricFamilies(allowAnnotationsList, allowLabelsList []string) metric.Gauge, "", wrapStorageClassFunc(func(s *storagev1.StorageClass) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(s.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", s.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/utils.go b/internal/store/utils.go index c7d405dcc0..8872825838 100644 --- a/internal/store/utils.go +++ b/internal/store/utils.go @@ -73,12 +73,8 @@ func addConditionMetrics(cs v1.ConditionStatus) []*metric.Metric { return ms } -func kubeAnnotationssToPrometheusLabels(annotations map[string]string) ([]string, []string) { - return mapToPrometheusLabels(annotations, "annotation") -} - -func kubeLabelsToPrometheusLabels(labels map[string]string) ([]string, []string) { - return mapToPrometheusLabels(labels, "label") +func kubeMapToPrometheusLabels(prefix string, input map[string]string) ([]string, []string) { + return mapToPrometheusLabels(input, prefix) } func mapToPrometheusLabels(labels map[string]string, prefix string) ([]string, []string) { @@ -176,42 +172,23 @@ func isPrefixedNativeResource(name v1.ResourceName) bool { return strings.Contains(string(name), v1.ResourceDefaultNamespacePrefix) } -// createAnnotationKeysValues takes in passed kubernetes annotations and allowed list in kubernetes label format -// it returns only those allowed annotations that exist in the list converting them to Prometheus labels. -func createAnnotationKeysValues(allKubeAnnotations map[string]string, allowList []string) ([]string, []string) { - allowedKubeAnnotations := make(map[string]string) - - if len(allowList) > 0 { - if allowList[0] == options.LabelWildcard { - return kubeAnnotationssToPrometheusLabels(allKubeAnnotations) - } - - for _, l := range allowList { - v, found := allKubeAnnotations[l] - if found { - allowedKubeAnnotations[l] = v - } - } - } - return kubeAnnotationssToPrometheusLabels(allowedKubeAnnotations) -} - -// createLabelKeysValues takes in passed kubernetes labels and allowed list in kubernetes label format -// it returns only those allowed labels that exist in the list converting them to Prometheus labels. -func createLabelKeysValues(allKubeLabels map[string]string, allowList []string) ([]string, []string) { - allowedKubeLabels := make(map[string]string) +// createPrometheusLabelKeysValues takes in passed kubernetes annotations/labels +// and associated allowed list in kubernetes label format. +// It returns only those allowed annotations/labels that exist in the list and converts them to Prometheus labels. +func createPrometheusLabelKeysValues(prefix string, allKubeData map[string]string, allowList []string) ([]string, []string) { + allowedKubeData := make(map[string]string) if len(allowList) > 0 { if allowList[0] == options.LabelWildcard { - return kubeLabelsToPrometheusLabels(allKubeLabels) + return kubeMapToPrometheusLabels(prefix, allKubeData) } for _, l := range allowList { - v, found := allKubeLabels[l] + v, found := allKubeData[l] if found { - allowedKubeLabels[l] = v + allowedKubeData[l] = v } } } - return kubeLabelsToPrometheusLabels(allowedKubeLabels) + return kubeMapToPrometheusLabels(prefix, allKubeData) } diff --git a/internal/store/utils_test.go b/internal/store/utils_test.go index 06e2cb4ac0..a2d914550c 100644 --- a/internal/store/utils_test.go +++ b/internal/store/utils_test.go @@ -246,7 +246,7 @@ func TestKubeLabelsToPrometheusLabels(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("kubelabels input=%v , expected prometheus keys=%v, expected prometheus values=%v", tc.kubeLabels, tc.expectKeys, tc.expectValues), func(t *testing.T) { - labelKeys, labelValues := kubeLabelsToPrometheusLabels(tc.kubeLabels) + labelKeys, labelValues := kubeMapToPrometheusLabels("label", tc.kubeLabels) if len(labelKeys) != len(tc.expectKeys) { t.Errorf("Got Prometheus label keys with len %d but expected %d", len(labelKeys), len(tc.expectKeys)) } diff --git a/internal/store/verticalpodautoscaler.go b/internal/store/verticalpodautoscaler.go index 1783ef0b77..90d3fe8daa 100644 --- a/internal/store/verticalpodautoscaler.go +++ b/internal/store/verticalpodautoscaler.go @@ -49,7 +49,7 @@ func vpaMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat metric.Gauge, "", wrapVPAFunc(func(a *autoscaling.VerticalPodAutoscaler) *metric.Family { - annotationKeys, annotationValues := createAnnotationKeysValues(a.Annotations, allowAnnotationsList) + annotationKeys, annotationValues := createPrometheusLabelKeysValues("annotation", a.Annotations, allowAnnotationsList) return &metric.Family{ Metrics: []*metric.Metric{ { @@ -67,7 +67,7 @@ func vpaMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat metric.Gauge, "", wrapVPAFunc(func(a *autoscaling.VerticalPodAutoscaler) *metric.Family { - labelKeys, labelValues := createLabelKeysValues(a.Labels, allowLabelsList) + labelKeys, labelValues := createPrometheusLabelKeysValues("label", a.Labels, allowLabelsList) return &metric.Family{ Metrics: []*metric.Metric{ { diff --git a/internal/store/volumeattachment.go b/internal/store/volumeattachment.go index 228a8c2bb9..82cc3d45b9 100644 --- a/internal/store/volumeattachment.go +++ b/internal/store/volumeattachment.go @@ -42,7 +42,7 @@ var ( metric.Gauge, "", wrapVolumeAttachmentFunc(func(va *storagev1.VolumeAttachment) *metric.Family { - labelKeys, labelValues := kubeLabelsToPrometheusLabels(va.Labels) + labelKeys, labelValues := kubeMapToPrometheusLabels("label", va.Labels) return &metric.Family{ Metrics: []*metric.Metric{ { From 517b46cf1d4744d0a7b17a816d85f0f1d00455bd Mon Sep 17 00:00:00 2001 From: Sylvain Rabot Date: Tue, 13 Jul 2021 17:41:23 +0200 Subject: [PATCH 7/9] Fix use of wrong var Signed-off-by: Sylvain Rabot --- internal/store/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/store/utils.go b/internal/store/utils.go index 8872825838..51c38ac19e 100644 --- a/internal/store/utils.go +++ b/internal/store/utils.go @@ -190,5 +190,5 @@ func createPrometheusLabelKeysValues(prefix string, allKubeData map[string]strin } } } - return kubeMapToPrometheusLabels(prefix, allKubeData) + return kubeMapToPrometheusLabels(prefix, allowedKubeData) } From e3688234a3cbed1829a425cb2a8b949fc22a7906 Mon Sep 17 00:00:00 2001 From: Sylvain Rabot Date: Sun, 15 Aug 2021 18:11:36 +0200 Subject: [PATCH 8/9] Mark new annotations metrics as EXPERIMENTAL Signed-off-by: Sylvain Rabot --- docs/certificatesigningrequest-metrics.md | 2 +- docs/cronjob-metrics.md | 2 +- docs/daemonset-metrics.md | 2 +- docs/deployment-metrics.md | 2 +- docs/endpoint-metrics.md | 2 +- docs/ingress-metrics.md | 2 +- docs/job-metrics.md | 2 +- docs/namespace-metrics.md | 2 +- docs/node-metrics.md | 2 +- docs/persistentvolume-metrics.md | 2 +- docs/persistentvolumeclaim-metrics.md | 2 +- docs/pod-metrics.md | 2 +- docs/replicaset-metrics.md | 2 +- docs/secret-metrics.md | 2 +- docs/service-metrics.md | 2 +- docs/statefulset-metrics.md | 2 +- docs/storageclass-metrics.md | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/certificatesigningrequest-metrics.md b/docs/certificatesigningrequest-metrics.md index 863daa9322..ca52fae725 100644 --- a/docs/certificatesigningrequest-metrics.md +++ b/docs/certificatesigningrequest-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_certificatesigningrequest_annotations | Gauge | `certificatesigningrequest`=<certificatesigningrequest-name>
`signer_name`=<certificatesigningrequest-signer-name>| STABLE | +| kube_certificatesigningrequest_annotations | Gauge | `certificatesigningrequest`=<certificatesigningrequest-name>
`signer_name`=<certificatesigningrequest-signer-name>| EXPERIMENTAL | | kube_certificatesigningrequest_created| Gauge | `certificatesigningrequest`=<certificatesigningrequest-name>
`signer_name`=<certificatesigningrequest-signer-name>| STABLE | | kube_certificatesigningrequest_condition | Gauge | `certificatesigningrequest`=<certificatesigningrequest-name>
`signer_name`=<certificatesigningrequest-signer-name>
`condition`=<approved\|denied> | STABLE | | kube_certificatesigningrequest_labels | Gauge | `certificatesigningrequest`=<certificatesigningrequest-name>
`signer_name`=<certificatesigningrequest-signer-name>| STABLE | diff --git a/docs/cronjob-metrics.md b/docs/cronjob-metrics.md index d8e76ffadc..e1a377cb0d 100644 --- a/docs/cronjob-metrics.md +++ b/docs/cronjob-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_cronjob_annotations | Gauge | `cronjob`=<cronjob-name>
`namespace`=<cronjob-namespace>
`annotation_CRONJOB_ANNOTATION`=<CRONJOB_ANNOTATION> | STABLE +| kube_cronjob_annotations | Gauge | `cronjob`=<cronjob-name>
`namespace`=<cronjob-namespace>
`annotation_CRONJOB_ANNOTATION`=<CRONJOB_ANNOTATION> | EXPERIMENTAL | kube_cronjob_info | Gauge | `cronjob`=<cronjob-name>
`namespace`=<cronjob-namespace>
`schedule`=<schedule>
`concurrency_policy`=<concurrency-policy> | STABLE | kube_cronjob_labels | Gauge | `cronjob`=<cronjob-name>
`namespace`=<cronjob-namespace>
`label_CRONJOB_LABEL`=<CRONJOB_LABEL> | STABLE | kube_cronjob_created | Gauge | `cronjob`=<cronjob-name>
`namespace`=<cronjob-namespace> | STABLE diff --git a/docs/daemonset-metrics.md b/docs/daemonset-metrics.md index bb80159650..9a49b21158 100644 --- a/docs/daemonset-metrics.md +++ b/docs/daemonset-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_daemonset_annotations | Gauge | `daemonset`=<daemonset-name>
`namespace`=<daemonset-namespace>
`annotation_DAEMONSET_ANNOTATION`=<DAEMONSET_ANNOTATION> | STABLE | +| kube_daemonset_annotations | Gauge | `daemonset`=<daemonset-name>
`namespace`=<daemonset-namespace>
`annotation_DAEMONSET_ANNOTATION`=<DAEMONSET_ANNOTATION> | EXPERIMENTAL | | kube_daemonset_created | Gauge | `daemonset`=<daemonset-name>
`namespace`=<daemonset-namespace> | STABLE | | kube_daemonset_status_current_number_scheduled | Gauge | `daemonset`=<daemonset-name>
`namespace`=<daemonset-namespace> | STABLE | | kube_daemonset_status_desired_number_scheduled | Gauge | `daemonset`=<daemonset-name>
`namespace`=<daemonset-namespace> | STABLE | diff --git a/docs/deployment-metrics.md b/docs/deployment-metrics.md index 8b3ef5810f..425115c2cf 100644 --- a/docs/deployment-metrics.md +++ b/docs/deployment-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_deployment_annotations | Gauge | `deployment`=<deployment-name>
`namespace`=<deployment-namespace>
`annotation_DEPLOYMENT_ANNOTATION`=<DEPLOYMENT_ANNOTATION> | STABLE | +| kube_deployment_annotations | Gauge | `deployment`=<deployment-name>
`namespace`=<deployment-namespace>
`annotation_DEPLOYMENT_ANNOTATION`=<DEPLOYMENT_ANNOTATION> | EXPERIMENTAL | | kube_deployment_status_replicas | Gauge | `deployment`=<deployment-name>
`namespace`=<deployment-namespace> | STABLE | | kube_deployment_status_replicas_available | Gauge | `deployment`=<deployment-name>
`namespace`=<deployment-namespace> | STABLE | | kube_deployment_status_replicas_unavailable | Gauge | `deployment`=<deployment-name>
`namespace`=<deployment-namespace> | STABLE | diff --git a/docs/endpoint-metrics.md b/docs/endpoint-metrics.md index 1006ae6f1d..d17211e008 100644 --- a/docs/endpoint-metrics.md +++ b/docs/endpoint-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_endpoint_annotations | Gauge | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace>
`annotation_ENDPOINT_ANNOTATION`=<ENDPOINT_ANNOTATION> | STABLE | +| kube_endpoint_annotations | Gauge | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace>
`annotation_ENDPOINT_ANNOTATION`=<ENDPOINT_ANNOTATION> | EXPERIMENTAL | | kube_endpoint_address_not_ready | Gauge | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace> | STABLE | | kube_endpoint_address_available | Gauge | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace> | STABLE | | kube_endpoint_info | Gauge | `endpoint`=<endpoint-name>
`namespace`=<endpoint-namespace> | STABLE | diff --git a/docs/ingress-metrics.md b/docs/ingress-metrics.md index 0bbe307dfb..4af1c20a9f 100644 --- a/docs/ingress-metrics.md +++ b/docs/ingress-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_ingress_annotations | Gauge | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`annotation_INGRESS_ANNOTATION`=<ANNOTATION_LABEL> | STABLE | +| kube_ingress_annotations | Gauge | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`annotation_INGRESS_ANNOTATION`=<ANNOTATION_LABEL> | EXPERIMENTAL | | kube_ingress_info | Gauge | `ingress`=<ingress-name>
`namespace`=<ingress-namespace> | STABLE | | kube_ingress_labels | Gauge | `ingress`=<ingress-name>
`namespace`=<ingress-namespace>
`label_INGRESS_LABEL`=<INGRESS_LABEL> | STABLE | | kube_ingress_created | Gauge | `ingress`=<ingress-name>
`namespace`=<ingress-namespace> | STABLE | diff --git a/docs/job-metrics.md b/docs/job-metrics.md index dd95d8169e..6d82a882d3 100644 --- a/docs/job-metrics.md +++ b/docs/job-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_job_annotations | Gauge | `job_name`=<job-name>
`namespace`=<job-namespace>
`annotation_JOB_ANNOTATION`=<JOB_ANNOTATION> | STABLE | +| kube_job_annotations | Gauge | `job_name`=<job-name>
`namespace`=<job-namespace>
`annotation_JOB_ANNOTATION`=<JOB_ANNOTATION> | EXPERIMENTAL | | kube_job_info | Gauge | `job_name`=<job-name>
`namespace`=<job-namespace> | STABLE | | kube_job_labels | Gauge | `job_name`=<job-name>
`namespace`=<job-namespace>
`label_JOB_LABEL`=<JOB_LABEL> | STABLE | | kube_job_owner | Gauge | `job_name`=<job-name>
`namespace`=<job-namespace>
`owner_kind`=<owner kind>
`owner_name`=<owner name>
`owner_is_controller`=<whether owner is controller> | STABLE | diff --git a/docs/namespace-metrics.md b/docs/namespace-metrics.md index e46af4edce..5bea8fa8d3 100644 --- a/docs/namespace-metrics.md +++ b/docs/namespace-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_namespace_annotations | Gauge | `namespace`=<namespace-name>
`label_NS_ANNOTATION`=<NS_ANNOTATION> | STABLE | +| kube_namespace_annotations | Gauge | `namespace`=<namespace-name>
`label_NS_ANNOTATION`=<NS_ANNOTATION> | EXPERIMENTAL | | kube_namespace_created | Gauge | `namespace`=<namespace-name> | STABLE | | kube_namespace_labels | Gauge | `namespace`=<namespace-name>
`label_NS_LABEL`=<NS_LABEL> | STABLE | | kube_namespace_status_condition | Gauge | `namespace`=<namespace-name>
`condition`=<NamespaceDeletionDiscoveryFailure\|NamespaceDeletionContentFailure\|NamespaceDeletionGroupVersionParsingFailure>
`status`=<true\|false\|unknown> | EXPERIMENTAL | diff --git a/docs/node-metrics.md b/docs/node-metrics.md index f5761afa4d..b159f1ae0b 100644 --- a/docs/node-metrics.md +++ b/docs/node-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Description | Unit (where applicable) | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------------------- | ----------- | ------ | -| kube_node_annotations | Gauge | Kubernetes annotations converted to Prometheus labels | | `node`=<node-address>
`annotation_NODE_ANNOTATION`=<NODE_ANNOTATION> | STABLE | +| kube_node_annotations | Gauge | Kubernetes annotations converted to Prometheus labels | | `node`=<node-address>
`annotation_NODE_ANNOTATION`=<NODE_ANNOTATION> | EXPERIMENTAL | | kube_node_info | Gauge | Information about a cluster node| |`node`=<node-address>
`kernel_version`=<kernel-version>
`os_image`=<os-image-name>
`container_runtime_version`=<container-runtime-and-version-combination>
`kubelet_version`=<kubelet-version>
`kubeproxy_version`=<kubeproxy-version>
`pod_cidr`=<pod-cidr>
`provider_id`=<provider-id>
`internal_ip`=<internal-ip> | STABLE | | kube_node_labels | Gauge | Kubernetes labels converted to Prometheus labels | | `node`=<node-address>
`label_NODE_LABEL`=<NODE_LABEL> | STABLE | | kube_node_role | Gauge | The role of a cluster node | | `node`=<node-address>
`role`=<NODE_ROLE> | EXPERIMENTAL | diff --git a/docs/persistentvolume-metrics.md b/docs/persistentvolume-metrics.md index 7cef50481e..241d7ebe83 100644 --- a/docs/persistentvolume-metrics.md +++ b/docs/persistentvolume-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_persistentvolume_annotations | Gauge | `persistentvolume`=<persistentvolume-name>
`annotation_PERSISTENTVOLUME_ANNOTATION`=<PERSISTENTVOLUME_ANNOTATION> | STABLE | +| kube_persistentvolume_annotations | Gauge | `persistentvolume`=<persistentvolume-name>
`annotation_PERSISTENTVOLUME_ANNOTATION`=<PERSISTENTVOLUME_ANNOTATION> | EXPERIMENTAL | | kube_persistentvolume_capacity_bytes | Gauge | `persistentvolume`=<pv-name> | STABLE | | kube_persistentvolume_status_phase | Gauge | `persistentvolume`=<pv-name>
`phase`=<Bound\|Failed\|Pending\|Available\|Released>| STABLE | | kube_persistentvolume_claim_ref | Gauge | `persistentvolume`=<pv-name>
`claim_namespace`=<>
`name`=<> | STABLE | diff --git a/docs/persistentvolumeclaim-metrics.md b/docs/persistentvolumeclaim-metrics.md index 6a2f2d16d9..7c786e351b 100644 --- a/docs/persistentvolumeclaim-metrics.md +++ b/docs/persistentvolumeclaim-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_persistentvolumeclaim_annotations | Gauge | `persistentvolumeclaim`=<persistentvolumeclaim-name>
`namespace`=<persistentvolumeclaim-namespace>
`annotation_PERSISTENTVOLUMECLAIM_ANNOTATION`=<PERSISTENTVOLUMECLAIM_ANNOATION> | STABLE | +| kube_persistentvolumeclaim_annotations | Gauge | `persistentvolumeclaim`=<persistentvolumeclaim-name>
`namespace`=<persistentvolumeclaim-namespace>
`annotation_PERSISTENTVOLUMECLAIM_ANNOTATION`=<PERSISTENTVOLUMECLAIM_ANNOATION> | EXPERIMENTAL | | kube_persistentvolumeclaim_access_mode | Gauge | `access_mode`=<persistentvolumeclaim-access-mode>
`namespace`=<persistentvolumeclaim-namespace>
`persistentvolumeclaim`=<persistentvolumeclaim-name> | STABLE | | kube_persistentvolumeclaim_info | Gauge | `namespace`=<persistentvolumeclaim-namespace>
`persistentvolumeclaim`=<persistentvolumeclaim-name>
`storageclass`=<persistentvolumeclaim-storageclassname>
`volumename`=<volumename> | STABLE | | kube_persistentvolumeclaim_labels | Gauge | `persistentvolumeclaim`=<persistentvolumeclaim-name>
`namespace`=<persistentvolumeclaim-namespace>
`label_PERSISTENTVOLUMECLAIM_LABEL`=<PERSISTENTVOLUMECLAIM_LABEL> | STABLE | diff --git a/docs/pod-metrics.md b/docs/pod-metrics.md index 3b10c7011f..424506bb1d 100644 --- a/docs/pod-metrics.md +++ b/docs/pod-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Description | Unit (where applicable) | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------------------- | ----------- | ------ | -| kube_pod_annotations | Gauge | Kubernetes annotations converted to Prometheus labels | | `pod`=<pod-name>
`namespace`=<pod-namespace>
`annotation_POD_ANNOTATION`=<POD_ANNOTATION>
`uid`=<pod-uid> | STABLE | +| kube_pod_annotations | Gauge | Kubernetes annotations converted to Prometheus labels | | `pod`=<pod-name>
`namespace`=<pod-namespace>
`annotation_POD_ANNOTATION`=<POD_ANNOTATION>
`uid`=<pod-uid> | EXPERIMENTAL | | kube_pod_info | Gauge | Information about pod | | `pod`=<pod-name>
`namespace`=<pod-namespace>
`host_ip`=<host-ip>
`pod_ip`=<pod-ip>
`node`=<node-name>
`created_by_kind`=<created_by_kind>
`created_by_name`=<created_by_name>
`uid`=<pod-uid>
`priority_class`=<priority_class>
`host_network`=<host_network>| STABLE | | kube_pod_start_time | Gauge | Start time in unix timestamp for a pod | seconds | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | STABLE | | kube_pod_completion_time | Gauge | Completion time in unix timestamp for a pod | seconds | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | STABLE | diff --git a/docs/replicaset-metrics.md b/docs/replicaset-metrics.md index 4c4d9a28a7..d4bb9c38d0 100644 --- a/docs/replicaset-metrics.md +++ b/docs/replicaset-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_replicaset_annotations | Gauge | `replicaset`=<replicaset-name>
`namespace`=<replicaset-namespace>
`annotation_REPLICASET_ANNOTATION`=<REPLICASET_ANNOTATION> | STABLE | +| kube_replicaset_annotations | Gauge | `replicaset`=<replicaset-name>
`namespace`=<replicaset-namespace>
`annotation_REPLICASET_ANNOTATION`=<REPLICASET_ANNOTATION> | EXPERIMENTAL | | kube_replicaset_status_replicas | Gauge | `replicaset`=<replicaset-name>
`namespace`=<replicaset-namespace> | STABLE | | kube_replicaset_status_fully_labeled_replicas | Gauge | `replicaset`=<replicaset-name>
`namespace`=<replicaset-namespace> | STABLE | | kube_replicaset_status_ready_replicas | Gauge | `replicaset`=<replicaset-name>
`namespace`=<replicaset-namespace> | STABLE | diff --git a/docs/secret-metrics.md b/docs/secret-metrics.md index a3e3752e0d..b5c4beeed6 100644 --- a/docs/secret-metrics.md +++ b/docs/secret-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_secret_annotations | Gauge | `secret`=<secret-name>
`namespace`=<secret-namespace>
`annotations_SECRET_ANNOTATION`=<SECRET_ANNOTATION> | STABLE | +| kube_secret_annotations | Gauge | `secret`=<secret-name>
`namespace`=<secret-namespace>
`annotations_SECRET_ANNOTATION`=<SECRET_ANNOTATION> | EXPERIMENTAL | | kube_secret_info | Gauge | `secret`=<secret-name>
`namespace`=<secret-namespace> | STABLE | | kube_secret_type | Gauge | `secret`=<secret-name>
`namespace`=<secret-namespace>
`type`=<secret-type> | STABLE | | kube_secret_labels | Gauge | `secret`=<secret-name>
`namespace`=<secret-namespace>
`label_SECRET_LABEL`=<SECRET_LABEL> | STABLE | diff --git a/docs/service-metrics.md b/docs/service-metrics.md index 88b92cc8b2..80207584c6 100644 --- a/docs/service-metrics.md +++ b/docs/service-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Description | Unit (where applicable) | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------------------- | ----------- | ------ | -| kube_service_annotations | Gauge | Kubernetes annotations converted to Prometheus labels | |`service`=<service-name>
`namespace`=<service-namespace>
`annotation_SERVICE_ANNOTATION`=<SERVICE_ANNOTATION> | STABLE | +| kube_service_annotations | Gauge | Kubernetes annotations converted to Prometheus labels | |`service`=<service-name>
`namespace`=<service-namespace>
`annotation_SERVICE_ANNOTATION`=<SERVICE_ANNOTATION> | EXPERIMENTAL | | kube_service_info | Gauge | Information about service | |`service`=<service-name>
`namespace`=<service-namespace>
`cluster_ip`=<service cluster ip>
`external_name`=<service external name>
`load_balancer_ip`=<service load balancer ip> | STABLE | | kube_service_labels | Gauge | Kubernetes labels converted to Prometheus labels | |`service`=<service-name>
`namespace`=<service-namespace>
`label_SERVICE_LABEL`=<SERVICE_LABEL> | STABLE | | kube_service_created | Gauge | Unix creation timestamp | seconds |`service`=<service-name>
`namespace`=<service-namespace> | STABLE | diff --git a/docs/statefulset-metrics.md b/docs/statefulset-metrics.md index 3df474c760..ca6b7114cc 100644 --- a/docs/statefulset-metrics.md +++ b/docs/statefulset-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_statefulset_annotations | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace>
`annotation_STATEFULSET_ANNOTATION`=<STATEFULSET_ANNOTATION> | STABLE | +| kube_statefulset_annotations | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace>
`annotation_STATEFULSET_ANNOTATION`=<STATEFULSET_ANNOTATION> | EXPERIMENTAL | | kube_statefulset_status_replicas | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace> | STABLE | | kube_statefulset_status_replicas_current | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace> | STABLE | | kube_statefulset_status_replicas_ready | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace> | STABLE | diff --git a/docs/storageclass-metrics.md b/docs/storageclass-metrics.md index bc6c686a98..d5f4088fb8 100644 --- a/docs/storageclass-metrics.md +++ b/docs/storageclass-metrics.md @@ -2,7 +2,7 @@ | Metric name| Metric type | Labels/tags | Status | | ---------- | ----------- | ----------- | ----------- | -| kube_storageclass_annotations | Gauge | `storageclass`=<storageclass-name>
`annotation_STORAGECLASS_ANNOTATION`=<STORAGECLASS_ANNOTATION> | STABLE | +| kube_storageclass_annotations | Gauge | `storageclass`=<storageclass-name>
`annotation_STORAGECLASS_ANNOTATION`=<STORAGECLASS_ANNOTATION> | EXPERIMENTAL | | kube_storageclass_info | Gauge | `storageclass`=<storageclass-name>
`provisioner`=<storageclass-provisioner>
`reclaim_policy`=<storageclass-reclaimPolicy>
`volume_binding_mode`=<storageclass-volumeBindingMode> | STABLE | | kube_storageclass_labels | Gauge | `storageclass`=<storageclass-name>
`label_STORAGECLASS_LABEL`=<STORAGECLASS_LABEL> | STABLE | | kube_storageclass_created | Gauge | `storageclass`=<storageclass-name> | STABLE | From 81db7e0b78075eee8d34f7f1eb65a9de488f3a97 Mon Sep 17 00:00:00 2001 From: Sylvain Rabot Date: Mon, 16 Aug 2021 13:45:51 +0200 Subject: [PATCH 9/9] Fix kube_horizontalpodautoscaler_annotations status Co-authored-by: Damien Grisonnet --- docs/horizontalpodautoscaler-metrics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/horizontalpodautoscaler-metrics.md b/docs/horizontalpodautoscaler-metrics.md index d8116f8691..518f34ab58 100644 --- a/docs/horizontalpodautoscaler-metrics.md +++ b/docs/horizontalpodautoscaler-metrics.md @@ -2,7 +2,7 @@ | Metric name | Metric type | Labels/tags | Status | | -------------------------------- | ----------- | ------------------------------------------------------------- | ------ | -| kube_horizontalpodautoscaler_annotations | Gauge | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | STABLE | +| kube_horizontalpodautoscaler_annotations | Gauge | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | EXPERIMENTAL | | kube_horizontalpodautoscaler_labels | Gauge | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | STABLE | | kube_horizontalpodautoscaler_metadata_generation | Gauge | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | STABLE | | kube_horizontalpodautoscaler_spec_max_replicas | Gauge | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | STABLE |