diff --git a/docs/metrics/workload/horizontalpodautoscaler-metrics.md b/docs/metrics/workload/horizontalpodautoscaler-metrics.md index 383bdca13f..5a6ccf4dde 100644 --- a/docs/metrics/workload/horizontalpodautoscaler-metrics.md +++ b/docs/metrics/workload/horizontalpodautoscaler-metrics.md @@ -1,15 +1,19 @@ # Horizontal Pod Autoscaler Metrics -| Metric name | Metric type | Description | Labels/tags | Status | -| ---------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | -| kube_horizontalpodautoscaler_info | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace>
`scaletargetref_api_version`=<hpa-target-api-version>
`scaletargetref_kind`=<hpa-target-kind>
`scaletargetref_name`=<hpa-target-name> | EXPERIMENTAL | -| kube_horizontalpodautoscaler_annotations | Gauge | Kubernetes annotations converted to Prometheus labels controlled via [--metric-annotations-allowlist](../../developer/cli-arguments.md) | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | EXPERIMENTAL | -| kube_horizontalpodautoscaler_labels | Gauge | Kubernetes labels converted to Prometheus labels controlled via [--metric-labels-allowlist](../../developer/cli-arguments.md) | `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 | -| kube_horizontalpodautoscaler_spec_min_replicas | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | STABLE | -| kube_horizontalpodautoscaler_spec_target_metric | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace>
`metric_name`=<metric-name>
`metric_target_type`=<value\|utilization\|average> | EXPERIMENTAL | -| kube_horizontalpodautoscaler_status_target_metric | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace>
`metric_name`=<metric-name>
`metric_target_type`=<value\|utilization\|average> | EXPERIMENTAL | -| kube_horizontalpodautoscaler_status_condition | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace>
`condition`=<hpa-condition>
`status`=<true\|false\|unknown> | STABLE | -| kube_horizontalpodautoscaler_status_current_replicas | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | STABLE | -| kube_horizontalpodautoscaler_status_desired_replicas | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | STABLE | +| Metric name | Metric type | Description | Labels/tags | Status | +| ---------------------------------------------------------------| ----------- | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | +| kube_horizontalpodautoscaler_info | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace>
`scaletargetref_api_version`=<hpa-target-api-version>
`scaletargetref_kind`=<hpa-target-kind>
`scaletargetref_name`=<hpa-target-name> | EXPERIMENTAL | +| kube_horizontalpodautoscaler_annotations | Gauge | Kubernetes annotations converted to Prometheus labels controlled via [--metric-annotations-allowlist](../../developer/cli-arguments.md) | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | EXPERIMENTAL | +| kube_horizontalpodautoscaler_labels | Gauge | Kubernetes labels converted to Prometheus labels controlled via [--metric-labels-allowlist](../../developer/cli-arguments.md) | `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 | +| kube_horizontalpodautoscaler_spec_min_replicas | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | STABLE | +| kube_horizontalpodautoscaler_spec_target_metric | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace>
`metric_name`=<metric-name>
`metric_target_type`=<value\|utilization\|average> | EXPERIMENTAL | +| kube_horizontalpodautoscaler_spec_target_container_metric | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace>
`metric_name`=<metric-name>
`metric_target_type`=<value\|utilization\|average>
`container`= | EXPERIMENTAL | +| kube_horizontalpodautoscaler_spec_target_object_metric | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace>
`metric_name`=<metric-name>
`metric_target_type`=<value\|utilization\|average>
`full_target_name`= | EXPERIMENTAL | +| kube_horizontalpodautoscaler_status_target_metric | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace>
`metric_name`=<metric-name>
`metric_target_type`=<value\|utilization\|average> | EXPERIMENTAL | +| kube_horizontalpodautoscaler_status_target_container_metric | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace>
`metric_name`=<metric-name>
`metric_target_type`=<value\|utilization\|average>
`container`= | EXPERIMENTAL | +| kube_horizontalpodautoscaler_status_target_object_metric | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace>
`metric_name`=<metric-name>
`metric_target_type`=<value\|utilization\|average>
`full_target_name`= | EXPERIMENTAL | +| kube_horizontalpodautoscaler_status_condition | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace>
`condition`=<hpa-condition>
`status`=<true\|false\|unknown> | STABLE | +| kube_horizontalpodautoscaler_status_current_replicas | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | STABLE | +| kube_horizontalpodautoscaler_status_desired_replicas | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | STABLE | diff --git a/internal/store/horizontalpodautoscaler.go b/internal/store/horizontalpodautoscaler.go index 3994f14c39..e117b2f285 100644 --- a/internal/store/horizontalpodautoscaler.go +++ b/internal/store/horizontalpodautoscaler.go @@ -27,6 +27,8 @@ import ( "k8s.io/client-go/tools/cache" basemetrics "k8s.io/component-base/metrics" + "slices" + "k8s.io/kube-state-metrics/v2/pkg/metric" generator "k8s.io/kube-state-metrics/v2/pkg/metric_generator" ) @@ -50,7 +52,9 @@ var ( descHorizontalPodAutoscalerLabelsHelp = "Kubernetes labels converted to Prometheus labels." descHorizontalPodAutoscalerLabelsDefaultLabels = []string{"namespace", "horizontalpodautoscaler"} - targetMetricLabels = []string{"metric_name", "metric_target_type"} + targetMetricLabels = []string{"metric_name", "metric_target_type"} + containerMetricLabels = []string{"metric_name", "metric_target_type", "container_name"} + objectMetricLabels = []string{"metric_name", "metric_target_type", "target_name"} ) func hpaMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator { @@ -60,7 +64,11 @@ func hpaMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat createHPASpecMaxReplicas(), createHPASpecMinReplicas(), createHPASpecTargetMetric(), + createHPASpecTargetContainerMetric(), + createHPASpecTargetObjectMetric(), createHPAStatusTargetMetric(), + createHPAStatusTargetContainerMetric(), + createHPAStatusTargetObjectMetric(), createHPAStatusCurrentReplicas(), createHPAStatusDesiredReplicas(), createHPAAnnotations(allowAnnotationsList), @@ -180,10 +188,10 @@ func createHPASpecMinReplicas() generator.FamilyGenerator { ) } -func createHPASpecTargetMetric() generator.FamilyGenerator { +func createHPASpecTargetContainerMetric() generator.FamilyGenerator { return *generator.NewFamilyGeneratorWithStability( - "kube_horizontalpodautoscaler_spec_target_metric", - "The metric specifications used by this autoscaler when calculating the desired replica count.", + "kube_horizontalpodautoscaler_spec_target_container_metric", + "The container metric specifications used by this autoscaler when calculating the desired replica count.", metric.Gauge, basemetrics.ALPHA, "", @@ -192,30 +200,84 @@ func createHPASpecTargetMetric() generator.FamilyGenerator { for _, m := range a.Spec.Metrics { var metricName string var metricTarget autoscaling.MetricTarget + var containerName string // The variable maps the type of metric to the corresponding value metricMap := make(map[metricTargetType]float64) switch m.Type { - case autoscaling.ObjectMetricSourceType: - metricName = m.Object.Metric.Name - metricTarget = m.Object.Target + case autoscaling.ContainerResourceMetricSourceType: + metricName = string(m.ContainerResource.Name) + metricTarget = m.ContainerResource.Target + containerName = m.ContainerResource.Container + default: + // Skip unsupported metric type + continue + } + + if metricTarget.Value != nil { + metricMap[value] = convertValueToFloat64(metricTarget.Value) + } + if metricTarget.AverageValue != nil { + metricMap[average] = convertValueToFloat64(metricTarget.AverageValue) + } + if metricTarget.AverageUtilization != nil { + metricMap[utilization] = float64(*metricTarget.AverageUtilization) + } + + for metricTypeIndex, metricValue := range metricMap { + ms = append(ms, &metric.Metric{ + LabelKeys: containerMetricLabels, + LabelValues: []string{metricName, metricTypeIndex.String(), containerName}, + Value: metricValue, + }) + } + } + + return &metric.Family{Metrics: ms} + }), + ) +} + +func createHPASpecTarget(metricName, metricDescription string, allowedTypes []autoscaling.MetricSourceType) generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + metricName, + metricDescription, + metric.Gauge, + basemetrics.ALPHA, + "", + wrapHPAFunc(func(a *autoscaling.HorizontalPodAutoscaler) *metric.Family { + ms := make([]*metric.Metric, 0, len(a.Spec.Metrics)) + for _, m := range a.Spec.Metrics { + // Check whether the metric type is allowed. + allowed := slices.Contains(allowedTypes, m.Type) + if !allowed { + continue + } + + var metricName string + var metricTarget autoscaling.MetricTarget + var fullTargetName string // only used for ObjectMetricSourceType + + switch m.Type { case autoscaling.PodsMetricSourceType: metricName = m.Pods.Metric.Name metricTarget = m.Pods.Target case autoscaling.ResourceMetricSourceType: metricName = string(m.Resource.Name) metricTarget = m.Resource.Target - case autoscaling.ContainerResourceMetricSourceType: - metricName = string(m.ContainerResource.Name) - metricTarget = m.ContainerResource.Target case autoscaling.ExternalMetricSourceType: metricName = m.External.Metric.Name metricTarget = m.External.Target + case autoscaling.ObjectMetricSourceType: + metricName = m.Object.Metric.Name + metricTarget = m.Object.Target + fullTargetName = m.Object.DescribedObject.Name default: - // Skip unsupported metric type + // Skip unsupported metric type. continue } - + // The variable maps the type of metric to the corresponding value + metricMap := make(map[metricTargetType]float64) if metricTarget.Value != nil { metricMap[value] = convertValueToFloat64(metricTarget.Value) } @@ -227,9 +289,15 @@ func createHPASpecTargetMetric() generator.FamilyGenerator { } for metricTypeIndex, metricValue := range metricMap { + metricLabels := targetMetricLabels + labelValues := []string{metricName, metricTypeIndex.String()} + if m.Type == autoscaling.ObjectMetricSourceType { + metricLabels = objectMetricLabels + labelValues = append(labelValues, fullTargetName) + } ms = append(ms, &metric.Metric{ - LabelKeys: targetMetricLabels, - LabelValues: []string{metricName, metricTypeIndex.String()}, + LabelKeys: metricLabels, + LabelValues: labelValues, Value: metricValue, }) } @@ -239,10 +307,30 @@ func createHPASpecTargetMetric() generator.FamilyGenerator { ) } -func createHPAStatusTargetMetric() generator.FamilyGenerator { +func createHPASpecTargetObjectMetric() generator.FamilyGenerator { + return createHPASpecTarget( + "kube_horizontalpodautoscaler_spec_target_object_metric", + "The object metric specifications used by this autoscaler when calculating the desired replica count.", + []autoscaling.MetricSourceType{ + autoscaling.ObjectMetricSourceType, + }) +} + +func createHPASpecTargetMetric() generator.FamilyGenerator { + return createHPASpecTarget( + "kube_horizontalpodautoscaler_spec_target_metric", + "The metric specifications used by this autoscaler when calculating the desired replica count.", + []autoscaling.MetricSourceType{ + autoscaling.PodsMetricSourceType, + autoscaling.ResourceMetricSourceType, + autoscaling.ExternalMetricSourceType, + }) +} + +func createHPAStatusTargetContainerMetric() generator.FamilyGenerator { return *generator.NewFamilyGeneratorWithStability( - "kube_horizontalpodautoscaler_status_target_metric", - "The current metric status used by this autoscaler when calculating the desired replica count.", + "kube_horizontalpodautoscaler_status_target_container_metric", + "The current container metric status used by this autoscaler when calculating the desired replica count.", metric.Gauge, basemetrics.ALPHA, "", @@ -251,6 +339,56 @@ func createHPAStatusTargetMetric() generator.FamilyGenerator { for _, m := range a.Status.CurrentMetrics { var metricName string var currentMetric autoscaling.MetricValueStatus + var containerName string + // The variable maps the type of metric to the corresponding value + metricMap := make(map[metricTargetType]float64) + + switch m.Type { + case autoscaling.ContainerResourceMetricSourceType: + metricName = string(m.ContainerResource.Name) + currentMetric = m.ContainerResource.Current + containerName = m.ContainerResource.Container + default: + // Skip unsupported metric type + continue + } + + if currentMetric.Value != nil { + metricMap[value] = convertValueToFloat64(currentMetric.Value) + } + if currentMetric.AverageValue != nil { + metricMap[average] = convertValueToFloat64(currentMetric.AverageValue) + } + if currentMetric.AverageUtilization != nil { + metricMap[utilization] = float64(*currentMetric.AverageUtilization) + } + + for metricTypeIndex, metricValue := range metricMap { + ms = append(ms, &metric.Metric{ + LabelKeys: containerMetricLabels, + LabelValues: []string{metricName, metricTypeIndex.String(), containerName}, + Value: metricValue, + }) + } + } + return &metric.Family{Metrics: ms} + }), + ) +} + +func createHPAStatusTargetObjectMetric() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_horizontalpodautoscaler_status_target_object_metric", + "The current object metric status used by this autoscaler when calculating the desired replica count.", + metric.Gauge, + basemetrics.ALPHA, + "", + wrapHPAFunc(func(a *autoscaling.HorizontalPodAutoscaler) *metric.Family { + ms := make([]*metric.Metric, 0, len(a.Status.CurrentMetrics)) + for _, m := range a.Status.CurrentMetrics { + var metricName string + var currentMetric autoscaling.MetricValueStatus + var fullTargetName string // The variable maps the type of metric to the corresponding value metricMap := make(map[metricTargetType]float64) @@ -258,15 +396,57 @@ func createHPAStatusTargetMetric() generator.FamilyGenerator { case autoscaling.ObjectMetricSourceType: metricName = m.Object.Metric.Name currentMetric = m.Object.Current + fullTargetName = m.Object.DescribedObject.Name + default: + // Skip unsupported metric type + continue + } + + if currentMetric.Value != nil { + metricMap[value] = convertValueToFloat64(currentMetric.Value) + } + if currentMetric.AverageValue != nil { + metricMap[average] = convertValueToFloat64(currentMetric.AverageValue) + } + if currentMetric.AverageUtilization != nil { + metricMap[utilization] = float64(*currentMetric.AverageUtilization) + } + + for metricTypeIndex, metricValue := range metricMap { + ms = append(ms, &metric.Metric{ + LabelKeys: objectMetricLabels, + LabelValues: []string{metricName, metricTypeIndex.String(), fullTargetName}, + Value: metricValue, + }) + } + } + return &metric.Family{Metrics: ms} + }), + ) +} + +func createHPAStatusTargetMetric() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_horizontalpodautoscaler_status_target_metric", + "The current metric status used by this autoscaler when calculating the desired replica count.", + metric.Gauge, + basemetrics.ALPHA, + "", + wrapHPAFunc(func(a *autoscaling.HorizontalPodAutoscaler) *metric.Family { + ms := make([]*metric.Metric, 0, len(a.Status.CurrentMetrics)) + for _, m := range a.Status.CurrentMetrics { + var metricName string + var currentMetric autoscaling.MetricValueStatus + // The variable maps the type of metric to the corresponding value + metricMap := make(map[metricTargetType]float64) + + switch m.Type { case autoscaling.PodsMetricSourceType: metricName = m.Pods.Metric.Name currentMetric = m.Pods.Current case autoscaling.ResourceMetricSourceType: metricName = string(m.Resource.Name) currentMetric = m.Resource.Current - case autoscaling.ContainerResourceMetricSourceType: - metricName = string(m.ContainerResource.Name) - currentMetric = m.ContainerResource.Current case autoscaling.ExternalMetricSourceType: metricName = m.External.Metric.Name currentMetric = m.External.Current diff --git a/internal/store/horizontalpodautoscaler_test.go b/internal/store/horizontalpodautoscaler_test.go index 25903fe432..3b8a23d664 100644 --- a/internal/store/horizontalpodautoscaler_test.go +++ b/internal/store/horizontalpodautoscaler_test.go @@ -41,7 +41,11 @@ func TestHPAStore(t *testing.T) { # HELP kube_horizontalpodautoscaler_metadata_generation [STABLE] The generation observed by the HorizontalPodAutoscaler controller. # HELP kube_horizontalpodautoscaler_spec_max_replicas [STABLE] Upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas. # HELP kube_horizontalpodautoscaler_spec_min_replicas [STABLE] Lower limit for the number of pods that can be set by the autoscaler, default 1. + # HELP kube_horizontalpodautoscaler_spec_target_container_metric The container metric specifications used by this autoscaler when calculating the desired replica count. + # HELP kube_horizontalpodautoscaler_spec_target_object_metric The object metric specifications used by this autoscaler when calculating the desired replica count. # HELP kube_horizontalpodautoscaler_spec_target_metric The metric specifications used by this autoscaler when calculating the desired replica count. + # HELP kube_horizontalpodautoscaler_status_target_container_metric The current container metric status used by this autoscaler when calculating the desired replica count. + # HELP kube_horizontalpodautoscaler_status_target_object_metric The current object metric status used by this autoscaler when calculating the desired replica count. # HELP kube_horizontalpodautoscaler_status_target_metric The current metric status used by this autoscaler when calculating the desired replica count. # HELP kube_horizontalpodautoscaler_status_condition [STABLE] The condition of this autoscaler. # HELP kube_horizontalpodautoscaler_status_current_replicas [STABLE] Current number of replicas of pods managed by this autoscaler. @@ -52,7 +56,11 @@ func TestHPAStore(t *testing.T) { # TYPE kube_horizontalpodautoscaler_metadata_generation gauge # TYPE kube_horizontalpodautoscaler_spec_max_replicas gauge # TYPE kube_horizontalpodautoscaler_spec_min_replicas gauge + # TYPE kube_horizontalpodautoscaler_spec_target_container_metric gauge + # TYPE kube_horizontalpodautoscaler_spec_target_object_metric gauge # TYPE kube_horizontalpodautoscaler_spec_target_metric gauge + # TYPE kube_horizontalpodautoscaler_status_target_container_metric gauge + # TYPE kube_horizontalpodautoscaler_status_target_object_metric gauge # TYPE kube_horizontalpodautoscaler_status_target_metric gauge # TYPE kube_horizontalpodautoscaler_status_condition gauge # TYPE kube_horizontalpodautoscaler_status_current_replicas gauge @@ -92,6 +100,9 @@ func TestHPAStore(t *testing.T) { Metric: autoscaling.MetricIdentifier{ Name: "connections", }, + DescribedObject: autoscaling.CrossVersionObjectReference{ + Name: "connections", + }, Target: autoscaling.MetricTarget{ Value: resourcePtr(resource.MustParse("0.5")), AverageValue: resourcePtr(resource.MustParse("0.7")), @@ -213,13 +224,9 @@ func TestHPAStore(t *testing.T) { kube_horizontalpodautoscaler_metadata_generation{horizontalpodautoscaler="hpa1",namespace="ns1"} 2 kube_horizontalpodautoscaler_spec_max_replicas{horizontalpodautoscaler="hpa1",namespace="ns1"} 4 kube_horizontalpodautoscaler_spec_min_replicas{horizontalpodautoscaler="hpa1",namespace="ns1"} 2 - kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="cpu",metric_target_type="utilization",namespace="ns1"} 80 kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="events",metric_target_type="average",namespace="ns1"} 30 - kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="hits",metric_target_type="average",namespace="ns1"} 12 - kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="hits",metric_target_type="value",namespace="ns1"} 10 - kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="connections",metric_target_type="average",namespace="ns1"} 0.7 - kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="connections",metric_target_type="value",namespace="ns1"} 0.5 kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="cpu",metric_target_type="utilization",namespace="ns1"} 80 + kube_horizontalpodautoscaler_spec_target_container_metric{horizontalpodautoscaler="hpa1",metric_name="cpu",metric_target_type="utilization",namespace="ns1",container_name="container1"} 80 kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="memory",metric_target_type="average",namespace="ns1"} 819200 kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="memory",metric_target_type="utilization",namespace="ns1"} 80 kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="sqs_jobs",metric_target_type="value",namespace="ns1"} 30 @@ -228,6 +235,10 @@ func TestHPAStore(t *testing.T) { kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa1",metric_name="cpu",metric_target_type="utilization",namespace="ns1"} 80 kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa1",metric_name="memory",metric_target_type="average",namespace="ns1"} 2.6335914666e+07 kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa1",metric_name="memory",metric_target_type="utilization",namespace="ns1"} 80 + kube_horizontalpodautoscaler_spec_target_object_metric{target_name="",horizontalpodautoscaler="hpa1",metric_name="hits",metric_target_type="average",namespace="ns1"} 12 + kube_horizontalpodautoscaler_spec_target_object_metric{target_name="",horizontalpodautoscaler="hpa1",metric_name="hits",metric_target_type="value",namespace="ns1"} 10 + kube_horizontalpodautoscaler_spec_target_object_metric{target_name="connections",horizontalpodautoscaler="hpa1",metric_name="connections",metric_target_type="average",namespace="ns1"} 0.7 + kube_horizontalpodautoscaler_spec_target_object_metric{target_name="connections",horizontalpodautoscaler="hpa1",metric_name="connections",metric_target_type="value",namespace="ns1"} 0.5 kube_horizontalpodautoscaler_status_condition{condition="AbleToScale",horizontalpodautoscaler="hpa1",namespace="ns1",status="false"} 0 kube_horizontalpodautoscaler_status_condition{condition="AbleToScale",horizontalpodautoscaler="hpa1",namespace="ns1",status="true"} 1 kube_horizontalpodautoscaler_status_condition{condition="AbleToScale",horizontalpodautoscaler="hpa1",namespace="ns1",status="unknown"} 0 @@ -240,6 +251,10 @@ func TestHPAStore(t *testing.T) { "kube_horizontalpodautoscaler_spec_max_replicas", "kube_horizontalpodautoscaler_spec_min_replicas", "kube_horizontalpodautoscaler_spec_target_metric", + "kube_horizontalpodautoscaler_spec_target_container_metric", + "kube_horizontalpodautoscaler_spec_target_object_metric", + "kube_horizontalpodautoscaler_status_target_container_metric", + "kube_horizontalpodautoscaler_status_target_object_metric", "kube_horizontalpodautoscaler_status_target_metric", "kube_horizontalpodautoscaler_status_current_replicas", "kube_horizontalpodautoscaler_status_desired_replicas", @@ -396,10 +411,10 @@ func TestHPAStore(t *testing.T) { kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa2",metric_name="traefik_backend_requests_per_second",metric_target_type="value",namespace="ns1"} 100 kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="memory",metric_target_type="average",namespace="ns1"} 8.47775744e+08 kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="memory",metric_target_type="utilization",namespace="ns1"} 28 - kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="cpu",metric_target_type="average",namespace="ns1"} 0.062 kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="cpu",metric_target_type="utilization",namespace="ns1"} 6 - kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="cpu",metric_target_type="average",namespace="ns1"} 0.08 - kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="cpu",metric_target_type="utilization",namespace="ns1"} 10 + kube_horizontalpodautoscaler_status_target_container_metric{container_name="container1",horizontalpodautoscaler="hpa2",metric_name="cpu",metric_target_type="average",namespace="ns1"} 0.08 + kube_horizontalpodautoscaler_status_target_container_metric{container_name="container1",horizontalpodautoscaler="hpa2",metric_name="cpu",metric_target_type="utilization",namespace="ns1"} 10 + kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="cpu",metric_target_type="average",namespace="ns1"} 0.062 kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="traefik_backend_requests_per_second",metric_target_type="value",namespace="ns1"} 0 kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="traefik_backend_requests_per_second",metric_target_type="average",namespace="ns1"} 2.9 kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="traefik_backend_errors_per_second",metric_target_type="value",namespace="ns1"} 0 @@ -415,6 +430,10 @@ func TestHPAStore(t *testing.T) { "kube_horizontalpodautoscaler_spec_max_replicas", "kube_horizontalpodautoscaler_spec_min_replicas", "kube_horizontalpodautoscaler_spec_target_metric", + "kube_horizontalpodautoscaler_spec_target_container_metric", + "kube_horizontalpodautoscaler_spec_target_object_metric", + "kube_horizontalpodautoscaler_status_target_container_metric", + "kube_horizontalpodautoscaler_status_target_object_metric", "kube_horizontalpodautoscaler_status_target_metric", "kube_horizontalpodautoscaler_status_current_replicas", "kube_horizontalpodautoscaler_status_desired_replicas",