@@ -9,21 +9,32 @@ import (
99 "github.com/prometheus/client_golang/prometheus"
1010 "github.com/webdevops/go-common/prometheus/collector"
1111 "github.com/webdevops/go-common/utils/to"
12+ "golang.org/x/exp/slices"
1213)
1314
1415const (
1516 CUSTOMPROP_LABEL_FMT = "prop_%s"
1617)
1718
19+ var (
20+ githubWorkflowRunningStatus = []string {"in_progress" , "action_required" , "queued" , "waiting" , "pending" }
21+ )
22+
1823type (
1924 MetricsCollectorGithubWorkflows struct {
2025 collector.Processor
2126
2227 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+
2738 workflowConsecutiveFailures * prometheus.GaugeVec
2839 }
2940 }
@@ -37,6 +48,9 @@ func (m *MetricsCollectorGithubWorkflows) Setup(collector *collector.Collector)
3748 customPropLabels = append (customPropLabels , fmt .Sprintf (CUSTOMPROP_LABEL_FMT , customProp ))
3849 }
3950
51+ // ##############################################################3
52+ // Infrastructure
53+
4054 m .prometheus .repository = prometheus .NewGaugeVec (
4155 prometheus.GaugeOpts {
4256 Name : "github_repository_info" ,
@@ -72,10 +86,13 @@ func (m *MetricsCollectorGithubWorkflows) Setup(collector *collector.Collector)
7286 )
7387 m .Collector .RegisterMetricList ("workflow" , m .prometheus .workflow , true )
7488
75- m .prometheus .workflowLatestRun = prometheus .NewGaugeVec (
89+ // ##############################################################3
90+ // Workflow run running
91+
92+ m .prometheus .workflowRunRunning = prometheus .NewGaugeVec (
7693 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" ,
7996 },
8097 []string {
8198 "org" ,
@@ -84,17 +101,33 @@ func (m *MetricsCollectorGithubWorkflows) Setup(collector *collector.Collector)
84101 "workflow" ,
85102 "event" ,
86103 "branch" ,
87- "conclusion " ,
104+ "status " ,
88105 "actorLogin" ,
89106 "actorType" ,
90107 },
91108 )
92- m .Collector .RegisterMetricList ("workflowLatestRun " , m .prometheus .workflowLatestRun , true )
109+ m .Collector .RegisterMetricList ("workflowRunRunning " , m .prometheus .workflowRunRunning , true )
93110
94- m .prometheus .workflowLatestRunTimestamp = prometheus .NewGaugeVec (
111+ m .prometheus .workflowRunRunningStartTime = prometheus .NewGaugeVec (
95112 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" ,
98131 },
99132 []string {
100133 "org" ,
@@ -108,7 +141,36 @@ func (m *MetricsCollectorGithubWorkflows) Setup(collector *collector.Collector)
108141 "actorType" ,
109142 },
110143 )
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
112174
113175 m .prometheus .workflowConsecutiveFailures = prometheus .NewGaugeVec (
114176 prometheus.GaugeOpts {
@@ -327,33 +389,66 @@ func (m *MetricsCollectorGithubWorkflows) Collect(callback chan<- func()) {
327389 }
328390
329391 if len (workflowRuns ) >= 1 {
392+ m .collectRunningRuns (Opts .GitHub .Organization , repo , workflowRuns , callback )
330393 m .collectLatestRun (Opts .GitHub .Organization , repo , workflowRuns , callback )
331394 m .collectConsecutiveFailures (Opts .GitHub .Organization , repo , workflowRuns , callback )
332395 }
333396 }
334397 }
335398}
336399
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+
337440func (m * MetricsCollectorGithubWorkflows ) collectLatestRun (org string , repo * github.Repository , workflowRun []* github.WorkflowRun , callback chan <- func ()) {
338441 runMetric := m .Collector .GetMetricList ("workflowLatestRun" )
339- runTimestampMetric := m .Collector .GetMetricList ("workflowLatestRunTimestamp" )
442+ runTimestampMetric := m .Collector .GetMetricList ("workflowLatestRunStartTime" )
443+ runDurationMetric := m .Collector .GetMetricList ("workflowLatestRunDuration" )
340444
341445 latestJobs := map [int64 ]* github.WorkflowRun {}
342446 for _ , row := range workflowRun {
343447 workflowRun := row
344448 workflowId := workflowRun .GetWorkflowID ()
345449
346450 // 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 ()) {
357452 continue
358453 }
359454
@@ -370,7 +465,7 @@ func (m *MetricsCollectorGithubWorkflows) collectLatestRun(org string, repo *git
370465 }
371466
372467 for _ , workflowRun := range latestJobs {
373- labels := prometheus.Labels {
468+ infoLabels := prometheus.Labels {
374469 "org" : org ,
375470 "repo" : repo .GetName (),
376471 "workflowID" : fmt .Sprintf ("%v" , workflowRun .GetWorkflowID ()),
@@ -382,8 +477,15 @@ func (m *MetricsCollectorGithubWorkflows) collectLatestRun(org string, repo *git
382477 "actorType" : workflowRun .Actor .GetType (),
383478 }
384479
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 ())
387489 }
388490}
389491
0 commit comments