-
Notifications
You must be signed in to change notification settings - Fork 129
V2 Rewrite.. #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
V2 Rewrite.. #15
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
e1b170d
V2 Rewrite, initial commit
Rucknar a33660b
Added private repo label dimension
Rucknar 17c64ec
Updates following testing
Rucknar 29abf2c
Cleaning up app
iamtgray d8edb42
Removed panic
Rucknar 2543f62
Fix error in Dockerfile
Rucknar 4274322
Port correction
Rucknar 4d7f525
Updated code comments
Rucknar be8037c
Added 404 detection
Rucknar 181dad4
Renamed file to make it clearer
Rucknar 26e9b4d
Various updates following testing, async request support added
Rucknar fc3a827
Fixed bug with single repositories
Rucknar cb4145e
Tidied up config
Rucknar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,24 @@ | ||
| FROM python:3.5-alpine | ||
| FROM golang:1.8.0-alpine | ||
| LABEL maintainer "Infinity Works" | ||
|
|
||
| RUN pip install prometheus_client requests | ||
| EXPOSE 9171 | ||
|
|
||
| ENV BIND_PORT 9171 | ||
| ENV GOPATH=/go | ||
| ENV LISTEN_PORT=9171 | ||
|
|
||
| ADD . /usr/src/app | ||
| WORKDIR /usr/src/app | ||
| RUN addgroup exporter \ | ||
| && adduser -S -G exporter exporter \ | ||
| && apk --update add ca-certificates \ | ||
| && apk --update add --virtual build-deps git | ||
|
|
||
| CMD ["python", "github_exporter.py"] | ||
| COPY ./ /go/src/github.com/infinityworksltd/github-exporter | ||
|
|
||
| WORKDIR /go/src/github.com/infinityworksltd/github-exporter | ||
|
|
||
| RUN go get \ | ||
| && go test ./... \ | ||
| && go build -o /bin/main | ||
|
|
||
| USER exporter | ||
|
|
||
| CMD [ "/bin/main" ] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # Metrics | ||
|
|
||
| Below are an example of the metrics as exposed by this exporter. | ||
|
|
||
| ``` | ||
| # HELP github_repo_open_issues open_issues | ||
| # TYPE github_repo_open_issues gauge | ||
| github_repo_open_issues{repo="docker-hub-exporter",user="infinityworksltd"} 1.0 | ||
| github_repo_open_issues{repo="prometheus-rancher-exporter",user="infinityworksltd"} 2.0 | ||
| # HELP github_repo_watchers watchers | ||
| # TYPE github_repo_watchers gauge | ||
| github_repo_watchers{repo="docker-hub-exporter",user="infinityworksltd"} 1.0 | ||
| github_repo_watchers{repo="prometheus-rancher-exporter",user="infinityworksltd"} 6.0 | ||
| # HELP github_repo_stars stars | ||
| # TYPE github_repo_stars gauge | ||
| github_repo_stars{repo="docker-hub-exporter",user="infinityworksltd"} 1.0 | ||
| github_repo_stars{repo="prometheus-rancher-exporter",user="infinityworksltd"} 6.0 | ||
| # HELP github_repo_forks forks | ||
| # TYPE github_repo_forks gauge | ||
| github_repo_forks{repo="docker-hub-exporter",user="infinityworksltd"} 0.0 | ||
| github_repo_forks{repo="prometheus-rancher-exporter",user="infinityworksltd"} 9.0 | ||
| # HELP github_repo_size_kb Size in KB for given repository | ||
| # TYPE github_repo_size_kb gauge | ||
| github_repo_size_kb{repo="docker-hub-exporter",user="infinityworksltd"} 44 | ||
| github_repo_size_kb{repo="prometheus-rancher-exporter",user="infinityworksltd"} 7242 | ||
| # HELP github_rate_limit Number of API queries allowed in a 60 minute window | ||
| # TYPE github_rate_limit gauge | ||
| github_rate_limit 60 | ||
| # HELP github_rate_remaining Number of API queries remaining in the current window | ||
| # TYPE github_rate_remaining gauge | ||
| github_rate_remaining 38 | ||
| # HELP github_rate_reset The time at which the current rate limit window resets in UTC epoch seconds | ||
| # TYPE github_rate_reset gauge | ||
| github_rate_reset 1.493139756e+09 | ||
| # HELP github_size_kb Size in KB for given repository | ||
| # TYPE github_size_kb gauge | ||
| github_size_kb{repo="CRUST",user="infinityworksltd"} 44 | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| package config | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "io/ioutil" | ||
| "strings" | ||
|
|
||
| log "github.com/Sirupsen/logrus" | ||
|
|
||
| "os" | ||
|
|
||
| cfg "github.com/infinityworksltd/go-common/config" | ||
| ) | ||
|
|
||
| // Config struct holds all of the runtime confgiguration for the application | ||
| type Config struct { | ||
| *cfg.BaseConfig | ||
| APIURL string | ||
| Repositories string | ||
| Organisations string | ||
| APITokenEnv string | ||
| APITokenFile string | ||
| APIToken string | ||
| TargetURLs []string | ||
| } | ||
|
|
||
| // Init populates the Config struct based on environmental runtime configuration | ||
| func Init() Config { | ||
|
|
||
| ac := cfg.Init() | ||
| url := cfg.GetEnv("API_URL", "https://api.github.com") | ||
| repos := os.Getenv("REPOS") | ||
| orgs := os.Getenv("ORGS") | ||
| tokenEnv := os.Getenv("GITHUB_TOKEN") | ||
| tokenFile := os.Getenv("GITHUB_TOKEN_FILE") | ||
| token, err := getAuth(tokenEnv, tokenFile) | ||
| scraped, err := getScrapeURLs(url, repos, orgs) | ||
|
|
||
| if err != nil { | ||
| log.Errorf("Error initialising Configuration, Error: %v", err) | ||
| } | ||
|
|
||
| appConfig := Config{ | ||
| &ac, | ||
| url, | ||
| repos, | ||
| orgs, | ||
| tokenEnv, | ||
| tokenFile, | ||
| token, | ||
| scraped, | ||
| } | ||
|
|
||
| return appConfig | ||
| } | ||
|
|
||
| // Init populates the Config struct based on environmental runtime configuration | ||
| // All URL's are added to the TargetURL's string array | ||
| func getScrapeURLs(apiURL string, repos string, orgs string) ([]string, error) { | ||
|
|
||
| urls := []string{} | ||
|
|
||
| opts := "?&per_page=100" // Used to set the Github API to return 100 results per page (max) | ||
|
|
||
| // User input validation, check that either repositories or organisations have been passed in | ||
| if len(repos) == 0 && len(orgs) == 0 { | ||
| return urls, fmt.Errorf("No organisations or repositories specified") | ||
| } | ||
|
|
||
| // Append repositories to the array | ||
| if repos != "" { | ||
| rs := strings.Split(repos, ", ") | ||
| for _, x := range rs { | ||
| y := fmt.Sprintf("%s/repos/%s%s", apiURL, x, opts) | ||
| urls = append(urls, y) | ||
| } | ||
| } | ||
|
|
||
| // Append github orginisations to the array | ||
| if orgs != "" { | ||
| o := strings.Split(orgs, ", ") | ||
| for _, x := range o { | ||
| y := fmt.Sprintf("%s/orgs/%s/repos%s", apiURL, x, opts) | ||
| urls = append(urls, y) | ||
| } | ||
| } | ||
|
|
||
| return urls, nil | ||
| } | ||
|
|
||
| // getAuth returns oauth2 token as string for usage in http.request | ||
| func getAuth(token string, tokenFile string) (string, error) { | ||
|
|
||
| if token != "" { | ||
| return token, nil | ||
| } else if tokenFile != "" { | ||
| b, err := ioutil.ReadFile(tokenFile) | ||
| if err != nil { | ||
| return "", err | ||
| } | ||
| return string(b), err | ||
|
|
||
| } | ||
|
|
||
| return "", nil | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,108 @@ | ||
| package exporter | ||
|
|
||
| import ( | ||
| "encoding/json" | ||
| "fmt" | ||
| "strconv" | ||
|
|
||
| log "github.com/Sirupsen/logrus" | ||
| ) | ||
|
|
||
| // gatherData - Collects the data from the API and stores into struct | ||
| func (e *Exporter) gatherData() ([]*Datum, *RateLimits, error) { | ||
|
|
||
| data := []*Datum{} | ||
|
|
||
| responses, err := asyncHTTPGets(e.TargetURLs, e.APIToken) | ||
|
|
||
| if err != nil { | ||
| return data, nil, err | ||
| } | ||
|
|
||
| for _, response := range responses { | ||
|
|
||
| // Github can at times present an array, or an object for the same data set. | ||
| // This code checks handles this variation. | ||
| if isArray(response.body) { | ||
| ds := []*Datum{} | ||
| json.Unmarshal(response.body, &ds) | ||
| data = append(data, ds...) | ||
| } else { | ||
| d := new(Datum) | ||
| json.Unmarshal(response.body, &d) | ||
| data = append(data, d) | ||
| } | ||
|
|
||
| log.Infof("API data fetched for repository: %s", response.url) | ||
| } | ||
|
|
||
| // Check the API rate data and store as a metric | ||
| rates, err := getRates(e.APIURL, e.APIToken) | ||
|
|
||
| if err != nil { | ||
| return data, rates, err | ||
| } | ||
|
|
||
| //return data, rates, err | ||
| return data, rates, nil | ||
|
|
||
| } | ||
|
|
||
| // getRates obtains the rate limit data for requests against the github API. | ||
| // Especially useful when operating without oauth and the subsequent lower cap. | ||
| func getRates(baseURL string, token string) (*RateLimits, error) { | ||
|
|
||
| rateEndPoint := ("/rate_limit") | ||
| url := fmt.Sprintf("%s%s", baseURL, rateEndPoint) | ||
|
|
||
| resp, err := getHTTPResponse(url, token) | ||
|
|
||
| defer resp.Body.Close() | ||
|
|
||
| if err != nil { | ||
| log.Errorf("Error requesting http data from API for repository: %s. Got Error: %s", url, err) | ||
| return &RateLimits{}, err | ||
| } | ||
|
|
||
| limit, err := strconv.ParseFloat(resp.Header.Get("X-RateLimit-Limit"), 64) | ||
|
|
||
| if err != nil { | ||
| return &RateLimits{}, err | ||
| } | ||
|
|
||
| rem, err := strconv.ParseFloat(resp.Header.Get("X-RateLimit-Remaining"), 64) | ||
|
|
||
| if err != nil { | ||
| return &RateLimits{}, err | ||
| } | ||
|
|
||
| reset, err := strconv.ParseFloat(resp.Header.Get("X-RateLimit-Reset"), 64) | ||
|
|
||
| if err != nil { | ||
| return &RateLimits{}, err | ||
| } | ||
|
|
||
| return &RateLimits{ | ||
| Limit: limit, | ||
| Remaining: rem, | ||
| Reset: reset, | ||
| }, err | ||
|
|
||
| } | ||
|
|
||
| // isArray simply looks for key details that determine if the JSON response is an array or not. | ||
| func isArray(body []byte) bool { | ||
|
|
||
| isArray := false | ||
|
|
||
| for _, c := range body { | ||
| if c == ' ' || c == '\t' || c == '\r' || c == '\n' { | ||
| continue | ||
| } | ||
| isArray = c == '[' | ||
| break | ||
| } | ||
|
|
||
| return isArray | ||
|
|
||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that go-common uses safe defaults, should we just remove this from the dockerfile?