diff --git a/docs/metrics/workload/horizontalpodautoscaler-metrics.md b/docs/metrics/workload/horizontalpodautoscaler-metrics.md index 383bdca13f..dbada0f97e 100644 --- a/docs/metrics/workload/horizontalpodautoscaler-metrics.md +++ b/docs/metrics/workload/horizontalpodautoscaler-metrics.md @@ -1,15 +1,17 @@ # 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 | +| 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 | +| 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 | +| kube_horizontalpodautoscaler_created | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | EXPERIMENTAL | +| kube_horizontalpodautoscaler_deletion_timestamp | Gauge | | `horizontalpodautoscaler`=<hpa-name>
`namespace`=<hpa-namespace> | EXPERIMENTAL | diff --git a/internal/store/horizontalpodautoscaler.go b/internal/store/horizontalpodautoscaler.go index d0bc3f28b9..eae40a9a53 100644 --- a/internal/store/horizontalpodautoscaler.go +++ b/internal/store/horizontalpodautoscaler.go @@ -66,6 +66,8 @@ func hpaMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat createHPAAnnotations(allowAnnotationsList), createHPALabels(allowLabelsList), createHPAStatusCondition(), + createHPACreated(), + createHPADeletionTimestamp(), } } @@ -413,3 +415,49 @@ func createHPAStatusCondition() generator.FamilyGenerator { }), ) } + +func createHPACreated() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_horizontalpodautoscaler_created", + "Unix creation timestamp", + metric.Gauge, + basemetrics.ALPHA, + "", + wrapHPAFunc(func(a *autoscaling.HorizontalPodAutoscaler) *metric.Family { + ms := []*metric.Metric{} + + if !a.CreationTimestamp.IsZero() { + ms = append(ms, &metric.Metric{ + Value: float64(a.CreationTimestamp.Unix()), + }) + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} + +func createHPADeletionTimestamp() generator.FamilyGenerator { + return *generator.NewFamilyGeneratorWithStability( + "kube_horizontalpodautoscaler_deletion_timestamp", + "Unix deletion timestamp", + metric.Gauge, + basemetrics.ALPHA, + "", + wrapHPAFunc(func(a *autoscaling.HorizontalPodAutoscaler) *metric.Family { + ms := []*metric.Metric{} + + if !a.DeletionTimestamp.IsZero() { + ms = append(ms, &metric.Metric{ + Value: float64(a.DeletionTimestamp.Unix()), + }) + } + + return &metric.Family{ + Metrics: ms, + } + }), + ) +} diff --git a/internal/store/horizontalpodautoscaler_test.go b/internal/store/horizontalpodautoscaler_test.go index 25903fe432..95eb737da8 100644 --- a/internal/store/horizontalpodautoscaler_test.go +++ b/internal/store/horizontalpodautoscaler_test.go @@ -18,6 +18,7 @@ package store import ( "testing" + "time" autoscaling "k8s.io/api/autoscaling/v2" v1 "k8s.io/api/core/v1" @@ -46,6 +47,8 @@ func TestHPAStore(t *testing.T) { # 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. # HELP kube_horizontalpodautoscaler_status_desired_replicas [STABLE] Desired number of replicas of pods managed by this autoscaler. + # HELP kube_horizontalpodautoscaler_created Unix creation timestamp + # HELP kube_horizontalpodautoscaler_deletion_timestamp Unix deletion timestamp # TYPE kube_horizontalpodautoscaler_info gauge # TYPE kube_horizontalpodautoscaler_annotations gauge # TYPE kube_horizontalpodautoscaler_labels gauge @@ -57,15 +60,19 @@ func TestHPAStore(t *testing.T) { # TYPE kube_horizontalpodautoscaler_status_condition gauge # TYPE kube_horizontalpodautoscaler_status_current_replicas gauge # TYPE kube_horizontalpodautoscaler_status_desired_replicas gauge + # TYPE kube_horizontalpodautoscaler_created gauge + # TYPE kube_horizontalpodautoscaler_deletion_timestamp gauge ` cases := []generateMetricsTestCase{ { // Verify populating base metric. Obj: &autoscaling.HorizontalPodAutoscaler{ ObjectMeta: metav1.ObjectMeta{ - Generation: 2, - Name: "hpa1", - Namespace: "ns1", + Generation: 2, + Name: "hpa1", + CreationTimestamp: metav1.Time{Time: time.Unix(1500000000, 0)}, + DeletionTimestamp: &metav1.Time{Time: time.Unix(1800000000, 0)}, + Namespace: "ns1", Labels: map[string]string{ "app": "foobar", }, @@ -233,6 +240,8 @@ func TestHPAStore(t *testing.T) { kube_horizontalpodautoscaler_status_condition{condition="AbleToScale",horizontalpodautoscaler="hpa1",namespace="ns1",status="unknown"} 0 kube_horizontalpodautoscaler_status_current_replicas{horizontalpodautoscaler="hpa1",namespace="ns1"} 2 kube_horizontalpodautoscaler_status_desired_replicas{horizontalpodautoscaler="hpa1",namespace="ns1"} 2 + kube_horizontalpodautoscaler_created{horizontalpodautoscaler="hpa1",namespace="ns1"} 1.5e+09 + kube_horizontalpodautoscaler_deletion_timestamp{horizontalpodautoscaler="hpa1",namespace="ns1"} 1.8e+09 `, MetricNames: []string{ "kube_horizontalpodautoscaler_info", @@ -246,6 +255,8 @@ func TestHPAStore(t *testing.T) { "kube_horizontalpodautoscaler_status_condition", "kube_horizontalpodautoscaler_annotations", "kube_horizontalpodautoscaler_labels", + "kube_horizontalpodautoscaler_created", + "kube_horizontalpodautoscaler_deletion_timestamp", }, }, { @@ -255,9 +266,11 @@ func TestHPAStore(t *testing.T) { }, Obj: &autoscaling.HorizontalPodAutoscaler{ ObjectMeta: metav1.ObjectMeta{ - Generation: 2, - Name: "hpa2", - Namespace: "ns1", + Generation: 2, + Name: "hpa2", + CreationTimestamp: metav1.Time{Time: time.Unix(1500000000, 0)}, + DeletionTimestamp: &metav1.Time{Time: time.Unix(1800000000, 0)}, + Namespace: "ns1", Labels: map[string]string{ "app": "foobar", }, @@ -408,6 +421,8 @@ func TestHPAStore(t *testing.T) { kube_horizontalpodautoscaler_status_condition{condition="AbleToScale",horizontalpodautoscaler="hpa2",namespace="ns1",status="unknown"} 0 kube_horizontalpodautoscaler_status_current_replicas{horizontalpodautoscaler="hpa2",namespace="ns1"} 2 kube_horizontalpodautoscaler_status_desired_replicas{horizontalpodautoscaler="hpa2",namespace="ns1"} 2 + kube_horizontalpodautoscaler_created{horizontalpodautoscaler="hpa2",namespace="ns1"} 1.5e+09 + kube_horizontalpodautoscaler_deletion_timestamp{horizontalpodautoscaler="hpa2",namespace="ns1"} 1.8e+09 `, MetricNames: []string{ "kube_horizontalpodautoscaler_info", @@ -421,6 +436,8 @@ func TestHPAStore(t *testing.T) { "kube_horizontalpodautoscaler_status_condition", "kube_horizontalpodautoscaler_annotation", "kube_horizontalpodautoscaler_labels", + "kube_horizontalpodautoscaler_created", + "kube_horizontalpodautoscaler_deletion_timestamp", }, }, }