Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(hpa): status current metric #1725

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/horizontalpodautoscaler-metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
| kube_horizontalpodautoscaler_spec_max_replicas | Gauge | `horizontalpodautoscaler`=&lt;hpa-name&gt; <br> `namespace`=&lt;hpa-namespace&gt; | STABLE |
| kube_horizontalpodautoscaler_spec_min_replicas | Gauge | `horizontalpodautoscaler`=&lt;hpa-name&gt; <br> `namespace`=&lt;hpa-namespace&gt; | STABLE |
| kube_horizontalpodautoscaler_spec_target_metric | Gauge | `horizontalpodautoscaler`=&lt;hpa-name&gt; <br> `namespace`=&lt;hpa-namespace&gt; <br> `metric_name`=&lt;metric-name&gt; <br> `metric_target_type`=&lt;value\|utilization\|average&gt; | EXPERIMENTAL |
| kube_horizontalpodautoscaler_status_current_target_metric | Gauge | `horizontalpodautoscaler`=&lt;hpa-name&gt; <br> `namespace`=&lt;hpa-namespace&gt; <br> `metric_name`=&lt;metric-name&gt; <br> `metric_target_type`=&lt;value\|utilization\|average&gt; | EXPERIMENTAL |
| kube_horizontalpodautoscaler_status_condition | Gauge | `horizontalpodautoscaler`=&lt;hpa-name&gt; <br> `namespace`=&lt;hpa-namespace&gt; <br> `condition`=&lt;hpa-condition&gt; <br> `status`=&lt;true\|false\|unknown&gt; | STABLE |
| kube_horizontalpodautoscaler_status_current_replicas | Gauge | `horizontalpodautoscaler`=&lt;hpa-name&gt; <br> `namespace`=&lt;hpa-namespace&gt; | STABLE |
| kube_horizontalpodautoscaler_status_desired_replicas | Gauge | `horizontalpodautoscaler`=&lt;hpa-name&gt; <br> `namespace`=&lt;hpa-namespace&gt; | STABLE |
62 changes: 62 additions & 0 deletions internal/store/horizontalpodautoscaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,68 @@ func hpaMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat
return &metric.Family{Metrics: ms}
}),
),
*generator.NewFamilyGenerator(
"kube_horizontalpodautoscaler_status_current_target_metric",
"The metric current status used by this autoscaler when calculating the desired replica count.",
tanguyfalconnet marked this conversation as resolved.
Show resolved Hide resolved
metric.Gauge,
"",
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

// 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.Current.Value != nil {
metricMap[value] = float64(m.Object.Current.Value.MilliValue()) / 1000
}
if m.Object.Current.AverageValue != nil {
metricMap[average] = float64(m.Object.Current.AverageValue.MilliValue()) / 1000
}
case autoscaling.PodsMetricSourceType:
metricName = m.Pods.Metric.Name

metricMap[average] = float64(m.Pods.Current.AverageValue.MilliValue()) / 1000
case autoscaling.ResourceMetricSourceType:
metricName = string(m.Resource.Name)

if m.Resource.Current.AverageUtilization != nil {
metricMap[utilization] = float64(*m.Resource.Current.AverageUtilization)
}

if m.Resource.Current.AverageValue != nil {
metricMap[average] = float64(m.Resource.Current.AverageValue.MilliValue()) / 1000
}
case autoscaling.ExternalMetricSourceType:
metricName = m.External.Metric.Name

if m.External.Current.Value != nil {
metricMap[value] = float64(m.External.Current.Value.MilliValue()) / 1000
}
if m.External.Current.AverageValue != nil {
metricMap[average] = float64(m.External.Current.AverageValue.MilliValue()) / 1000
}
default:
// Skip unsupported metric type
continue
}

for metricTypeIndex, metricValue := range metricMap {
ms = append(ms, &metric.Metric{
LabelKeys: targetMetricLabels,
LabelValues: []string{metricName, metricTypeIndex.String()},
Value: metricValue,
})
}
}
return &metric.Family{Metrics: ms}
}),
),
*generator.NewFamilyGenerator(
"kube_horizontalpodautoscaler_status_current_replicas",
"Current number of replicas of pods managed by this autoscaler.",
Expand Down
19 changes: 17 additions & 2 deletions internal/store/horizontalpodautoscaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func TestHPAStore(t *testing.T) {
# HELP kube_horizontalpodautoscaler_spec_max_replicas 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 Lower limit for the number of pods that can be set by the autoscaler, default 1.
# HELP kube_horizontalpodautoscaler_spec_target_metric The metric specifications used by this autoscaler when calculating the desired replica count.
# HELP kube_horizontalpodautoscaler_status_current_target_metric The metric current status used by this autoscaler when calculating the desired replica count.
# HELP kube_horizontalpodautoscaler_status_condition The condition of this autoscaler.
# HELP kube_horizontalpodautoscaler_status_current_replicas Current number of replicas of pods managed by this autoscaler.
# HELP kube_horizontalpodautoscaler_status_desired_replicas Desired number of replicas of pods managed by this autoscaler.
Expand All @@ -52,6 +53,7 @@ func TestHPAStore(t *testing.T) {
# TYPE kube_horizontalpodautoscaler_spec_max_replicas gauge
# TYPE kube_horizontalpodautoscaler_spec_min_replicas gauge
# TYPE kube_horizontalpodautoscaler_spec_target_metric gauge
# TYPE kube_horizontalpodautoscaler_status_current_target_metric gauge
# TYPE kube_horizontalpodautoscaler_status_condition gauge
# TYPE kube_horizontalpodautoscaler_status_current_replicas gauge
# TYPE kube_horizontalpodautoscaler_status_desired_replicas gauge
Expand Down Expand Up @@ -179,7 +181,7 @@ func TestHPAStore(t *testing.T) {
Name: "cpu",
Current: autoscaling.MetricValueStatus{
AverageValue: resourcePtr(resource.MustParse("7m")),
AverageUtilization: new(int32),
AverageUtilization: int32ptr(80),
},
},
},
Expand All @@ -189,7 +191,7 @@ func TestHPAStore(t *testing.T) {
Name: "memory",
Current: autoscaling.MetricValueStatus{
AverageValue: resourcePtr(resource.MustParse("26335914666m")),
AverageUtilization: new(int32),
AverageUtilization: int32ptr(80),
},
},
},
Expand All @@ -213,6 +215,10 @@ func TestHPAStore(t *testing.T) {
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
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="transactions_processed",metric_target_type="average",namespace="ns1"} 33
kube_horizontalpodautoscaler_status_current_target_metric{horizontalpodautoscaler="hpa1",metric_name="cpu",metric_target_type="average",namespace="ns1"} 0.007
kube_horizontalpodautoscaler_status_current_target_metric{horizontalpodautoscaler="hpa1",metric_name="cpu",metric_target_type="utilization",namespace="ns1"} 80
kube_horizontalpodautoscaler_status_current_target_metric{horizontalpodautoscaler="hpa1",metric_name="memory",metric_target_type="average",namespace="ns1"} 2.6335914666e+07
kube_horizontalpodautoscaler_status_current_target_metric{horizontalpodautoscaler="hpa1",metric_name="memory",metric_target_type="utilization",namespace="ns1"} 80
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
Expand All @@ -225,6 +231,7 @@ func TestHPAStore(t *testing.T) {
"kube_horizontalpodautoscaler_spec_max_replicas",
"kube_horizontalpodautoscaler_spec_min_replicas",
"kube_horizontalpodautoscaler_spec_target_metric",
"kube_horizontalpodautoscaler_status_current_target_metric",
"kube_horizontalpodautoscaler_status_current_replicas",
"kube_horizontalpodautoscaler_status_desired_replicas",
"kube_horizontalpodautoscaler_status_condition",
Expand Down Expand Up @@ -368,6 +375,13 @@ func TestHPAStore(t *testing.T) {
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa2",metric_name="memory",metric_target_type="utilization",namespace="ns1"} 75
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa2",metric_name="traefik_backend_errors_per_second",metric_target_type="value",namespace="ns1"} 100
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa2",metric_name="traefik_backend_requests_per_second",metric_target_type="value",namespace="ns1"} 100
kube_horizontalpodautoscaler_status_current_target_metric{horizontalpodautoscaler="hpa2",metric_name="memory",metric_target_type="average",namespace="ns1"} 8.47775744e+08
kube_horizontalpodautoscaler_status_current_target_metric{horizontalpodautoscaler="hpa2",metric_name="memory",metric_target_type="utilization",namespace="ns1"} 28
kube_horizontalpodautoscaler_status_current_target_metric{horizontalpodautoscaler="hpa2",metric_name="cpu",metric_target_type="average",namespace="ns1"} 0.062
kube_horizontalpodautoscaler_status_current_target_metric{horizontalpodautoscaler="hpa2",metric_name="cpu",metric_target_type="utilization",namespace="ns1"} 6
kube_horizontalpodautoscaler_status_current_target_metric{horizontalpodautoscaler="hpa2",metric_name="traefik_backend_requests_per_second",metric_target_type="value",namespace="ns1"} 0
kube_horizontalpodautoscaler_status_current_target_metric{horizontalpodautoscaler="hpa2",metric_name="traefik_backend_requests_per_second",metric_target_type="average",namespace="ns1"} 2.9
kube_horizontalpodautoscaler_status_current_target_metric{horizontalpodautoscaler="hpa2",metric_name="traefik_backend_errors_per_second",metric_target_type="value",namespace="ns1"} 0
kube_horizontalpodautoscaler_status_condition{condition="AbleToScale",horizontalpodautoscaler="hpa2",namespace="ns1",status="false"} 0
kube_horizontalpodautoscaler_status_condition{condition="AbleToScale",horizontalpodautoscaler="hpa2",namespace="ns1",status="true"} 1
kube_horizontalpodautoscaler_status_condition{condition="AbleToScale",horizontalpodautoscaler="hpa2",namespace="ns1",status="unknown"} 0
Expand All @@ -380,6 +394,7 @@ func TestHPAStore(t *testing.T) {
"kube_horizontalpodautoscaler_spec_max_replicas",
"kube_horizontalpodautoscaler_spec_min_replicas",
"kube_horizontalpodautoscaler_spec_target_metric",
"kube_horizontalpodautoscaler_status_current_target_metric",
"kube_horizontalpodautoscaler_status_current_replicas",
"kube_horizontalpodautoscaler_status_desired_replicas",
"kube_horizontalpodautoscaler_status_condition",
Expand Down