bosun.org@v0.0.0-20210513094433-e25bc3e69a1f/cmd/scollector/collectors/github.go (about) 1 package collectors 2 3 import ( 4 "fmt" 5 "net/http" 6 "strings" 7 "time" 8 9 "bosun.org/cmd/scollector/conf" 10 "bosun.org/metadata" 11 "bosun.org/opentsdb" 12 "bosun.org/slog" 13 "github.com/google/go-github/github" 14 ) 15 16 func init() { 17 registerInit(startGithubCollectors) 18 } 19 20 type githubRoundTripper struct { 21 accessToken string 22 } 23 24 func (rt githubRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { 25 r.Header.Set("Authorization", fmt.Sprintf("token %s", rt.accessToken)) 26 return http.DefaultTransport.RoundTrip(r) 27 } 28 29 func startGithubCollectors(c *conf.Conf) { 30 for _, gh := range c.Github { 31 client := github.NewClient(&http.Client{Transport: githubRoundTripper{gh.Token}}) 32 split := strings.Split(gh.Repo, "/") 33 if len(split) != 2 { 34 slog.Fatal("Repo must have two parts (owner/repo)") 35 } 36 owner, repo := split[0], split[1] 37 collectors = append(collectors, &IntervalCollector{ 38 F: func() (opentsdb.MultiDataPoint, error) { 39 return githubCollect(client, owner, repo) 40 }, 41 name: fmt.Sprintf("github-%s", gh.Repo), 42 Interval: 10 * time.Minute, //10 minutes to respect api limits 43 }) 44 } 45 } 46 47 const ( 48 descGithubOpenIssues = "Number of currently open issues" 49 descGithubOpenPrs = "Number of currently open pull requests" 50 ) 51 52 func githubCollect(client *github.Client, owner, repo string) (o opentsdb.MultiDataPoint, e error) { 53 var md opentsdb.MultiDataPoint 54 opts := &github.IssueListByRepoOptions{ 55 ListOptions: github.ListOptions{ 56 PerPage: 100, 57 Page: 1, 58 }, 59 } 60 openIssueCount := 0 61 openPrCount := 0 62 issueLabelCounts := make(map[string]int) 63 prLabelCounts := make(map[string]int) 64 for { 65 issues, resp, err := client.Issues.ListByRepo(owner, repo, opts) 66 if err != nil { 67 return md, err 68 } 69 for _, i := range issues { 70 if i.PullRequestLinks != nil { 71 openPrCount++ 72 for _, label := range i.Labels { 73 prLabelCounts[*label.Name] = prLabelCounts[*label.Name] + 1 74 } 75 } else { 76 openIssueCount++ 77 for _, label := range i.Labels { 78 issueLabelCounts[*label.Name] = issueLabelCounts[*label.Name] + 1 79 } 80 } 81 } 82 if resp.NextPage == 0 { 83 break 84 } 85 opts.Page = resp.NextPage 86 } 87 Add(&md, "github.open_issues", openIssueCount, opentsdb.TagSet{"repo": repo}, metadata.Gauge, metadata.Count, descGithubOpenIssues) 88 for name, count := range issueLabelCounts { 89 Add(&md, "github.open_issues_label", count, opentsdb.TagSet{"repo": repo, "label": name}, metadata.Gauge, metadata.Count, descGithubOpenIssues) 90 } 91 Add(&md, "github.open_prs", openPrCount, opentsdb.TagSet{"repo": repo}, metadata.Gauge, metadata.Count, descGithubOpenPrs) 92 for name, count := range prLabelCounts { 93 Add(&md, "github.open_prs_label", count, opentsdb.TagSet{"repo": repo, "label": name}, metadata.Gauge, metadata.Count, descGithubOpenPrs) 94 } 95 return md, nil 96 }