Go · 1782 bytes Raw Blame History
1 // SPDX-License-Identifier: AGPL-3.0-or-later
2
3 // Package telemetry records bounded-cardinality Actions metrics.
4 package telemetry
5
6 import (
7 "strings"
8
9 actionsdb "github.com/tenseleyFlow/shithub/internal/actions/sqlc"
10 "github.com/tenseleyFlow/shithub/internal/infra/metrics"
11 )
12
13 // RecordRunTerminal records terminal workflow-run counters and duration. It is
14 // idempotency-sensitive: callers must invoke it only when a run first becomes
15 // terminal.
16 func RecordRunTerminal(run actionsdb.WorkflowRun) {
17 if !run.CompletedAt.Valid || !run.Conclusion.Valid {
18 return
19 }
20 start := run.CreatedAt.Time
21 if run.StartedAt.Valid {
22 start = run.StartedAt.Time
23 }
24 duration := run.CompletedAt.Time.Sub(start).Seconds()
25 if duration < 0 {
26 duration = 0
27 }
28 event := string(run.Event)
29 conclusion := string(run.Conclusion.CheckConclusion)
30 metrics.ActionsRunsCompletedTotal.WithLabelValues(event, conclusion).Inc()
31 metrics.ActionsRunDurationSeconds.WithLabelValues(event, conclusion).Observe(duration)
32 }
33
34 // RecordStepTerminal records terminal step outcomes using a bounded step_type
35 // label. Do not label by user-authored step name; workflow YAML would then be
36 // able to create unbounded Prometheus series.
37 func RecordStepTerminal(step actionsdb.WorkflowStep) {
38 if !step.Conclusion.Valid {
39 return
40 }
41 metrics.ActionsStepsCompletedTotal.WithLabelValues(stepType(step), string(step.Conclusion.CheckConclusion)).Inc()
42 }
43
44 func stepType(step actionsdb.WorkflowStep) string {
45 uses := strings.TrimSpace(step.UsesAlias)
46 if uses != "" {
47 switch uses {
48 case "actions/checkout@v4":
49 return "checkout"
50 case "shithub/upload-artifact@v1":
51 return "upload-artifact"
52 case "shithub/download-artifact@v1":
53 return "download-artifact"
54 default:
55 return "uses"
56 }
57 }
58 return "run"
59 }
60