From 8e184f03b1085ec55930e8fdae4bedf426534988 Mon Sep 17 00:00:00 2001 From: whitebear009 Date: Tue, 15 Feb 2022 19:32:47 +0800 Subject: [PATCH 1/4] Change the processing type from int to float in kube_horizontalpodautoscaler_spec_target_metric --- internal/store/horizontalpodautoscaler.go | 35 +++++++++++------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/internal/store/horizontalpodautoscaler.go b/internal/store/horizontalpodautoscaler.go index baf002eb27..0888dfc29c 100644 --- a/internal/store/horizontalpodautoscaler.go +++ b/internal/store/horizontalpodautoscaler.go @@ -134,53 +134,52 @@ func hpaMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat for _, m := range a.Spec.Metrics { var metricName string - var v [metricTargetTypeCount]int64 - var ok [metricTargetTypeCount]bool + var v [metricTargetTypeCount]float64 switch m.Type { case autoscaling.ObjectMetricSourceType: metricName = m.Object.Metric.Name - v[value], ok[value] = m.Object.Target.Value.AsInt64() + if m.Object.Target.Value != nil { + v[value] = float64(m.Object.Target.Value.MilliValue()) / 1000 + } if m.Object.Target.AverageValue != nil { - v[average], ok[average] = m.Object.Target.AverageValue.AsInt64() + v[average] = float64(m.Object.Target.AverageValue.MilliValue()) / 1000 } case autoscaling.PodsMetricSourceType: metricName = m.Pods.Metric.Name - v[average], ok[average] = m.Pods.Target.AverageValue.AsInt64() + v[average] = float64(m.Pods.Target.AverageValue.MilliValue()) / 1000 case autoscaling.ResourceMetricSourceType: metricName = string(m.Resource.Name) - if ok[utilization] = (m.Resource.Target.AverageUtilization != nil); ok[utilization] { - v[utilization] = int64(*m.Resource.Target.AverageUtilization) + if m.Resource.Target.AverageUtilization != nil { + v[utilization] = float64(*m.Resource.Target.AverageUtilization) } if m.Resource.Target.AverageValue != nil { - v[average], ok[average] = m.Resource.Target.AverageValue.AsInt64() + v[average] = float64(m.Resource.Target.AverageValue.MilliValue()) / 1000 } case autoscaling.ExternalMetricSourceType: metricName = m.External.Metric.Name if m.External.Target.Value != nil { - v[value], ok[value] = m.External.Target.Value.AsInt64() + v[value] = float64(m.External.Target.Value.MilliValue()) / 1000 } if m.External.Target.AverageValue != nil { - v[average], ok[average] = m.External.Target.AverageValue.AsInt64() + v[average] = float64(m.External.Target.AverageValue.MilliValue()) / 1000 } default: // Skip unsupported metric type continue } - for i := range ok { - if ok[i] { - ms = append(ms, &metric.Metric{ - LabelKeys: targetMetricLabels, - LabelValues: []string{metricName, metricTargetType(i).String()}, - Value: float64(v[i]), - }) - } + for i := range v { + ms = append(ms, &metric.Metric{ + LabelKeys: targetMetricLabels, + LabelValues: []string{metricName, metricTargetType(i).String()}, + Value: v[i], + }) } } return &metric.Family{Metrics: ms} From 2f5b0f0ff317d9620511ad7e6c1c199253d511a3 Mon Sep 17 00:00:00 2001 From: whitebear009 Date: Wed, 16 Feb 2022 18:55:40 +0800 Subject: [PATCH 2/4] filter unset field and add unit test --- internal/store/horizontalpodautoscaler.go | 27 ++++++++++--------- .../store/horizontalpodautoscaler_test.go | 4 +-- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/internal/store/horizontalpodautoscaler.go b/internal/store/horizontalpodautoscaler.go index 0888dfc29c..3018445abb 100644 --- a/internal/store/horizontalpodautoscaler.go +++ b/internal/store/horizontalpodautoscaler.go @@ -135,39 +135,40 @@ func hpaMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat var metricName string var v [metricTargetTypeCount]float64 + var ok [metricTargetTypeCount]bool switch m.Type { case autoscaling.ObjectMetricSourceType: metricName = m.Object.Metric.Name if m.Object.Target.Value != nil { - v[value] = float64(m.Object.Target.Value.MilliValue()) / 1000 + v[value], ok[value] = float64(m.Object.Target.Value.MilliValue())/1000, true } if m.Object.Target.AverageValue != nil { - v[average] = float64(m.Object.Target.AverageValue.MilliValue()) / 1000 + v[average], ok[average] = float64(m.Object.Target.AverageValue.MilliValue())/1000, true } case autoscaling.PodsMetricSourceType: metricName = m.Pods.Metric.Name - v[average] = float64(m.Pods.Target.AverageValue.MilliValue()) / 1000 + v[average], ok[average] = float64(m.Pods.Target.AverageValue.MilliValue())/1000, true case autoscaling.ResourceMetricSourceType: metricName = string(m.Resource.Name) if m.Resource.Target.AverageUtilization != nil { - v[utilization] = float64(*m.Resource.Target.AverageUtilization) + v[utilization], ok[utilization] = float64(*m.Resource.Target.AverageUtilization), true } if m.Resource.Target.AverageValue != nil { - v[average] = float64(m.Resource.Target.AverageValue.MilliValue()) / 1000 + v[average], ok[average] = float64(m.Resource.Target.AverageValue.MilliValue())/1000, true } case autoscaling.ExternalMetricSourceType: metricName = m.External.Metric.Name if m.External.Target.Value != nil { - v[value] = float64(m.External.Target.Value.MilliValue()) / 1000 + v[value], ok[value] = float64(m.External.Target.Value.MilliValue())/1000, true } if m.External.Target.AverageValue != nil { - v[average] = float64(m.External.Target.AverageValue.MilliValue()) / 1000 + v[average], ok[average] = float64(m.External.Target.AverageValue.MilliValue())/1000, true } default: // Skip unsupported metric type @@ -175,11 +176,13 @@ func hpaMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat } for i := range v { - ms = append(ms, &metric.Metric{ - LabelKeys: targetMetricLabels, - LabelValues: []string{metricName, metricTargetType(i).String()}, - Value: v[i], - }) + if ok[i] { + ms = append(ms, &metric.Metric{ + LabelKeys: targetMetricLabels, + LabelValues: []string{metricName, metricTargetType(i).String()}, + Value: v[i], + }) + } } } return &metric.Family{Metrics: ms} diff --git a/internal/store/horizontalpodautoscaler_test.go b/internal/store/horizontalpodautoscaler_test.go index a115e0183a..6d077e4f3b 100644 --- a/internal/store/horizontalpodautoscaler_test.go +++ b/internal/store/horizontalpodautoscaler_test.go @@ -80,7 +80,7 @@ func TestHPAStore(t *testing.T) { }, Target: autoscaling.MetricTarget{ Value: resourcePtr(resource.MustParse("10")), - AverageValue: resourcePtr(resource.MustParse("12")), + AverageValue: resourcePtr(resource.MustParse("0.5")), }, }, }, @@ -193,7 +193,7 @@ func TestHPAStore(t *testing.T) { 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="average",namespace="ns1"} 0.5 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="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 From eece675df0ea6b23272fba345411dc0241296e66 Mon Sep 17 00:00:00 2001 From: whitebear009 Date: Wed, 16 Feb 2022 22:49:19 +0800 Subject: [PATCH 3/4] fix typo and add unit test for float target metric --- internal/store/horizontalpodautoscaler.go | 2 +- internal/store/horizontalpodautoscaler_test.go | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/internal/store/horizontalpodautoscaler.go b/internal/store/horizontalpodautoscaler.go index 3018445abb..734bd91ec2 100644 --- a/internal/store/horizontalpodautoscaler.go +++ b/internal/store/horizontalpodautoscaler.go @@ -175,7 +175,7 @@ func hpaMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat continue } - for i := range v { + for i := range ok { if ok[i] { ms = append(ms, &metric.Metric{ LabelKeys: targetMetricLabels, diff --git a/internal/store/horizontalpodautoscaler_test.go b/internal/store/horizontalpodautoscaler_test.go index 6d077e4f3b..9192e19035 100644 --- a/internal/store/horizontalpodautoscaler_test.go +++ b/internal/store/horizontalpodautoscaler_test.go @@ -80,7 +80,19 @@ func TestHPAStore(t *testing.T) { }, Target: autoscaling.MetricTarget{ Value: resourcePtr(resource.MustParse("10")), - AverageValue: resourcePtr(resource.MustParse("0.5")), + AverageValue: resourcePtr(resource.MustParse("12")), + }, + }, + }, + { + Type: autoscaling.ObjectMetricSourceType, + Object: &autoscaling.ObjectMetricSource{ + Metric: autoscaling.MetricIdentifier{ + Name: "connections", + }, + Target: autoscaling.MetricTarget{ + Value: resourcePtr(resource.MustParse("0.5")), + AverageValue: resourcePtr(resource.MustParse("0.7")), }, }, }, @@ -193,8 +205,10 @@ func TestHPAStore(t *testing.T) { 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"} 0.5 + 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="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 From c04de9a0ae9ae9cb8f49855b6a509e708b898f52 Mon Sep 17 00:00:00 2001 From: whitebear009 Date: Thu, 17 Feb 2022 19:39:31 +0800 Subject: [PATCH 4/4] remove ok variable and change the type of v variable to map --- internal/store/horizontalpodautoscaler.go | 34 ++++++++++------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/internal/store/horizontalpodautoscaler.go b/internal/store/horizontalpodautoscaler.go index 734bd91ec2..6531866d7f 100644 --- a/internal/store/horizontalpodautoscaler.go +++ b/internal/store/horizontalpodautoscaler.go @@ -36,8 +36,6 @@ const ( value metricTargetType = iota utilization average - - metricTargetTypeCount // Used as a length argument to arrays ) func (m metricTargetType) String() string { @@ -134,55 +132,53 @@ func hpaMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat for _, m := range a.Spec.Metrics { var metricName string - var v [metricTargetTypeCount]float64 - var ok [metricTargetTypeCount]bool + // 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 if m.Object.Target.Value != nil { - v[value], ok[value] = float64(m.Object.Target.Value.MilliValue())/1000, true + metricMap[value] = float64(m.Object.Target.Value.MilliValue()) / 1000 } if m.Object.Target.AverageValue != nil { - v[average], ok[average] = float64(m.Object.Target.AverageValue.MilliValue())/1000, true + metricMap[average] = float64(m.Object.Target.AverageValue.MilliValue()) / 1000 } case autoscaling.PodsMetricSourceType: metricName = m.Pods.Metric.Name - v[average], ok[average] = float64(m.Pods.Target.AverageValue.MilliValue())/1000, true + metricMap[average] = float64(m.Pods.Target.AverageValue.MilliValue()) / 1000 case autoscaling.ResourceMetricSourceType: metricName = string(m.Resource.Name) if m.Resource.Target.AverageUtilization != nil { - v[utilization], ok[utilization] = float64(*m.Resource.Target.AverageUtilization), true + metricMap[utilization] = float64(*m.Resource.Target.AverageUtilization) } if m.Resource.Target.AverageValue != nil { - v[average], ok[average] = float64(m.Resource.Target.AverageValue.MilliValue())/1000, true + metricMap[average] = float64(m.Resource.Target.AverageValue.MilliValue()) / 1000 } case autoscaling.ExternalMetricSourceType: metricName = m.External.Metric.Name if m.External.Target.Value != nil { - v[value], ok[value] = float64(m.External.Target.Value.MilliValue())/1000, true + metricMap[value] = float64(m.External.Target.Value.MilliValue()) / 1000 } if m.External.Target.AverageValue != nil { - v[average], ok[average] = float64(m.External.Target.AverageValue.MilliValue())/1000, true + metricMap[average] = float64(m.External.Target.AverageValue.MilliValue()) / 1000 } default: // Skip unsupported metric type continue } - for i := range ok { - if ok[i] { - ms = append(ms, &metric.Metric{ - LabelKeys: targetMetricLabels, - LabelValues: []string{metricName, metricTargetType(i).String()}, - Value: v[i], - }) - } + for metricTypeIndex, metricValue := range metricMap { + ms = append(ms, &metric.Metric{ + LabelKeys: targetMetricLabels, + LabelValues: []string{metricName, metricTypeIndex.String()}, + Value: metricValue, + }) } } return &metric.Family{Metrics: ms}