diff --git a/internal/store/pod.go b/internal/store/pod.go index d9ad4afa6..f2714e5d0 100644 --- a/internal/store/pod.go +++ b/internal/store/pod.go @@ -1541,15 +1541,12 @@ func createPodStatusReasonFamilyGenerator() generator.FamilyGenerator { ms := []*metric.Metric{} for _, reason := range podStatusReasons { - metric := &metric.Metric{} - metric.LabelKeys = []string{"reason"} - metric.LabelValues = []string{reason} - if p.Status.Reason == reason { - metric.Value = boolFloat64(true) - } else { - metric.Value = boolFloat64(false) + m := &metric.Metric{ + LabelKeys: []string{"reason"}, + LabelValues: []string{reason}, + Value: getPodStatusReasonValue(p, reason), } - ms = append(ms, metric) + ms = append(ms, m) } return &metric.Family{ @@ -1559,6 +1556,23 @@ func createPodStatusReasonFamilyGenerator() generator.FamilyGenerator { ) } +func getPodStatusReasonValue(p *v1.Pod, reason string) float64 { + if p.Status.Reason == reason { + return 1 + } + for _, cond := range p.Status.Conditions { + if cond.Reason == reason { + return 1 + } + } + for _, cs := range p.Status.ContainerStatuses { + if cs.State.Terminated != nil && cs.State.Terminated.Reason == reason { + return 1 + } + } + return 0 +} + func createPodStatusScheduledFamilyGenerator() generator.FamilyGenerator { return *generator.NewFamilyGeneratorWithStability( "kube_pod_status_scheduled", diff --git a/internal/store/pod_test.go b/internal/store/pod_test.go index 3ba2875d0..113b65d00 100644 --- a/internal/store/pod_test.go +++ b/internal/store/pod_test.go @@ -2290,3 +2290,85 @@ func BenchmarkPodStore(b *testing.B) { } } } + +func TestGetPodStatusReasonValue(t *testing.T) { + reason := "TestReason" + + tests := []struct { + name string + pod *v1.Pod + want float64 + }{ + { + name: "matches Status.Reason", + pod: &v1.Pod{ + Status: v1.PodStatus{ + Reason: "TestReason", + }, + }, + want: 1, + }, + { + name: "matches condition Reason", + pod: &v1.Pod{ + Status: v1.PodStatus{ + Conditions: []v1.PodCondition{ + { + Reason: "TestReason", + }, + }, + }, + }, + want: 1, + }, + { + name: "matches container terminated Reason", + pod: &v1.Pod{ + Status: v1.PodStatus{ + ContainerStatuses: []v1.ContainerStatus{ + { + State: v1.ContainerState{ + Terminated: &v1.ContainerStateTerminated{ + Reason: "TestReason", + }, + }, + }, + }, + }, + }, + want: 1, + }, + { + name: "no match returns 0", + pod: &v1.Pod{ + Status: v1.PodStatus{ + Reason: "OtherReason", + Conditions: []v1.PodCondition{ + { + Reason: "NotTestReason", + }, + }, + ContainerStatuses: []v1.ContainerStatus{ + { + State: v1.ContainerState{ + Terminated: &v1.ContainerStateTerminated{ + Reason: "AnotherReason", + }, + }, + }, + }, + }, + }, + want: 0, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := getPodStatusReasonValue(tt.pod, reason) + if got != tt.want { + t.Errorf("getPodStatusReasonValue() = %v, want %v", got, tt.want) + } + }) + } +}