/
main.go
122 lines (101 loc) · 3.22 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package main
import (
"context"
"log"
"net/http"
"strings"
"time"
"github.com/bradleyfalzon/ghinstallation"
"github.com/google/go-github/github"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)
const (
FlagGitHubAppID = "github-app-id"
FlagGitHubInstallationID = "github-installation-id"
FlagGitHubPrivateKey = "github-private-key"
FlagRefreshInterval = "refresh-interval"
FlagVerbose = "verbose"
)
var (
coreLimit = promauto.NewGauge(prometheus.GaugeOpts{
Name: "github_resources_core_limit",
Help: "The upper limit of requests per hour",
})
coreUsed = promauto.NewGauge(prometheus.GaugeOpts{
Name: "github_resources_core_used",
Help: "The used requests per hour",
})
coreRemaining = promauto.NewGauge(prometheus.GaugeOpts{
Name: "github_resources_core_remaining",
Help: "The remaining requests per hour",
})
coreReset = promauto.NewGauge(prometheus.GaugeOpts{
Name: "github_resources_core_reset",
Help: "Number of seconds until the rate limit resets",
})
)
func updateMetrics(ctx context.Context, client *github.Client, verbose bool) {
if verbose {
log.Println("Refreshing metrics")
}
rateLimits, resp, err := client.RateLimits(ctx)
if err != nil {
log.Printf("Error getting rate limits: %v", err)
return
}
defer resp.Body.Close()
coreLimit.Set(float64(rateLimits.Core.Limit))
coreUsed.Set(float64(rateLimits.Core.Limit - rateLimits.Core.Remaining))
coreRemaining.Set(float64(rateLimits.Core.Remaining))
coreReset.Set(time.Until(rateLimits.Core.Reset.Time).Seconds())
}
func main() {
pflag.Int64(FlagGitHubAppID, -1, "GitHub App ID")
pflag.Int64(FlagGitHubInstallationID, -1, "GitHub App Installation ID")
pflag.String(FlagGitHubPrivateKey, "", "GitHub App private key")
pflag.Duration(FlagRefreshInterval, 5*time.Second, "How often to refresh the metrics")
pflag.BoolP(FlagVerbose, "v", false, "Enable verbose logging")
pflag.Parse()
viper.BindPFlags(pflag.CommandLine)
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
viper.AutomaticEnv()
githubAppID := viper.GetInt64(FlagGitHubAppID)
githubInstallationID := viper.GetInt64(FlagGitHubInstallationID)
githubPrivateKey := viper.GetString(FlagGitHubPrivateKey)
refreshInterval := viper.GetDuration(FlagRefreshInterval)
verbose := viper.GetBool(FlagVerbose)
if githubAppID == -1 {
log.Fatalf("GitHub App ID is required")
}
if githubInstallationID == -1 {
log.Fatalf("GitHub App Installation ID is required")
}
if githubPrivateKey == "" {
log.Fatalf("GitHub App private key is required")
}
tr := http.DefaultTransport
installationTransport, err := ghinstallation.New(
tr,
githubAppID,
githubInstallationID,
[]byte(githubPrivateKey),
)
if err != nil {
log.Fatal(err)
}
go func() {
ctx := context.Background()
ticker := time.NewTicker(refreshInterval)
client := github.NewClient(&http.Client{Transport: installationTransport})
updateMetrics(ctx, client, verbose)
for range ticker.C {
updateMetrics(ctx, client, verbose)
}
}()
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":8000", nil)
}