diff --git a/docs/statefulset-metrics.md b/docs/statefulset-metrics.md
index 80c51629..6ed42f32 100644
--- a/docs/statefulset-metrics.md
+++ b/docs/statefulset-metrics.md
@@ -10,7 +10,7 @@
| kube_statefulset_status_replicas_updated | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace> | STABLE |
| kube_statefulset_status_observed_generation | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace> | STABLE |
| kube_statefulset_replicas | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace> | STABLE |
-| kube_statefulset_ordinal_start | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace> | ALPHA |
+| kube_statefulset_ordinals_start | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace> | ALPHA |
| kube_statefulset_metadata_generation | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace> | STABLE |
| kube_statefulset_persistentvolumeclaim_retention_policy | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace>
`when_deleted`=<statefulset-when-deleted-pvc-policy>
`when_scaled`=<statefulset-when-scaled-pvc-policy> | EXPERIMENTAL |
| kube_statefulset_created | Gauge | `statefulset`=<statefulset-name>
`namespace`=<statefulset-namespace> | STABLE |
diff --git a/internal/store/statefulset.go b/internal/store/statefulset.go
index d5d57e5b..528b536c 100644
--- a/internal/store/statefulset.go
+++ b/internal/store/statefulset.go
@@ -178,6 +178,26 @@ func statefulSetMetricFamilies(allowAnnotationsList, allowLabelsList []string) [
}
}),
),
+ *generator.NewFamilyGeneratorWithStability(
+ "kube_statefulset_ordinals_start",
+ "Start ordinal of the StatefulSet.",
+ metric.Gauge,
+ basemetrics.ALPHA,
+ "",
+ wrapStatefulSetFunc(func(s *v1.StatefulSet) *metric.Family {
+ ms := []*metric.Metric{}
+
+ if s.Spec.Ordinals != nil {
+ ms = append(ms, &metric.Metric{
+ Value: float64(s.Spec.Ordinals.Start),
+ })
+ }
+
+ return &metric.Family{
+ Metrics: ms,
+ }
+ }),
+ ),
*generator.NewFamilyGeneratorWithStability(
"kube_statefulset_metadata_generation",
"Sequence number representing a specific generation of the desired state for the StatefulSet.",
diff --git a/internal/store/statefulset_test.go b/internal/store/statefulset_test.go
index e48a96d9..dd68756d 100644
--- a/internal/store/statefulset_test.go
+++ b/internal/store/statefulset_test.go
@@ -65,6 +65,7 @@ func TestStatefulSetStore(t *testing.T) {
# HELP kube_statefulset_metadata_generation [STABLE] Sequence number representing a specific generation of the desired state for the StatefulSet.
# HELP kube_statefulset_persistentvolumeclaim_retention_policy Count of retention policy for StatefulSet template PVCs
# HELP kube_statefulset_replicas [STABLE] Number of desired pods for a StatefulSet.
+ # HELP kube_statefulset_ordinals_start Start ordinal of the StatefulSet.
# HELP kube_statefulset_status_current_revision [STABLE] Indicates the version of the StatefulSet used to generate Pods in the sequence [0,currentReplicas).
# HELP kube_statefulset_status_observed_generation [STABLE] The generation observed by the StatefulSet controller.
# HELP kube_statefulset_status_replicas [STABLE] The number of replicas per StatefulSet.
@@ -78,6 +79,7 @@ func TestStatefulSetStore(t *testing.T) {
# TYPE kube_statefulset_metadata_generation gauge
# TYPE kube_statefulset_persistentvolumeclaim_retention_policy gauge
# TYPE kube_statefulset_replicas gauge
+ # TYPE kube_statefulset_ordinals_start gauge
# TYPE kube_statefulset_status_current_revision gauge
# TYPE kube_statefulset_status_observed_generation gauge
# TYPE kube_statefulset_status_replicas gauge
@@ -104,6 +106,7 @@ func TestStatefulSetStore(t *testing.T) {
"kube_statefulset_labels",
"kube_statefulset_metadata_generation",
"kube_statefulset_replicas",
+ "kube_statefulset_ordinals_start",
"kube_statefulset_status_observed_generation",
"kube_statefulset_status_replicas",
"kube_statefulset_status_replicas_available",
@@ -335,6 +338,83 @@ func TestStatefulSetStore(t *testing.T) {
"kube_statefulset_persistentvolumeclaim_retention_policy",
},
},
+ {
+ // Validate kube_statefulset_ordinals_start metric.
+ Obj: &v1.StatefulSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "statefulset5",
+ Namespace: "ns5",
+ Labels: map[string]string{
+ "app": "example5",
+ },
+ Generation: 1,
+ },
+ Spec: v1.StatefulSetSpec{
+ Replicas: &statefulSet1Replicas,
+ ServiceName: "statefulset5service",
+ Ordinals: &v1.StatefulSetOrdinals{
+ Start: 2,
+ },
+ },
+ Status: v1.StatefulSetStatus{
+ ObservedGeneration: 0,
+ Replicas: 3,
+ UpdateRevision: "ur5",
+ CurrentRevision: "cr5",
+ },
+ },
+ Want: `
+ # HELP kube_statefulset_labels [STABLE] Kubernetes labels converted to Prometheus labels.
+ # HELP kube_statefulset_metadata_generation [STABLE] Sequence number representing a specific generation of the desired state for the StatefulSet.
+ # HELP kube_statefulset_persistentvolumeclaim_retention_policy Count of retention policy for StatefulSet template PVCs
+ # HELP kube_statefulset_replicas [STABLE] Number of desired pods for a StatefulSet.
+ # HELP kube_statefulset_ordinals_start Start ordinal of the StatefulSet.
+ # HELP kube_statefulset_status_current_revision [STABLE] Indicates the version of the StatefulSet used to generate Pods in the sequence [0,currentReplicas).
+ # HELP kube_statefulset_status_replicas [STABLE] The number of replicas per StatefulSet.
+ # HELP kube_statefulset_status_replicas_available The number of available replicas per StatefulSet.
+ # HELP kube_statefulset_status_replicas_current [STABLE] The number of current replicas per StatefulSet.
+ # HELP kube_statefulset_status_replicas_ready [STABLE] The number of ready replicas per StatefulSet.
+ # HELP kube_statefulset_status_replicas_updated [STABLE] The number of updated replicas per StatefulSet.
+ # HELP kube_statefulset_status_update_revision [STABLE] Indicates the version of the StatefulSet used to generate Pods in the sequence [replicas-updatedReplicas,replicas)
+ # TYPE kube_statefulset_labels gauge
+ # TYPE kube_statefulset_metadata_generation gauge
+ # TYPE kube_statefulset_persistentvolumeclaim_retention_policy gauge
+ # TYPE kube_statefulset_replicas gauge
+ # TYPE kube_statefulset_ordinals_start gauge
+ # TYPE kube_statefulset_status_current_revision gauge
+ # TYPE kube_statefulset_status_replicas gauge
+ # TYPE kube_statefulset_status_replicas_available gauge
+ # TYPE kube_statefulset_status_replicas_current gauge
+ # TYPE kube_statefulset_status_replicas_ready gauge
+ # TYPE kube_statefulset_status_replicas_updated gauge
+ # TYPE kube_statefulset_status_update_revision gauge
+ kube_statefulset_status_update_revision{namespace="ns5",revision="ur5",statefulset="statefulset5"} 1
+ kube_statefulset_status_replicas{namespace="ns5",statefulset="statefulset5"} 3
+ kube_statefulset_status_replicas_available{namespace="ns5",statefulset="statefulset5"} 0
+ kube_statefulset_status_replicas_current{namespace="ns5",statefulset="statefulset5"} 0
+ kube_statefulset_status_replicas_ready{namespace="ns5",statefulset="statefulset5"} 0
+ kube_statefulset_status_replicas_updated{namespace="ns5",statefulset="statefulset5"} 0
+ kube_statefulset_replicas{namespace="ns5",statefulset="statefulset5"} 3
+ kube_statefulset_ordinals_start{namespace="ns5",statefulset="statefulset5"} 2
+ kube_statefulset_metadata_generation{namespace="ns5",statefulset="statefulset5"} 1
+ kube_statefulset_labels{namespace="ns5",statefulset="statefulset5"} 1
+ kube_statefulset_status_current_revision{namespace="ns5",revision="cr5",statefulset="statefulset5"} 1
+ `,
+ MetricNames: []string{
+ "kube_statefulset_labels",
+ "kube_statefulset_metadata_generation",
+ "kube_statefulset_replicas",
+ "kube_statefulset_ordinals_start",
+ "kube_statefulset_status_replicas",
+ "kube_statefulset_status_replicas_available",
+ "kube_statefulset_status_replicas_current",
+ "kube_statefulset_status_replicas_ready",
+ "kube_statefulset_status_replicas_updated",
+ "kube_statefulset_status_update_revision",
+ "kube_statefulset_status_current_revision",
+ "kube_statefulset_persistentvolumeclaim_retention_policy",
+ },
+ },
}
for i, c := range cases {
c.Func = generator.ComposeMetricGenFuncs(statefulSetMetricFamilies(nil, nil))