Skip to content

Commit b14a346

Browse files
committed
fix(horizontalpodautoscaler): add selector labels where applicable for hpa spec|status target metrics
1 parent c853e41 commit b14a346

File tree

3 files changed

+61
-14
lines changed

3 files changed

+61
-14
lines changed
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
# Horizontal Pod Autoscaler Metrics
22

33
| Metric name | Metric type | Description | Labels/tags | Status |
4-
| ---------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
4+
| ---------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------- |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ------------ |
55
| kube_horizontalpodautoscaler_info | Gauge | | `horizontalpodautoscaler`=&lt;hpa-name&gt; <br> `namespace`=&lt;hpa-namespace&gt; <br> `scaletargetref_api_version`=&lt;hpa-target-api-version&gt; <br> `scaletargetref_kind`=&lt;hpa-target-kind&gt; <br> `scaletargetref_name`=&lt;hpa-target-name&gt; | EXPERIMENTAL |
66
| kube_horizontalpodautoscaler_annotations | Gauge | Kubernetes annotations converted to Prometheus labels controlled via [--metric-annotations-allowlist](../../developer/cli-arguments.md) | `horizontalpodautoscaler`=&lt;hpa-name&gt; <br> `namespace`=&lt;hpa-namespace&gt; | EXPERIMENTAL |
77
| kube_horizontalpodautoscaler_labels | Gauge | Kubernetes labels converted to Prometheus labels controlled via [--metric-labels-allowlist](../../developer/cli-arguments.md) | `horizontalpodautoscaler`=&lt;hpa-name&gt; <br> `namespace`=&lt;hpa-namespace&gt; | STABLE |
88
| kube_horizontalpodautoscaler_metadata_generation | Gauge | | `horizontalpodautoscaler`=&lt;hpa-name&gt; <br> `namespace`=&lt;hpa-namespace&gt; | STABLE |
99
| kube_horizontalpodautoscaler_spec_max_replicas | Gauge | | `horizontalpodautoscaler`=&lt;hpa-name&gt; <br> `namespace`=&lt;hpa-namespace&gt; | STABLE |
1010
| kube_horizontalpodautoscaler_spec_min_replicas | Gauge | | `horizontalpodautoscaler`=&lt;hpa-name&gt; <br> `namespace`=&lt;hpa-namespace&gt; | STABLE |
11-
| 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 |
12-
| kube_horizontalpodautoscaler_status_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 |
11+
| 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 <br> `selectorLabel_$labelKey`=&lt;labelValue&gt; | EXPERIMENTAL |
12+
| kube_horizontalpodautoscaler_status_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<br> `selectorLabel_$labelKey`=&lt;labelValue&gt; | EXPERIMENTAL |
1313
| 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 |
1414
| kube_horizontalpodautoscaler_status_current_replicas | Gauge | | `horizontalpodautoscaler`=&lt;hpa-name&gt; <br> `namespace`=&lt;hpa-namespace&gt; | STABLE |
1515
| kube_horizontalpodautoscaler_status_desired_replicas | Gauge | | `horizontalpodautoscaler`=&lt;hpa-name&gt; <br> `namespace`=&lt;hpa-namespace&gt; | STABLE |

internal/store/horizontalpodautoscaler.go

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,14 +194,22 @@ func createHPASpecTargetMetric() generator.FamilyGenerator {
194194
var metricTarget autoscaling.MetricTarget
195195
// The variable maps the type of metric to the corresponding value
196196
metricMap := make(map[metricTargetType]float64)
197+
// Object|Pods|External metrics can use the same name for mutltiple metrics. Add SelectorLabels to the metric labels
198+
selectorLabels := make(map[string]string)
197199

198200
switch m.Type {
199201
case autoscaling.ObjectMetricSourceType:
200202
metricName = m.Object.Metric.Name
201203
metricTarget = m.Object.Target
204+
if m.Object.Metric.Selector != nil {
205+
selectorLabels = m.Object.Metric.Selector.MatchLabels
206+
}
202207
case autoscaling.PodsMetricSourceType:
203208
metricName = m.Pods.Metric.Name
204209
metricTarget = m.Pods.Target
210+
if m.Pods.Metric.Selector != nil {
211+
selectorLabels = m.Pods.Metric.Selector.MatchLabels
212+
}
205213
case autoscaling.ResourceMetricSourceType:
206214
metricName = string(m.Resource.Name)
207215
metricTarget = m.Resource.Target
@@ -211,6 +219,9 @@ func createHPASpecTargetMetric() generator.FamilyGenerator {
211219
case autoscaling.ExternalMetricSourceType:
212220
metricName = m.External.Metric.Name
213221
metricTarget = m.External.Target
222+
if m.External.Metric.Selector != nil {
223+
selectorLabels = m.External.Metric.Selector.MatchLabels
224+
}
214225
default:
215226
// Skip unsupported metric type
216227
continue
@@ -227,9 +238,10 @@ func createHPASpecTargetMetric() generator.FamilyGenerator {
227238
}
228239

229240
for metricTypeIndex, metricValue := range metricMap {
241+
selectorLabelKeys, selectorLabelValues := kubeMapToPrometheusLabels("selectorlabel", selectorLabels)
230242
ms = append(ms, &metric.Metric{
231-
LabelKeys: targetMetricLabels,
232-
LabelValues: []string{metricName, metricTypeIndex.String()},
243+
LabelKeys: append(targetMetricLabels, selectorLabelKeys...),
244+
LabelValues: append([]string{metricName, metricTypeIndex.String()}, selectorLabelValues...),
233245
Value: metricValue,
234246
})
235247
}
@@ -253,14 +265,22 @@ func createHPAStatusTargetMetric() generator.FamilyGenerator {
253265
var currentMetric autoscaling.MetricValueStatus
254266
// The variable maps the type of metric to the corresponding value
255267
metricMap := make(map[metricTargetType]float64)
268+
// Object|Pods|External metrics can use the same name for mutltiple metrics. Add SelectorLabels to the metric labels
269+
selectorLabels := make(map[string]string)
256270

257271
switch m.Type {
258272
case autoscaling.ObjectMetricSourceType:
259273
metricName = m.Object.Metric.Name
260274
currentMetric = m.Object.Current
275+
if m.Object.Metric.Selector != nil {
276+
selectorLabels = m.Object.Metric.Selector.MatchLabels
277+
}
261278
case autoscaling.PodsMetricSourceType:
262279
metricName = m.Pods.Metric.Name
263280
currentMetric = m.Pods.Current
281+
if m.Pods.Metric.Selector != nil {
282+
selectorLabels = m.Pods.Metric.Selector.MatchLabels
283+
}
264284
case autoscaling.ResourceMetricSourceType:
265285
metricName = string(m.Resource.Name)
266286
currentMetric = m.Resource.Current
@@ -270,6 +290,9 @@ func createHPAStatusTargetMetric() generator.FamilyGenerator {
270290
case autoscaling.ExternalMetricSourceType:
271291
metricName = m.External.Metric.Name
272292
currentMetric = m.External.Current
293+
if m.External.Metric.Selector != nil {
294+
selectorLabels = m.External.Metric.Selector.MatchLabels
295+
}
273296
default:
274297
// Skip unsupported metric type
275298
continue
@@ -286,9 +309,10 @@ func createHPAStatusTargetMetric() generator.FamilyGenerator {
286309
}
287310

288311
for metricTypeIndex, metricValue := range metricMap {
312+
selectorLabelKeys, selectorLabelValues := kubeMapToPrometheusLabels("selectorlabel", selectorLabels)
289313
ms = append(ms, &metric.Metric{
290-
LabelKeys: targetMetricLabels,
291-
LabelValues: []string{metricName, metricTypeIndex.String()},
314+
LabelKeys: append(targetMetricLabels, selectorLabelKeys...),
315+
LabelValues: append([]string{metricName, metricTypeIndex.String()}, selectorLabelValues...),
292316
Value: metricValue,
293317
})
294318
}

internal/store/horizontalpodautoscaler_test.go

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ func TestHPAStore(t *testing.T) {
7979
Object: &autoscaling.ObjectMetricSource{
8080
Metric: autoscaling.MetricIdentifier{
8181
Name: "hits",
82+
Selector: &metav1.LabelSelector{
83+
MatchLabels: map[string]string{
84+
"app": "foobar",
85+
}},
8286
},
8387
Target: autoscaling.MetricTarget{
8488
Value: resourcePtr(resource.MustParse("10")),
@@ -103,6 +107,11 @@ func TestHPAStore(t *testing.T) {
103107
Pods: &autoscaling.PodsMetricSource{
104108
Metric: autoscaling.MetricIdentifier{
105109
Name: "transactions_processed",
110+
Selector: &metav1.LabelSelector{
111+
MatchLabels: map[string]string{
112+
"app": "foobar",
113+
"k8s.io/name": "foobar",
114+
}},
106115
},
107116
Target: autoscaling.MetricTarget{
108117
AverageValue: resourcePtr(resource.MustParse("33")),
@@ -150,6 +159,11 @@ func TestHPAStore(t *testing.T) {
150159
External: &autoscaling.ExternalMetricSource{
151160
Metric: autoscaling.MetricIdentifier{
152161
Name: "sqs_jobs",
162+
Selector: &metav1.LabelSelector{
163+
MatchLabels: map[string]string{
164+
"app": "foobar",
165+
"job.1.type": "type1",
166+
}},
153167
},
154168
Target: autoscaling.MetricTarget{
155169
Value: resourcePtr(resource.MustParse("30")),
@@ -215,15 +229,15 @@ func TestHPAStore(t *testing.T) {
215229
kube_horizontalpodautoscaler_spec_min_replicas{horizontalpodautoscaler="hpa1",namespace="ns1"} 2
216230
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="cpu",metric_target_type="utilization",namespace="ns1"} 80
217231
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="events",metric_target_type="average",namespace="ns1"} 30
218-
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="hits",metric_target_type="average",namespace="ns1"} 12
219-
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="hits",metric_target_type="value",namespace="ns1"} 10
232+
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="hits",metric_target_type="average",namespace="ns1",selectorlabel_app="foobar"} 12
233+
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="hits",metric_target_type="value",namespace="ns1",selectorlabel_app="foobar"} 10
220234
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="connections",metric_target_type="average",namespace="ns1"} 0.7
221235
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="connections",metric_target_type="value",namespace="ns1"} 0.5
222236
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="cpu",metric_target_type="utilization",namespace="ns1"} 80
223237
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="memory",metric_target_type="average",namespace="ns1"} 819200
224238
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="memory",metric_target_type="utilization",namespace="ns1"} 80
225-
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="sqs_jobs",metric_target_type="value",namespace="ns1"} 30
226-
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="transactions_processed",metric_target_type="average",namespace="ns1"} 33
239+
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="sqs_jobs",metric_target_type="value",namespace="ns1",selectorlabel_app="foobar",selectorlabel_job_1_type="type1"} 30
240+
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa1",metric_name="transactions_processed",metric_target_type="average",namespace="ns1",selectorlabel_app="foobar",selectorlabel_k8s_io_name="foobar"} 33
227241
kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa1",metric_name="cpu",metric_target_type="average",namespace="ns1"} 0.007
228242
kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa1",metric_name="cpu",metric_target_type="utilization",namespace="ns1"} 80
229243
kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa1",metric_name="memory",metric_target_type="average",namespace="ns1"} 2.6335914666e+07
@@ -293,6 +307,10 @@ func TestHPAStore(t *testing.T) {
293307
External: &autoscaling.ExternalMetricSource{
294308
Metric: autoscaling.MetricIdentifier{
295309
Name: "traefik_backend_requests_per_second",
310+
Selector: &metav1.LabelSelector{
311+
MatchLabels: map[string]string{
312+
"app": "foobar",
313+
}},
296314
},
297315
Target: autoscaling.MetricTarget{
298316
Value: resourcePtr(resource.MustParse("100")),
@@ -363,6 +381,11 @@ func TestHPAStore(t *testing.T) {
363381
External: &autoscaling.ExternalMetricStatus{
364382
Metric: autoscaling.MetricIdentifier{
365383
Name: "traefik_backend_requests_per_second",
384+
Selector: &metav1.LabelSelector{
385+
MatchLabels: map[string]string{
386+
"app": "foobar",
387+
"app-type": "traefik",
388+
}},
366389
},
367390
Current: autoscaling.MetricValueStatus{
368391
Value: resourcePtr(resource.MustParse("0")),
@@ -393,15 +416,15 @@ func TestHPAStore(t *testing.T) {
393416
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa2",metric_name="cpu",metric_target_type="utilization",namespace="ns1"} 80
394417
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa2",metric_name="memory",metric_target_type="utilization",namespace="ns1"} 75
395418
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa2",metric_name="traefik_backend_errors_per_second",metric_target_type="value",namespace="ns1"} 100
396-
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa2",metric_name="traefik_backend_requests_per_second",metric_target_type="value",namespace="ns1"} 100
419+
kube_horizontalpodautoscaler_spec_target_metric{horizontalpodautoscaler="hpa2",metric_name="traefik_backend_requests_per_second",metric_target_type="value",namespace="ns1",selectorlabel_app="foobar"} 100
397420
kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="memory",metric_target_type="average",namespace="ns1"} 8.47775744e+08
398421
kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="memory",metric_target_type="utilization",namespace="ns1"} 28
399422
kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="cpu",metric_target_type="average",namespace="ns1"} 0.062
400423
kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="cpu",metric_target_type="utilization",namespace="ns1"} 6
401424
kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="cpu",metric_target_type="average",namespace="ns1"} 0.08
402425
kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="cpu",metric_target_type="utilization",namespace="ns1"} 10
403-
kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="traefik_backend_requests_per_second",metric_target_type="value",namespace="ns1"} 0
404-
kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="traefik_backend_requests_per_second",metric_target_type="average",namespace="ns1"} 2.9
426+
kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="traefik_backend_requests_per_second",metric_target_type="value",namespace="ns1",selectorlabel_app="foobar",selectorlabel_app_type="traefik"} 0
427+
kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="traefik_backend_requests_per_second",metric_target_type="average",namespace="ns1",selectorlabel_app="foobar",selectorlabel_app_type="traefik"} 2.9
405428
kube_horizontalpodautoscaler_status_target_metric{horizontalpodautoscaler="hpa2",metric_name="traefik_backend_errors_per_second",metric_target_type="value",namespace="ns1"} 0
406429
kube_horizontalpodautoscaler_status_condition{condition="AbleToScale",horizontalpodautoscaler="hpa2",namespace="ns1",status="false"} 0
407430
kube_horizontalpodautoscaler_status_condition{condition="AbleToScale",horizontalpodautoscaler="hpa2",namespace="ns1",status="true"} 1

0 commit comments

Comments
 (0)