Skip to content

Commit 8db4480

Browse files
committed
adding kube_job_status_ready metrics
1 parent c892a3f commit 8db4480

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

docs/metrics/workload/job-metrics.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@
1818
| kube_job_failed | Gauge | | `job_name`=&lt;job-name&gt; <br> `namespace`=&lt;job-namespace&gt; <br> `condition`=&lt;true\|false\|unknown&gt; | STABLE |
1919
| kube_job_created | Gauge | | `job_name`=&lt;job-name&gt; <br> `namespace`=&lt;job-namespace&gt; | STABLE |
2020
| kube_job_status_suspended | Gauge | | `job_name`=&lt;job-name&gt; <br> `namespace`=&lt;job-namespace&gt; | EXPERIMENTAL |
21+
| kube_job_status_ready | Gauge | The number of ready pods that belong to this Job. | `job_name`=&lt;job-name&gt; <br> `namespace`=&lt;job-namespace&gt; | EXPERIMENTAL |

internal/store/job.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,26 @@ func jobMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generat
266266
}
267267
}),
268268
),
269+
*generator.NewFamilyGeneratorWithStability(
270+
"kube_job_status_ready",
271+
"The number of ready pods that belong to this Job.",
272+
metric.Gauge,
273+
basemetrics.ALPHA,
274+
"",
275+
wrapJobFunc(func(j *v1batch.Job) *metric.Family {
276+
value := float64(0)
277+
if j.Status.Ready != nil {
278+
value = float64(*j.Status.Ready)
279+
}
280+
return &metric.Family{
281+
Metrics: []*metric.Metric{
282+
{
283+
Value: value,
284+
},
285+
},
286+
}
287+
}),
288+
),
269289
*generator.NewFamilyGeneratorWithStability(
270290
"kube_job_complete",
271291
"The job has completed its execution.",

internal/store/job_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ var (
4545
func TestJobStore(t *testing.T) {
4646
var trueValue = true
4747
var falseValue = false
48+
var readyValue int32 = 1
4849

4950
// Fixed metadata on type and help text. We prepend this to every expected
5051
// output so we only have to modify a single place when doing adjustments.
@@ -81,6 +82,8 @@ func TestJobStore(t *testing.T) {
8182
# TYPE kube_job_status_succeeded gauge
8283
# HELP kube_job_status_suspended The number of pods which reached Phase Suspended.
8384
# TYPE kube_job_status_suspended gauge
85+
# HELP kube_job_status_ready The number of ready pods that belong to this Job.
86+
# TYPE kube_job_status_ready gauge
8487
`
8588

8689
cases := []generateMetricsTestCase{
@@ -124,6 +127,7 @@ func TestJobStore(t *testing.T) {
124127
kube_job_spec_parallelism{job_name="RunningJob1",namespace="ns1"} 1
125128
kube_job_status_active{job_name="RunningJob1",namespace="ns1"} 1
126129
kube_job_status_failed{job_name="RunningJob1",namespace="ns1"} 0
130+
kube_job_status_ready{job_name="RunningJob1",namespace="ns1"} 0
127131
kube_job_status_start_time{job_name="RunningJob1",namespace="ns1"} 1.495800007e+09
128132
kube_job_status_succeeded{job_name="RunningJob1",namespace="ns1"} 0
129133
`,
@@ -166,6 +170,7 @@ func TestJobStore(t *testing.T) {
166170
kube_job_status_active{job_name="SuccessfulJob1",namespace="ns1"} 0
167171
kube_job_status_completion_time{job_name="SuccessfulJob1",namespace="ns1"} 1.495803607e+09
168172
kube_job_status_failed{job_name="SuccessfulJob1",namespace="ns1"} 0
173+
kube_job_status_ready{job_name="SuccessfulJob1",namespace="ns1"} 0
169174
kube_job_status_start_time{job_name="SuccessfulJob1",namespace="ns1"} 1.495800007e+09
170175
kube_job_status_succeeded{job_name="SuccessfulJob1",namespace="ns1"} 1
171176
`,
@@ -210,6 +215,7 @@ func TestJobStore(t *testing.T) {
210215
kube_job_status_failed{job_name="FailedJob1",namespace="ns1",reason="BackoffLimitExceeded"} 1
211216
kube_job_status_failed{job_name="FailedJob1",namespace="ns1",reason="DeadlineExceeded"} 0
212217
kube_job_status_failed{job_name="FailedJob1",namespace="ns1",reason="Evicted"} 0
218+
kube_job_status_ready{job_name="FailedJob1",namespace="ns1"} 0
213219
kube_job_status_start_time{job_name="FailedJob1",namespace="ns1"} 1.495807207e+09
214220
kube_job_status_succeeded{job_name="FailedJob1",namespace="ns1"} 0
215221
`,
@@ -233,6 +239,7 @@ func TestJobStore(t *testing.T) {
233239
kube_job_spec_active_deadline_seconds{job_name="FailedJobWithNoConditions",namespace="ns1"} 900
234240
kube_job_status_active{job_name="FailedJobWithNoConditions",namespace="ns1"} 0
235241
kube_job_status_failed{job_name="FailedJobWithNoConditions",namespace="ns1",reason=""} 1
242+
kube_job_status_ready{job_name="FailedJobWithNoConditions",namespace="ns1"} 0
236243
kube_job_status_succeeded{job_name="FailedJobWithNoConditions",namespace="ns1"} 0
237244
`,
238245
},
@@ -274,6 +281,7 @@ func TestJobStore(t *testing.T) {
274281
kube_job_status_active{job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 0
275282
kube_job_status_completion_time{job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 1.495804207e+09
276283
kube_job_status_failed{job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 0
284+
kube_job_status_ready{job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 0
277285
kube_job_status_start_time{job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 1.495800607e+09
278286
kube_job_status_succeeded{job_name="SuccessfulJob2NoActiveDeadlineSeconds",namespace="ns1"} 1
279287
`,
@@ -307,6 +315,7 @@ func TestJobStore(t *testing.T) {
307315
kube_job_spec_parallelism{job_name="SuspendedNoActiveDeadlineSeconds",namespace="ns1"} 1
308316
kube_job_status_active{job_name="SuspendedNoActiveDeadlineSeconds",namespace="ns1"} 0
309317
kube_job_status_failed{job_name="SuspendedNoActiveDeadlineSeconds",namespace="ns1"} 0
318+
kube_job_status_ready{job_name="SuspendedNoActiveDeadlineSeconds",namespace="ns1"} 0
310319
kube_job_status_start_time{job_name="SuspendedNoActiveDeadlineSeconds",namespace="ns1"} 1.495800607e+09
311320
kube_job_status_succeeded{job_name="SuspendedNoActiveDeadlineSeconds",namespace="ns1"} 0
312321
kube_job_status_suspended{job_name="SuspendedNoActiveDeadlineSeconds",namespace="ns1"} 1
@@ -344,6 +353,29 @@ func TestJobStore(t *testing.T) {
344353
kube_job_status_start_time{job_name="UnsuspendedNoActiveDeadlineSeconds",namespace="ns1"} 1.495800607e+09
345354
kube_job_status_succeeded{job_name="UnsuspendedNoActiveDeadlineSeconds",namespace="ns1"} 0
346355
kube_job_status_suspended{job_name="UnsuspendedNoActiveDeadlineSeconds",namespace="ns1"} 0
356+
kube_job_status_ready{job_name="UnsuspendedNoActiveDeadlineSeconds",namespace="ns1"} 0
357+
`,
358+
},
359+
// Test cases for ready pods metric
360+
{
361+
Obj: &v1batch.Job{
362+
ObjectMeta: metav1.ObjectMeta{
363+
Name: "job-with-ready-pods",
364+
Namespace: "ns1",
365+
UID: "job-123",
366+
},
367+
Status: v1batch.JobStatus{
368+
Active: 2,
369+
Ready: &readyValue,
370+
},
371+
},
372+
Want: metadata + `
373+
kube_job_owner{job_name="job-with-ready-pods",namespace="ns1",owner_is_controller="",owner_kind="",owner_name=""} 1
374+
kube_job_info{job_name="job-with-ready-pods",namespace="ns1"} 1
375+
kube_job_status_active{job_name="job-with-ready-pods",namespace="ns1"} 2
376+
kube_job_status_failed{job_name="job-with-ready-pods",namespace="ns1"} 0
377+
kube_job_status_succeeded{job_name="job-with-ready-pods",namespace="ns1"} 0
378+
kube_job_status_ready{job_name="job-with-ready-pods",namespace="ns1"} 1
347379
`,
348380
},
349381
}

0 commit comments

Comments
 (0)