1 package metrics
2
3 import (
4 "os"
5 "strconv"
6 "sync"
7
8 "github.com/google/go-github/v47/github"
9 "github.com/prometheus/client_golang/prometheus"
10 "github.com/prometheus/client_golang/prometheus/promauto"
11
12 githubclient "edge-infra.dev/pkg/f8n/devinfra/github-client"
13 )
14
15 const (
16 workflowRunStatus = "github_workflow_run_status"
17 workflowDuration = "github_workflow_run_duration_ms"
18 workflowUsage = "github_workflow_usage_seconds"
19 runnerStatus = "github_runner_status"
20 runnerOrganization = "github_runner_organization_status"
21 )
22
23 var (
24 org string
25 repo string
26 client *github.Client
27 )
28
29 var Metrics = struct {
30 sync.Mutex
31
32 runnersGauge *prometheus.GaugeVec
33 runnersOrganizationGauge *prometheus.GaugeVec
34 workflowRunStatusGauge *prometheus.GaugeVec
35 workflowRunDurationGauge *prometheus.GaugeVec
36 workflowBillGauge *prometheus.GaugeVec
37 }{
38
39 runnersGauge: promauto.NewGaugeVec(prometheus.GaugeOpts{
40 Name: runnerStatus,
41 Help: "runner status",
42 },
43 []string{"repo", "os", "name", "id", "busy"},
44 ),
45 runnersOrganizationGauge: promauto.NewGaugeVec(prometheus.GaugeOpts{
46 Name: runnerOrganization,
47 Help: "runner status",
48 },
49 []string{"repo", "id", "node_id", "name", "state", "os"},
50 ),
51 workflowRunStatusGauge: promauto.NewGaugeVec(prometheus.GaugeOpts{
52 Name: workflowRunStatus,
53 Help: "Workflow run status",
54 },
55 []string{"repo", "id", "node_id", "head_branch", "head_sha", "run_number", "workflow_id", "workflow_event", "status"},
56 ),
57 workflowRunDurationGauge: promauto.NewGaugeVec(prometheus.GaugeOpts{
58 Name: workflowDuration,
59 Help: "Workflow run duration (in milliseconds)",
60 },
61 []string{"repo", "id", "node_id", "head_branch", "head_sha", "run_number", "workflow_id", "workflow_event", "status"},
62 ),
63 workflowBillGauge: promauto.NewGaugeVec(prometheus.GaugeOpts{
64 Name: workflowUsage,
65 Help: "Number of billable seconds used by a specific workflow during the current billing cycle. Any job re-runs are also included in the usage. Only apply to workflows in private repositories that use GitHub-hosted runners.",
66 },
67 []string{"repo", "id", "node_id", "name", "state", "os"},
68 ),
69 }
70
71
72 func InitMetrics() error {
73 appRepo := os.Getenv("REPO_URL")
74 privateKey := []byte(os.Getenv("GITHUB_APP_PRIVATE_KEY"))
75
76 appID, err := strconv.ParseInt(os.Getenv("APP_ID"), 10, 64)
77 if err != nil {
78 return err
79 }
80 cfg := githubclient.Config{
81 Repository: appRepo,
82 PrivateKey: privateKey,
83 AppID: appID,
84 }
85
86 repo = cfg.Repo()
87 org = cfg.Owner()
88
89 ac, err := githubclient.NewClient(cfg)
90 if err != nil {
91 return err
92 }
93 client = ac.Client
94 go workflowCache()
95 Metrics.Lock()
96 defer Metrics.Unlock()
97 go getBillableFromGithub(Metrics.workflowBillGauge)
98 go getRunnersFromGithub(Metrics.runnersGauge)
99 go getRunnersOrganizationFromGithub(Metrics.runnersOrganizationGauge)
100 go getWorkflowRunsFromGithub(Metrics.workflowRunStatusGauge)
101 go getDurationGithub(Metrics.workflowRunDurationGauge)
102
103 return nil
104 }
105
View as plain text