Skip to content

Commit 69ba047

Browse files
committed
refactoring
- add metric github_workflow_run_running - add metric github_workflow_run_running_start_time_seconds - add metric github_workflow_latest_run_duration_seconds - rename metric github_workflow_latest_run_timestamp_seconds to github_workflow_latest_run_start_time_seconds - simpliied labels on secondary metrics (only org, repo and workflowID) Signed-off-by: Markus Blaschke <[email protected]>
1 parent d064d36 commit 69ba047

File tree

3 files changed

+136
-34
lines changed

3 files changed

+136
-34
lines changed

go.mod

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ require (
88
github.com/dustin/go-humanize v1.0.1
99
github.com/google/go-github/v61 v61.0.0
1010
github.com/jessevdk/go-flags v1.6.1
11-
github.com/prometheus/client_golang v1.20.3
11+
github.com/prometheus/client_golang v1.20.4
1212
github.com/webdevops/go-common v0.0.0-20240914143308-98dd8416e15d
1313
go.uber.org/zap v1.27.0
1414
go.uber.org/zap/exp v0.2.0
15+
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0
1516
)
1617

1718
require (
@@ -21,7 +22,7 @@ require (
2122
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph v0.9.0 // indirect
2223
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 // indirect
2324
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0 // indirect
24-
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.4.0 // indirect
25+
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.4.1 // indirect
2526
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
2627
github.com/beorn7/perks v1.0.1 // indirect
2728
github.com/cespare/xxhash/v2 v2.3.0 // indirect
@@ -68,7 +69,6 @@ require (
6869
github.com/x448/float16 v0.8.4 // indirect
6970
go.uber.org/multierr v1.11.0 // indirect
7071
golang.org/x/crypto v0.27.0 // indirect
71-
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
7272
golang.org/x/net v0.29.0 // indirect
7373
golang.org/x/oauth2 v0.23.0 // indirect
7474
golang.org/x/sys v0.25.0 // indirect

go.sum

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions
1616
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0/go.mod h1:TpiwjwnW/khS0LKs4vW5UmmT9OWcxaveS8U7+tlknzo=
1717
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.6.0 h1:PiSrjRPpkQNjrM8H0WwKMnZUdu1RGMtd/LdGKUrOo+c=
1818
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.6.0/go.mod h1:oDrbWx4ewMylP7xHivfgixbfGBT6APAwsSoHRKotnIc=
19-
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.4.0 h1:Be6KInmFEKV81c0pOAEbRYehLMwmmGI1exuFj248AMk=
20-
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.4.0/go.mod h1:WCPBHsOXfBVnivScjs2ypRfimjEW0qPVLGgJkZlrIOA=
19+
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.4.1 h1:cf+OIKbkmMHBaC3u78AXomweqM0oxQSgBXRZf3WH4yM=
20+
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.4.1/go.mod h1:ap1dmS6vQKJxSMNiGJcq4QuUQkOynyD93gLw6MDF7ek=
2121
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU=
2222
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
2323
github.com/KimMachineGun/automemlimit v0.6.1 h1:ILa9j1onAAMadBsyyUJv5cack8Y1WT26yLj/V+ulKp8=
@@ -136,8 +136,8 @@ github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjL
136136
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
137137
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
138138
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
139-
github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4=
140-
github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
139+
github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI=
140+
github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
141141
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
142142
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
143143
github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0=

metrics_github_workflows.go

+129-27
Original file line numberDiff line numberDiff line change
@@ -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

1415
const (
1516
CUSTOMPROP_LABEL_FMT = "prop_%s"
1617
)
1718

19+
var (
20+
githubWorkflowRunningStatus = []string{"in_progress", "action_required", "queued", "waiting", "pending"}
21+
)
22+
1823
type (
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+
337440
func (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

Comments
 (0)