diff --git a/docs/pod-metrics.md b/docs/pod-metrics.md
index 8767ac238b..3aafdbed1c 100644
--- a/docs/pod-metrics.md
+++ b/docs/pod-metrics.md
@@ -10,6 +10,8 @@
| kube_pod_labels | Gauge | Kubernetes labels converted to Prometheus labels | | `pod`=<pod-name>
`namespace`=<pod-namespace>
`label_POD_LABEL`=<POD_LABEL>
`uid`=<pod-uid> | STABLE |
| kube_pod_status_phase | Gauge | The pods current phase | | `pod`=<pod-name>
`namespace`=<pod-namespace>
`phase`=<Pending\|Running\|Succeeded\|Failed\|Unknown>
`uid`=<pod-uid> | STABLE |
| kube_pod_status_ready | Gauge | Describes whether the pod is ready to serve requests | | `pod`=<pod-name>
`namespace`=<pod-namespace>
`condition`=<true\|false\|unknown>
`uid`=<pod-uid> | STABLE |
+| kube_pod_status_ready_time | Gauge | Time when pod passed readiness probes. | seconds | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | STABLE |
+| kube_pod_status_containers_ready_time | Gauge | Time when pod containers entered Ready state. | seconds | `pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | STABLE |
| kube_pod_status_scheduled | Gauge | Describes the status of the scheduling process for the pod | |`pod`=<pod-name>
`namespace`=<pod-namespace>
`condition`=<true\|false\|unknown>
`uid`=<pod-uid> | STABLE |
| kube_pod_container_info | Gauge | Information about a container in a pod | | `container`=<container-name>
`pod`=<pod-name>
`namespace`=<pod-namespace>
`image`=<image-name>
`image_id`=<image-id>
`image_spec`=<image-spec>
`container_id`=<containerid>
`uid`=<pod-uid> | STABLE |
| kube_pod_container_status_waiting | Gauge | Describes whether the container is currently in waiting state | | `container`=<container-name>
`pod`=<pod-name>
`namespace`=<pod-namespace>
`uid`=<pod-uid> | STABLE |
diff --git a/internal/store/pod.go b/internal/store/pod.go
index f4783419c4..91eb69ce5d 100644
--- a/internal/store/pod.go
+++ b/internal/store/pod.go
@@ -78,6 +78,8 @@ func podMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat
createPodStartTimeFamilyGenerator(),
createPodStatusPhaseFamilyGenerator(),
createPodStatusReadyFamilyGenerator(),
+ createPodStatusReadyTimeFamilyGenerator(),
+ createPodStatusContainersReadyTimeFamilyGenerator(),
createPodStatusReasonFamilyGenerator(),
createPodStatusScheduledFamilyGenerator(),
createPodStatusScheduledTimeFamilyGenerator(),
@@ -1179,6 +1181,32 @@ func createPodStartTimeFamilyGenerator() generator.FamilyGenerator {
)
}
+func createPodStatusContainersReadyTimeFamilyGenerator() generator.FamilyGenerator {
+ return *generator.NewFamilyGenerator(
+ "kube_pod_status_containers_ready_time",
+ "Readiness achieved time in unix timestamp for a pod containers.",
+ metric.Gauge,
+ "",
+ wrapPodFunc(func(p *v1.Pod) *metric.Family {
+ ms := []*metric.Metric{}
+
+ for _, c := range p.Status.Conditions {
+ if c.Type == v1.ContainersReady {
+ ms = append(ms, &metric.Metric{
+ LabelKeys: []string{},
+ LabelValues: []string{},
+ Value: float64((c.LastTransitionTime).Unix()),
+ })
+ }
+ }
+
+ return &metric.Family{
+ Metrics: ms,
+ }
+ }),
+ )
+}
+
func createPodStatusPhaseFamilyGenerator() generator.FamilyGenerator {
return *generator.NewFamilyGenerator(
"kube_pod_status_phase",
@@ -1250,6 +1278,32 @@ func createPodStatusReadyFamilyGenerator() generator.FamilyGenerator {
)
}
+func createPodStatusReadyTimeFamilyGenerator() generator.FamilyGenerator {
+ return *generator.NewFamilyGenerator(
+ "kube_pod_status_ready_time",
+ "Readiness achieved time in unix timestamp for a pod.",
+ metric.Gauge,
+ "",
+ wrapPodFunc(func(p *v1.Pod) *metric.Family {
+ ms := []*metric.Metric{}
+
+ for _, c := range p.Status.Conditions {
+ if c.Type == v1.PodReady {
+ ms = append(ms, &metric.Metric{
+ LabelKeys: []string{},
+ LabelValues: []string{},
+ Value: float64((c.LastTransitionTime).Unix()),
+ })
+ }
+ }
+
+ return &metric.Family{
+ Metrics: ms,
+ }
+ }),
+ )
+}
+
func createPodStatusReasonFamilyGenerator() generator.FamilyGenerator {
return *generator.NewFamilyGenerator(
"kube_pod_status_reason",
diff --git a/internal/store/pod_test.go b/internal/store/pod_test.go
index a1ec7f483d..a3097beb9b 100644
--- a/internal/store/pod_test.go
+++ b/internal/store/pod_test.go
@@ -1366,13 +1366,19 @@ func TestPodStore(t *testing.T) {
{
Type: v1.PodReady,
Status: v1.ConditionTrue,
+ LastTransitionTime: metav1.Time{
+ Time: time.Unix(1501666018, 0),
+ },
},
},
},
},
Want: `
# HELP kube_pod_status_ready Describes whether the pod is ready to serve requests.
- # TYPE kube_pod_status_ready gauge
+ # HELP kube_pod_status_ready_time Readiness achieved time in unix timestamp for a pod.
+ # TYPE kube_pod_status_ready gauge
+ # TYPE kube_pod_status_ready_time gauge
+ kube_pod_status_ready_time{namespace="ns1",pod="pod1",uid="uid1"} 1.501666018e+09
kube_pod_status_ready{condition="false",namespace="ns1",pod="pod1",uid="uid1"} 0
kube_pod_status_ready{condition="true",namespace="ns1",pod="pod1",uid="uid1"} 1
kube_pod_status_ready{condition="unknown",namespace="ns1",pod="pod1",uid="uid1"} 0
@@ -1391,16 +1397,22 @@ func TestPodStore(t *testing.T) {
{
Type: v1.PodReady,
Status: v1.ConditionFalse,
+ LastTransitionTime: metav1.Time{
+ Time: time.Unix(1501666018, 0),
+ },
},
},
},
},
Want: `
# HELP kube_pod_status_ready Describes whether the pod is ready to serve requests.
- # TYPE kube_pod_status_ready gauge
- kube_pod_status_ready{condition="false",namespace="ns2",pod="pod2",uid="uid2"} 1
- kube_pod_status_ready{condition="true",namespace="ns2",pod="pod2",uid="uid2"} 0
- kube_pod_status_ready{condition="unknown",namespace="ns2",pod="pod2",uid="uid2"} 0
+ # HELP kube_pod_status_ready_time Readiness achieved time in unix timestamp for a pod.
+ # TYPE kube_pod_status_ready gauge
+ # TYPE kube_pod_status_ready_time gauge
+ kube_pod_status_ready_time{namespace="ns2",pod="pod2",uid="uid2"} 1.501666018e+09
+ kube_pod_status_ready{condition="false",namespace="ns2",pod="pod2",uid="uid2"} 1
+ kube_pod_status_ready{condition="true",namespace="ns2",pod="pod2",uid="uid2"} 0
+ kube_pod_status_ready{condition="unknown",namespace="ns2",pod="pod2",uid="uid2"} 0
`,
MetricNames: []string{"kube_pod_status_ready"},
},
@@ -1925,7 +1937,7 @@ func BenchmarkPodStore(b *testing.B) {
},
}
- expectedFamilies := 43
+ expectedFamilies := 45
for n := 0; n < b.N; n++ {
families := f(pod)
if len(families) != expectedFamilies {
diff --git a/pkg/app/server_test.go b/pkg/app/server_test.go
index 53cd0356dd..87b7a415a3 100644
--- a/pkg/app/server_test.go
+++ b/pkg/app/server_test.go
@@ -209,14 +209,16 @@ func TestFullScrapeCycle(t *testing.T) {
# HELP kube_pod_labels Kubernetes labels converted to Prometheus labels.
# HELP kube_pod_overhead_cpu_cores The pod overhead in regards to cpu cores associated with running a pod.
# HELP kube_pod_overhead_memory_bytes The pod overhead in regards to memory associated with running a pod.
-# HELP kube_pod_runtimeclass_name_info The runtimeclass associated with the pod.
# HELP kube_pod_owner Information about the Pod's owner.
# HELP kube_pod_restart_policy Describes the restart policy in use by this pod.
+# HELP kube_pod_runtimeclass_name_info The runtimeclass associated with the pod.
# HELP kube_pod_spec_volumes_persistentvolumeclaims_info Information about persistentvolumeclaim volumes in a pod.
# HELP kube_pod_spec_volumes_persistentvolumeclaims_readonly Describes whether a persistentvolumeclaim is mounted read only.
# HELP kube_pod_start_time Start time in unix timestamp for a pod.
+# HELP kube_pod_status_containers_ready_time Readiness achieved time in unix timestamp for a pod containers.
# HELP kube_pod_status_phase The pods current phase.
# HELP kube_pod_status_ready Describes whether the pod is ready to serve requests.
+# HELP kube_pod_status_ready_time Readiness achieved time in unix timestamp for a pod.
# HELP kube_pod_status_reason The pod status reasons
# HELP kube_pod_status_scheduled Describes the status of the scheduling process for the pod.
# HELP kube_pod_status_scheduled_time Unix timestamp when pod moved into scheduled status
@@ -252,14 +254,16 @@ func TestFullScrapeCycle(t *testing.T) {
# TYPE kube_pod_labels gauge
# TYPE kube_pod_overhead_cpu_cores gauge
# TYPE kube_pod_overhead_memory_bytes gauge
-# TYPE kube_pod_runtimeclass_name_info gauge
# TYPE kube_pod_owner gauge
# TYPE kube_pod_restart_policy gauge
+# TYPE kube_pod_runtimeclass_name_info gauge
# TYPE kube_pod_spec_volumes_persistentvolumeclaims_info gauge
# TYPE kube_pod_spec_volumes_persistentvolumeclaims_readonly gauge
# TYPE kube_pod_start_time gauge
+# TYPE kube_pod_status_containers_ready_time gauge
# TYPE kube_pod_status_phase gauge
# TYPE kube_pod_status_ready gauge
+# TYPE kube_pod_status_ready_time gauge
# TYPE kube_pod_status_reason gauge
# TYPE kube_pod_status_scheduled gauge
# TYPE kube_pod_status_scheduled_time gauge