// Package metrics provides monitoring of the GitHub related metrics. // // This depends on the metrics exporter of kubebuilder. // See https://book.kubebuilder.io/reference/metrics.html for details. package metrics import ( "net/http" "strconv" "sync" "github.com/prometheus/client_golang/prometheus" "sigs.k8s.io/controller-runtime/pkg/metrics" ) var onceRegister sync.Once func Register() { onceRegister.Do(func() { metrics.Registry.MustRegister(metricRateLimit, metricRateLimitRemaining) }) } var ( // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting metricRateLimit = prometheus.NewGauge( prometheus.GaugeOpts{ Name: "github_rate_limit", Help: "The maximum number of requests you're permitted to make per hour", }, ) metricRateLimitRemaining = prometheus.NewGauge( prometheus.GaugeOpts{ Name: "github_rate_limit_remaining", Help: "The number of requests remaining in the current rate limit window", }, ) ) const ( // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting headerRateLimit = "X-RateLimit-Limit" headerRateLimitRemaining = "X-RateLimit-Remaining" ) // Transport wraps a transport with metrics monitoring type Transport struct { Transport http.RoundTripper } func (t Transport) RoundTrip(req *http.Request) (*http.Response, error) { resp, err := t.Transport.RoundTrip(req) if resp != nil { parseResponse(resp) } return resp, err } func parseResponse(resp *http.Response) { rateLimit, err := strconv.Atoi(resp.Header.Get(headerRateLimit)) if err == nil { metricRateLimit.Set(float64(rateLimit)) } rateLimitRemaining, err := strconv.Atoi(resp.Header.Get(headerRateLimitRemaining)) if err == nil { metricRateLimitRemaining.Set(float64(rateLimitRemaining)) } }