Skip to content

Commit 02cb8bc

Browse files
authored
Add a branch label to workflow metrics (#164)
Signed-off-by: Rauf Guliyev <[email protected]>
1 parent b0d602a commit 02cb8bc

File tree

4 files changed

+82
-46
lines changed

4 files changed

+82
-46
lines changed

internal/server/metrics.go

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,36 @@ var (
88
Help: "Time that a workflow job took to reach a given state.",
99
Buckets: prometheus.ExponentialBuckets(1, 1.4, 30),
1010
},
11-
[]string{"org", "repo", "state", "runner_group", "workflow_name", "job_name"},
11+
[]string{"org", "repo", "branch", "state", "runner_group", "workflow_name", "job_name"},
1212
)
1313

1414
workflowJobDurationCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
1515
Name: "workflow_job_duration_seconds_total",
1616
Help: "The total duration of jobs.",
1717
},
18-
[]string{"org", "repo", "status", "conclusion", "runner_group", "workflow_name", "job_name"},
18+
[]string{"org", "repo", "branch", "status", "conclusion", "runner_group", "workflow_name", "job_name"},
1919
)
2020

2121
workflowJobStatusCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
2222
Name: "workflow_job_status_count",
2323
Help: "Count of workflow job events.",
2424
},
25-
[]string{"org", "repo", "status", "conclusion", "runner_group", "workflow_name", "job_name"},
25+
[]string{"org", "repo", "branch", "status", "conclusion", "runner_group", "workflow_name", "job_name"},
2626
)
2727

2828
workflowRunHistogramVec = prometheus.NewHistogramVec(prometheus.HistogramOpts{
2929
Name: "workflow_execution_time_seconds",
3030
Help: "Time that a workflow took to run.",
3131
Buckets: prometheus.ExponentialBuckets(1, 1.4, 30),
3232
},
33-
[]string{"org", "repo", "workflow_name", "conclusion"},
33+
[]string{"org", "repo", "branch", "workflow_name", "conclusion"},
3434
)
3535

3636
workflowRunStatusCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
3737
Name: "workflow_status_count",
3838
Help: "Count of the occurrences of different workflow states.",
3939
},
40-
[]string{"org", "repo", "status", "conclusion", "workflow_name"},
40+
[]string{"org", "repo", "branch", "status", "conclusion", "workflow_name"},
4141
)
4242

4343
totalMinutesUsedActions = prometheus.NewGaugeVec(prometheus.GaugeOpts{
@@ -83,36 +83,36 @@ func init() {
8383
}
8484

8585
type WorkflowObserver interface {
86-
ObserveWorkflowJobDuration(org, repo, state, runnerGroup, workflowName, jobName string, seconds float64)
87-
CountWorkflowJobStatus(org, repo, status, conclusion, runnerGroup, workflowName, jobName string)
88-
CountWorkflowJobDuration(org, repo, status, conclusion, runnerGroup, workflowName, jobName string, seconds float64)
86+
ObserveWorkflowJobDuration(org, repo, branch, state, runnerGroup, workflowName, jobName string, seconds float64)
87+
CountWorkflowJobStatus(org, repo, branch, status, conclusion, runnerGroup, workflowName, jobName string)
88+
CountWorkflowJobDuration(org, repo, branch, status, conclusion, runnerGroup, workflowName, jobName string, seconds float64)
8989

90-
ObserveWorkflowRunDuration(org, repo, workflow, conclusion string, seconds float64)
91-
CountWorkflowRunStatus(org, repo, status, conclusion, workflow string)
90+
ObserveWorkflowRunDuration(org, repo, branch, workflow, conclusion string, seconds float64)
91+
CountWorkflowRunStatus(org, repo, branch, status, conclusion, workflow string)
9292
}
9393

9494
var _ WorkflowObserver = (*PrometheusObserver)(nil)
9595

9696
type PrometheusObserver struct{}
9797

98-
func (o *PrometheusObserver) ObserveWorkflowJobDuration(org, repo, state, runnerGroup, workflowName, jobName string, seconds float64) {
99-
workflowJobHistogramVec.WithLabelValues(org, repo, state, runnerGroup, workflowName, jobName).
98+
func (o *PrometheusObserver) ObserveWorkflowJobDuration(org, repo, branch, state, runnerGroup, workflowName, jobName string, seconds float64) {
99+
workflowJobHistogramVec.WithLabelValues(org, repo, branch, state, runnerGroup, workflowName, jobName).
100100
Observe(seconds)
101101
}
102102

103-
func (o *PrometheusObserver) CountWorkflowJobStatus(org, repo, status, conclusion, runnerGroup, workflowName, jobName string) {
104-
workflowJobStatusCounter.WithLabelValues(org, repo, status, conclusion, runnerGroup, workflowName, jobName).Inc()
103+
func (o *PrometheusObserver) CountWorkflowJobStatus(org, repo, branch, status, conclusion, runnerGroup, workflowName, jobName string) {
104+
workflowJobStatusCounter.WithLabelValues(org, repo, branch, status, conclusion, runnerGroup, workflowName, jobName).Inc()
105105
}
106106

107-
func (o *PrometheusObserver) CountWorkflowJobDuration(org, repo, status, conclusion, runnerGroup, workflowName, jobName string, seconds float64) {
108-
workflowJobDurationCounter.WithLabelValues(org, repo, status, conclusion, runnerGroup, workflowName, jobName).Add(seconds)
107+
func (o *PrometheusObserver) CountWorkflowJobDuration(org, repo, branch, status, conclusion, runnerGroup, workflowName, jobName string, seconds float64) {
108+
workflowJobDurationCounter.WithLabelValues(org, repo, branch, status, conclusion, runnerGroup, workflowName, jobName).Add(seconds)
109109
}
110110

111-
func (o *PrometheusObserver) ObserveWorkflowRunDuration(org, repo, workflowName, conclusion string, seconds float64) {
112-
workflowRunHistogramVec.WithLabelValues(org, repo, workflowName, conclusion).
111+
func (o *PrometheusObserver) ObserveWorkflowRunDuration(org, repo, branch, workflowName, conclusion string, seconds float64) {
112+
workflowRunHistogramVec.WithLabelValues(org, repo, branch, workflowName, conclusion).
113113
Observe(seconds)
114114
}
115115

116-
func (o *PrometheusObserver) CountWorkflowRunStatus(org, repo, status, conclusion, workflowName string) {
117-
workflowRunStatusCounter.WithLabelValues(org, repo, status, conclusion, workflowName).Inc()
116+
func (o *PrometheusObserver) CountWorkflowRunStatus(org, repo, branch, status, conclusion, workflowName string) {
117+
workflowRunStatusCounter.WithLabelValues(org, repo, branch, status, conclusion, workflowName).Inc()
118118
}

internal/server/server_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ func Test_Server_MetricsRouteAfterWorkflowJob(t *testing.T) {
8787
}()
8888

8989
repo := "some-repo"
90+
branch := "some-branch"
9091
org := "someone"
9192
expectedDuration := 10.0
9293
jobStartedAt := time.Unix(1650308740, 0)
@@ -104,6 +105,7 @@ func Test_Server_MetricsRouteAfterWorkflowJob(t *testing.T) {
104105
},
105106
},
106107
WorkflowJob: &github.WorkflowJob{
108+
HeadBranch: &branch,
107109
Status: github.String("completed"),
108110
Conclusion: github.String("success"),
109111
StartedAt: &github.Timestamp{Time: jobStartedAt},
@@ -129,6 +131,6 @@ func Test_Server_MetricsRouteAfterWorkflowJob(t *testing.T) {
129131

130132
payload, err := io.ReadAll(metricsRes.Body)
131133
require.NoError(t, err)
132-
assert.Contains(t, string(payload), `workflow_job_duration_seconds_bucket{job_name="Test",org="someone",repo="some-repo",runner_group="runner-group",state="in_progress",workflow_name="Build and test",le="10.541350399999995"} 1`)
133-
assert.Contains(t, string(payload), `workflow_job_duration_seconds_total{conclusion="success",job_name="Test",org="someone",repo="some-repo",runner_group="runner-group",status="completed",workflow_name="Build and test"} 10`)
134+
assert.Contains(t, string(payload), `workflow_job_duration_seconds_bucket{branch="some-branch",job_name="Test",org="someone",repo="some-repo",runner_group="runner-group",state="in_progress",workflow_name="Build and test",le="10.541350399999995"} 1`)
135+
assert.Contains(t, string(payload), `workflow_job_duration_seconds_total{branch="some-branch",conclusion="success",job_name="Test",org="someone",repo="some-repo",runner_group="runner-group",status="completed",workflow_name="Build and test"} 10`)
134136
}

internal/server/workflow_metrics_exporter.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,15 @@ func (c *WorkflowMetricsExporter) HandleGHWebHook(w http.ResponseWriter, r *http
7777
_ = level.Info(c.Logger).Log("msg", "got workflow_job event",
7878
"org", event.GetRepo().GetOwner().GetLogin(),
7979
"repo", event.GetRepo().GetName(),
80+
"branch", event.GetWorkflowJob().GetHeadBranch(),
8081
"runId", event.GetWorkflowJob().GetRunID(),
8182
"action", event.GetAction(),
8283
"workflow_name", event.GetWorkflowJob().GetWorkflowName(),
8384
"job_name", event.GetWorkflowJob().GetName())
8485
go c.CollectWorkflowJobEvent(event)
8586
case "workflow_run":
8687
event := model.WorkflowRunEventFromJSON(io.NopCloser(bytes.NewBuffer(buf)))
87-
_ = level.Info(c.Logger).Log("msg", "got workflow_run event", "org", event.GetRepo().GetOwner().GetLogin(), "repo", event.GetRepo().GetName(), "workflow_name", event.GetWorkflow().GetName(), "runNumber", event.GetWorkflowRun().GetRunNumber(), "action", event.GetAction())
88+
_ = level.Info(c.Logger).Log("msg", "got workflow_run event", "org", event.GetRepo().GetOwner().GetLogin(), "repo", event.GetRepo().GetName(), "branch", event.GetWorkflowRun().GetHeadBranch(), "workflow_name", event.GetWorkflow().GetName(), "runNumber", event.GetWorkflowRun().GetRunNumber(), "action", event.GetAction())
8889
go c.CollectWorkflowRunEvent(event)
8990
default:
9091
_ = level.Info(c.Logger).Log("msg", "not implemented", "eventType", eventType)
@@ -99,6 +100,7 @@ func (c *WorkflowMetricsExporter) HandleGHWebHook(w http.ResponseWriter, r *http
99100
func (c *WorkflowMetricsExporter) CollectWorkflowJobEvent(event *github.WorkflowJobEvent) {
100101
repo := event.GetRepo().GetName()
101102
org := event.GetRepo().GetOwner().GetLogin()
103+
branch := event.WorkflowJob.GetHeadBranch()
102104
action := event.GetAction()
103105

104106
workflowJob := event.GetWorkflowJob()
@@ -120,34 +122,35 @@ func (c *WorkflowMetricsExporter) CollectWorkflowJobEvent(event *github.Workflow
120122

121123
firstStep := workflowJob.Steps[0]
122124
queuedSeconds := firstStep.StartedAt.Time.Sub(workflowJob.GetStartedAt().Time).Seconds()
123-
c.PrometheusObserver.ObserveWorkflowJobDuration(org, repo, "queued", runnerGroup, workflowName, jobName, math.Max(0, queuedSeconds))
125+
c.PrometheusObserver.ObserveWorkflowJobDuration(org, repo, branch, "queued", runnerGroup, workflowName, jobName, math.Max(0, queuedSeconds))
124126
case "completed":
125127
if workflowJob.StartedAt == nil || workflowJob.CompletedAt == nil {
126128
_ = level.Debug(c.Logger).Log("msg", "unable to calculate job duration of completed event steps are missing timestamps")
127129
break
128130
}
129131

130132
jobSeconds := math.Max(0, workflowJob.GetCompletedAt().Time.Sub(workflowJob.GetStartedAt().Time).Seconds())
131-
c.PrometheusObserver.ObserveWorkflowJobDuration(org, repo, "in_progress", runnerGroup, workflowName, jobName, jobSeconds)
132-
c.PrometheusObserver.CountWorkflowJobDuration(org, repo, status, conclusion, runnerGroup, workflowName, jobName, jobSeconds)
133+
c.PrometheusObserver.ObserveWorkflowJobDuration(org, repo, branch, "in_progress", runnerGroup, workflowName, jobName, jobSeconds)
134+
c.PrometheusObserver.CountWorkflowJobDuration(org, repo, branch, status, conclusion, runnerGroup, workflowName, jobName, jobSeconds)
133135
}
134136

135-
c.PrometheusObserver.CountWorkflowJobStatus(org, repo, status, conclusion, runnerGroup, workflowName, jobName)
137+
c.PrometheusObserver.CountWorkflowJobStatus(org, repo, branch, status, conclusion, runnerGroup, workflowName, jobName)
136138
}
137139

138140
func (c *WorkflowMetricsExporter) CollectWorkflowRunEvent(event *github.WorkflowRunEvent) {
139141
repo := event.GetRepo().GetName()
140142
org := event.GetRepo().GetOwner().GetLogin()
143+
branch := event.GetWorkflowRun().GetHeadBranch()
141144
workflowName := event.GetWorkflow().GetName()
142145
conclusion := event.GetWorkflowRun().GetConclusion()
143146

144147
if event.GetAction() == "completed" {
145148
seconds := event.GetWorkflowRun().UpdatedAt.Time.Sub(event.GetWorkflowRun().RunStartedAt.Time).Seconds()
146-
c.PrometheusObserver.ObserveWorkflowRunDuration(org, repo, workflowName, conclusion, seconds)
149+
c.PrometheusObserver.ObserveWorkflowRunDuration(org, repo, branch, workflowName, conclusion, seconds)
147150
}
148151

149152
status := event.GetWorkflowRun().GetStatus()
150-
c.PrometheusObserver.CountWorkflowRunStatus(org, repo, status, conclusion, workflowName)
153+
c.PrometheusObserver.CountWorkflowRunStatus(org, repo, branch, status, conclusion, workflowName)
151154
}
152155

153156
// validateSignature validate the incoming github event.

0 commit comments

Comments
 (0)