| 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 |