improvement(go.d/k8state): add CronJob suspend status (#19829)
* improvement(go.d/k8state): add CronJob suspend status * fix tests
Ilya Mashchenko committed
Mar 12, 2025 at 14:03 UTC
aed408ec41f996d437f2493713da9d47ae78d181
6 files changed
+54
-2
src/go/plugin/go.d/collector/k8s_state/charts.go
+15
@@ -68,6 +68,7 @@ const (
68
prioCronJobLastCompletionDuration
69
prioCronJobLastCompletedTimeAgo
70
prioCronJobLastScheduleTimeAgo
71
+ prioCronJobSuspendStatus
72
prioCronJobAge
73
)
74
@@ -153,6 +154,7 @@ var cronJobChartsTmpl = module.Charts{
154
cronJobLastCompletionDurationChartTmpl.Copy(),
155
cronJobLastCompletedTimeAgoChartTmpl.Copy(),
156
cronJobLastScheduleTimeAgoChartTmpl.Copy(),
157
+ cronJobSuspendStatusChartTmpl.Copy(),
158
cronJobAgeChartTmpl.Copy(),
159
}
160
@@ -929,6 +931,19 @@ var (
931
{ID: "cronjob_%s_last_schedule_seconds_ago", Name: "last_schedule_ago"},
932
},
933
}
934
+ cronJobSuspendStatusChartTmpl = module.Chart{
935
+ IDSep: true,
936
+ ID: "cronjob_%s.suspend_status",
937
+ Title: "CronJob Suspend Status",
938
+ Units: "status",
939
+ Fam: "cronjob status",
940
+ Ctx: "k8s_state.cronjob_suspend_status",
941
+ Priority: prioCronJobSuspendStatus,
942
+ Dims: module.Dims{
943
+ {ID: "cronjob_%s_suspend_status_enabled", Name: "enabled"},
944
+ {ID: "cronjob_%s_suspend_status_suspended", Name: "suspended"},
945
+ },
946
+ }
947
cronJobAgeChartTmpl = module.Chart{
948
IDSep: true,
949
ID: "cronjob_%s.age",
src/go/plugin/go.d/collector/k8s_state/collect.go
+3
@@ -388,6 +388,9 @@ func (c *Collector) collectCronJobState(mx map[string]int64) {
388
mx[px+"complete_jobs"] = 0
389
mx[px+"suspended_jobs"] = 0
390
391
+ mx[px+"suspend_status_enabled"] = metrix.Bool(!st.suspend)
392
+ mx[px+"suspend_status_suspended"] = metrix.Bool(st.suspend)
393
+
394
mx[px+"failed_jobs_reason_pod_failure_policy"] = 0
395
mx[px+"failed_jobs_reason_backoff_limit_exceeded"] = 0
396
mx[px+"failed_jobs_reason_deadline_exceeded"] = 0
src/go/plugin/go.d/collector/k8s_state/collector_test.go
+23
-2
@@ -515,6 +515,8 @@ func TestCollector_Collect(t *testing.T) {
515
"CronJobs": {
516
create: func(t *testing.T) testCase {
517
cj := prepareCronJob("cronjob01")
518
+ cjSuspended := prepareCronJob("cronjob02")
519
+ cjSuspended.Spec.Suspend = ptr(true)
520
jobNotStarted := prepareCronJobNotStartedJob("job-not-started", cj)
521
jobComplete := prepareCronJobCompleteJob("job-complete", cj)
522
jobFailed := prepareCronJobFailedJob("job-failed", cj)
@@ -522,6 +524,7 @@ func TestCollector_Collect(t *testing.T) {
524
jobSuspended := prepareCronJobSuspendedJob("job-suspended", cj)
525
526
client := fake.NewClientset(
527
+ cjSuspended,
528
cj,
529
jobNotStarted,
530
jobComplete,
@@ -545,7 +548,23 @@ func TestCollector_Collect(t *testing.T) {
548
"cronjob_default_cronjob01_last_schedule_seconds_ago": 130,
549
"cronjob_default_cronjob01_last_successful_seconds_ago": 70,
550
"cronjob_default_cronjob01_running_jobs": 1,
551
+ "cronjob_default_cronjob01_suspend_status_enabled": 1,
552
+ "cronjob_default_cronjob01_suspend_status_suspended": 0,
553
"cronjob_default_cronjob01_suspended_jobs": 1,
554
+ "cronjob_default_cronjob02_age": 10,
555
+ "cronjob_default_cronjob02_complete_jobs": 0,
556
+ "cronjob_default_cronjob02_failed_jobs": 0,
557
+ "cronjob_default_cronjob02_failed_jobs_reason_backoff_limit_exceeded": 0,
558
+ "cronjob_default_cronjob02_failed_jobs_reason_deadline_exceeded": 0,
559
+ "cronjob_default_cronjob02_failed_jobs_reason_pod_failure_policy": 0,
560
+ "cronjob_default_cronjob02_last_execution_status_failed": 0,
561
+ "cronjob_default_cronjob02_last_execution_status_succeeded": 0,
562
+ "cronjob_default_cronjob02_last_schedule_seconds_ago": 130,
563
+ "cronjob_default_cronjob02_last_successful_seconds_ago": 70,
564
+ "cronjob_default_cronjob02_running_jobs": 0,
565
+ "cronjob_default_cronjob02_suspend_status_enabled": 0,
566
+ "cronjob_default_cronjob02_suspend_status_suspended": 1,
567
+ "cronjob_default_cronjob02_suspended_jobs": 0,
568
"discovery_node_discoverer_state": 1,
569
"discovery_pod_discoverer_state": 1,
570
}
@@ -554,11 +573,13 @@ func TestCollector_Collect(t *testing.T) {
573
574
assert.Equal(t, expected, mx)
575
assert.Equal(t,
557
- len(cronJobChartsTmpl)+
576
+ len(cronJobChartsTmpl)*2+
577
len(baseCharts),
578
len(*collr.Charts()),
579
)
561
- module.TestMetricsHasAllChartsDims(t, collr.Charts(), mx)
580
+ module.TestMetricsHasAllChartsDimsSkip(t, collr.Charts(), mx, func(chart *module.Chart, dim *module.Dim) bool {
581
+ return strings.Contains(chart.ID, cjSuspended.Name) && strings.HasSuffix(chart.ID, "last_completion_duration")
582
+ })
583
}
584
585
return testCase{
src/go/plugin/go.d/collector/k8s_state/metadata.yaml
+7
@@ -309,6 +309,13 @@ modules:
309
chart_type: line
310
dimensions:
311
- name: last_schedule_ago
312
+ - name: k8s_state.cronjob_suspend_status
313
+ description: CronJob Suspend Status
314
+ unit: 'status'
315
+ chart_type: line
316
+ dimensions:
317
+ - name: enabled
318
+ - name: suspended
319
- name: k8s_state.cronjob_age
320
description: CronJob Age
321
unit: 'seconds'
src/go/plugin/go.d/collector/k8s_state/state.go
+1
@@ -203,6 +203,7 @@ type cronJobState struct {
203
namespace string
204
creationTime time.Time
205
206
+ suspend bool
207
lastScheduleTime *time.Time
208
lastSuccessfulTime *time.Time
209
}
src/go/plugin/go.d/collector/k8s_state/update_cronjob_state.go
+5
@@ -27,6 +27,11 @@ func (c *Collector) updateCronJobState(r resource) {
27
st.creationTime = cj.CreationTimestamp.Time
28
}
29
30
+ st.suspend = false
31
+ if cj.Spec.Suspend != nil {
32
+ st.suspend = *cj.Spec.Suspend
33
+ }
34
+
35
st.lastScheduleTime = nil
36
st.lastSuccessfulTime = nil
37