@@ -9,21 +9,32 @@ import (
9
9
"github.com/prometheus/client_golang/prometheus"
10
10
"github.com/webdevops/go-common/prometheus/collector"
11
11
"github.com/webdevops/go-common/utils/to"
12
+ "golang.org/x/exp/slices"
12
13
)
13
14
14
15
const (
15
16
CUSTOMPROP_LABEL_FMT = "prop_%s"
16
17
)
17
18
19
+ var (
20
+ githubWorkflowRunningStatus = []string {"in_progress" , "action_required" , "queued" , "waiting" , "pending" }
21
+ )
22
+
18
23
type (
19
24
MetricsCollectorGithubWorkflows struct {
20
25
collector.Processor
21
26
22
27
prometheus struct {
23
- repository * prometheus.GaugeVec
24
- workflow * prometheus.GaugeVec
25
- workflowLatestRun * prometheus.GaugeVec
26
- workflowLatestRunTimestamp * prometheus.GaugeVec
28
+ repository * prometheus.GaugeVec
29
+ workflow * prometheus.GaugeVec
30
+
31
+ workflowRunRunning * prometheus.GaugeVec
32
+ workflowRunRunningStartTime * prometheus.GaugeVec
33
+
34
+ workflowLatestRun * prometheus.GaugeVec
35
+ workflowLatestRunStartTime * prometheus.GaugeVec
36
+ workflowLatestRunDuration * prometheus.GaugeVec
37
+
27
38
workflowConsecutiveFailures * prometheus.GaugeVec
28
39
}
29
40
}
@@ -37,6 +48,9 @@ func (m *MetricsCollectorGithubWorkflows) Setup(collector *collector.Collector)
37
48
customPropLabels = append (customPropLabels , fmt .Sprintf (CUSTOMPROP_LABEL_FMT , customProp ))
38
49
}
39
50
51
+ // ##############################################################3
52
+ // Infrastructure
53
+
40
54
m .prometheus .repository = prometheus .NewGaugeVec (
41
55
prometheus.GaugeOpts {
42
56
Name : "github_repository_info" ,
@@ -72,10 +86,13 @@ func (m *MetricsCollectorGithubWorkflows) Setup(collector *collector.Collector)
72
86
)
73
87
m .Collector .RegisterMetricList ("workflow" , m .prometheus .workflow , true )
74
88
75
- m .prometheus .workflowLatestRun = prometheus .NewGaugeVec (
89
+ // ##############################################################3
90
+ // Workflow run running
91
+
92
+ m .prometheus .workflowRunRunning = prometheus .NewGaugeVec (
76
93
prometheus.GaugeOpts {
77
- Name : "github_workflow_latest_run " ,
78
- Help : "GitHub workflow latest run information" ,
94
+ Name : "github_workflow_run_running " ,
95
+ Help : "GitHub workflow running information" ,
79
96
},
80
97
[]string {
81
98
"org" ,
@@ -84,17 +101,33 @@ func (m *MetricsCollectorGithubWorkflows) Setup(collector *collector.Collector)
84
101
"workflow" ,
85
102
"event" ,
86
103
"branch" ,
87
- "conclusion " ,
104
+ "status " ,
88
105
"actorLogin" ,
89
106
"actorType" ,
90
107
},
91
108
)
92
- m .Collector .RegisterMetricList ("workflowLatestRun " , m .prometheus .workflowLatestRun , true )
109
+ m .Collector .RegisterMetricList ("workflowRunRunning " , m .prometheus .workflowRunRunning , true )
93
110
94
- m .prometheus .workflowLatestRunTimestamp = prometheus .NewGaugeVec (
111
+ m .prometheus .workflowRunRunningStartTime = prometheus .NewGaugeVec (
95
112
prometheus.GaugeOpts {
96
- Name : "github_workflow_latest_run_timestamp_seconds" ,
97
- Help : "GitHub workflow latest run last executed timestamp" ,
113
+ Name : "github_workflow_run_running_start_time_seconds" ,
114
+ Help : "GitHub workflow run running start time as unix timestamp" ,
115
+ },
116
+ []string {
117
+ "org" ,
118
+ "repo" ,
119
+ "workflowID" ,
120
+ },
121
+ )
122
+ m .Collector .RegisterMetricList ("workflowRunRunningStartTime" , m .prometheus .workflowRunRunningStartTime , true )
123
+
124
+ // ##############################################################3
125
+ // Workflow run latest
126
+
127
+ m .prometheus .workflowLatestRun = prometheus .NewGaugeVec (
128
+ prometheus.GaugeOpts {
129
+ Name : "github_workflow_latest_run" ,
130
+ Help : "GitHub workflow latest run information" ,
98
131
},
99
132
[]string {
100
133
"org" ,
@@ -108,7 +141,36 @@ func (m *MetricsCollectorGithubWorkflows) Setup(collector *collector.Collector)
108
141
"actorType" ,
109
142
},
110
143
)
111
- m .Collector .RegisterMetricList ("workflowLatestRunTimestamp" , m .prometheus .workflowLatestRunTimestamp , true )
144
+ m .Collector .RegisterMetricList ("workflowLatestRun" , m .prometheus .workflowLatestRun , true )
145
+
146
+ m .prometheus .workflowLatestRunStartTime = prometheus .NewGaugeVec (
147
+ prometheus.GaugeOpts {
148
+ Name : "github_workflow_latest_run_start_time_seconds" ,
149
+ Help : "GitHub workflow latest run last executed timestamp" ,
150
+ },
151
+ []string {
152
+ "org" ,
153
+ "repo" ,
154
+ "workflowID" ,
155
+ },
156
+ )
157
+ m .Collector .RegisterMetricList ("workflowLatestRunStartTime" , m .prometheus .workflowLatestRunStartTime , true )
158
+
159
+ m .prometheus .workflowLatestRunDuration = prometheus .NewGaugeVec (
160
+ prometheus.GaugeOpts {
161
+ Name : "github_workflow_latest_run_duration_seconds" ,
162
+ Help : "GitHub workflow latest run last duration in seconds" ,
163
+ },
164
+ []string {
165
+ "org" ,
166
+ "repo" ,
167
+ "workflowID" ,
168
+ },
169
+ )
170
+ m .Collector .RegisterMetricList ("workflowLatestRunDuration" , m .prometheus .workflowLatestRunDuration , true )
171
+
172
+ // ##############################################################3
173
+ // Workflow consecutive failed runs
112
174
113
175
m .prometheus .workflowConsecutiveFailures = prometheus .NewGaugeVec (
114
176
prometheus.GaugeOpts {
@@ -327,33 +389,66 @@ func (m *MetricsCollectorGithubWorkflows) Collect(callback chan<- func()) {
327
389
}
328
390
329
391
if len (workflowRuns ) >= 1 {
392
+ m .collectRunningRuns (Opts .GitHub .Organization , repo , workflowRuns , callback )
330
393
m .collectLatestRun (Opts .GitHub .Organization , repo , workflowRuns , callback )
331
394
m .collectConsecutiveFailures (Opts .GitHub .Organization , repo , workflowRuns , callback )
332
395
}
333
396
}
334
397
}
335
398
}
336
399
400
+ func (m * MetricsCollectorGithubWorkflows ) collectRunningRuns (org string , repo * github.Repository , workflowRun []* github.WorkflowRun , callback chan <- func ()) {
401
+ runMetric := m .Collector .GetMetricList ("workflowRunRunning" )
402
+ runStartTimeMetric := m .Collector .GetMetricList ("workflowRunRunningStartTime" )
403
+
404
+ for _ , row := range workflowRun {
405
+ workflowRun := row
406
+
407
+ // ignore non running workflows
408
+ if ! slices .Contains (githubWorkflowRunningStatus , workflowRun .GetStatus ()) {
409
+ continue
410
+ }
411
+
412
+ if workflowRun .GetConclusion () != "" {
413
+ // skip if task has a conclusion
414
+ continue
415
+ }
416
+
417
+ infoLabels := prometheus.Labels {
418
+ "org" : org ,
419
+ "repo" : repo .GetName (),
420
+ "workflowID" : fmt .Sprintf ("%v" , workflowRun .GetWorkflowID ()),
421
+ "workflow" : workflowRun .GetName (),
422
+ "event" : workflowRun .GetEvent (),
423
+ "branch" : workflowRun .GetHeadBranch (),
424
+ "status" : workflowRun .GetStatus (),
425
+ "actorLogin" : workflowRun .Actor .GetLogin (),
426
+ "actorType" : workflowRun .Actor .GetType (),
427
+ }
428
+
429
+ statLabels := prometheus.Labels {
430
+ "org" : org ,
431
+ "repo" : repo .GetName (),
432
+ "workflowID" : fmt .Sprintf ("%v" , workflowRun .GetWorkflowID ()),
433
+ }
434
+
435
+ runMetric .AddInfo (infoLabels )
436
+ runStartTimeMetric .AddTime (statLabels , workflowRun .GetRunStartedAt ().Time )
437
+ }
438
+ }
439
+
337
440
func (m * MetricsCollectorGithubWorkflows ) collectLatestRun (org string , repo * github.Repository , workflowRun []* github.WorkflowRun , callback chan <- func ()) {
338
441
runMetric := m .Collector .GetMetricList ("workflowLatestRun" )
339
- runTimestampMetric := m .Collector .GetMetricList ("workflowLatestRunTimestamp" )
442
+ runTimestampMetric := m .Collector .GetMetricList ("workflowLatestRunStartTime" )
443
+ runDurationMetric := m .Collector .GetMetricList ("workflowLatestRunDuration" )
340
444
341
445
latestJobs := map [int64 ]* github.WorkflowRun {}
342
446
for _ , row := range workflowRun {
343
447
workflowRun := row
344
448
workflowId := workflowRun .GetWorkflowID ()
345
449
346
450
// ignore running/not finished workflow runs
347
- switch workflowRun .GetStatus () {
348
- case "in_progress" :
349
- continue
350
- case "action_required" :
351
- continue
352
- case "queued" :
353
- continue
354
- case "waiting" :
355
- continue
356
- case "pending" :
451
+ if slices .Contains (githubWorkflowRunningStatus , workflowRun .GetStatus ()) {
357
452
continue
358
453
}
359
454
@@ -370,7 +465,7 @@ func (m *MetricsCollectorGithubWorkflows) collectLatestRun(org string, repo *git
370
465
}
371
466
372
467
for _ , workflowRun := range latestJobs {
373
- labels := prometheus.Labels {
468
+ infoLabels := prometheus.Labels {
374
469
"org" : org ,
375
470
"repo" : repo .GetName (),
376
471
"workflowID" : fmt .Sprintf ("%v" , workflowRun .GetWorkflowID ()),
@@ -382,8 +477,15 @@ func (m *MetricsCollectorGithubWorkflows) collectLatestRun(org string, repo *git
382
477
"actorType" : workflowRun .Actor .GetType (),
383
478
}
384
479
385
- runMetric .AddInfo (labels )
386
- runTimestampMetric .AddTime (labels , workflowRun .GetRunStartedAt ().Time )
480
+ statLabels := prometheus.Labels {
481
+ "org" : org ,
482
+ "repo" : repo .GetName (),
483
+ "workflowID" : fmt .Sprintf ("%v" , workflowRun .GetWorkflowID ()),
484
+ }
485
+
486
+ runMetric .AddInfo (infoLabels )
487
+ runTimestampMetric .AddTime (statLabels , workflowRun .GetRunStartedAt ().Time )
488
+ runDurationMetric .Add (statLabels , workflowRun .GetUpdatedAt ().Sub (workflowRun .GetCreatedAt ().Time ).Seconds ())
387
489
}
388
490
}
389
491
0 commit comments