pax_global_header00006660000000000000000000000064144410727570014525gustar00rootroot0000000000000052 comment=b187e3b3ce7346ae4d7674fbcb0e8c2bcec5176f prometheus-squid-exporter-1.10.4+ds/000077500000000000000000000000001444107275700173765ustar00rootroot00000000000000prometheus-squid-exporter-1.10.4+ds/.github/000077500000000000000000000000001444107275700207365ustar00rootroot00000000000000prometheus-squid-exporter-1.10.4+ds/.github/FUNDING.yml000066400000000000000000000012761444107275700225610ustar00rootroot00000000000000# These are supported funding model platforms github: [boynux] patreon: # Replace with a single Patreon username open_collective: # Replace with a single Open Collective username ko_fi: boynux tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry liberapay: # Replace with a single Liberapay username issuehunt: # Replace with a single IssueHunt username otechie: # Replace with a single Otechie username lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] prometheus-squid-exporter-1.10.4+ds/.github/ISSUE_TEMPLATE/000077500000000000000000000000001444107275700231215ustar00rootroot00000000000000prometheus-squid-exporter-1.10.4+ds/.github/ISSUE_TEMPLATE/bug_report.md000066400000000000000000000007031444107275700256130ustar00rootroot00000000000000--- name: Bug report about: Create a report to help us improve --- **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: **Expected behavior** A clear and concise description of what you expected to happen. **OS (please complete the following information):** - OS: [e.g. Ubuntu] - Version [e.g. v0.4] **Additional context** Add any other context about the problem here. prometheus-squid-exporter-1.10.4+ds/.github/workflows/000077500000000000000000000000001444107275700227735ustar00rootroot00000000000000prometheus-squid-exporter-1.10.4+ds/.github/workflows/docker.yml000066400000000000000000000022701444107275700247660ustar00rootroot00000000000000name: Docker Image CI on: push: branches: [master] tags: ['v*'] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Login to DockerHub uses: docker/login-action@v1 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build the Docker image run: docker build -t squid-exporter . - name: Tag the Docker image latest run: docker tag squid-exporter ${{ secrets.DOCKER_USERNAME }}/squid-exporter:latest - name: Push the Docker image latest uses: docker/build-push-action@v2 with: context: . push: true tags: ${{ secrets.DOCKER_USERNAME }}/squid-exporter:latest - name: Tag the Docker image version if: startsWith(github.ref, 'refs/tags/v') run: docker tag squid-exporter ${{ secrets.DOCKER_USERNAME }}/squid-exporter:${{ github.ref_name }} - name: Push the Docker image latest if: startsWith(github.ref, 'refs/tags/v') uses: docker/build-push-action@v2 with: context: . push: true tags: ${{ secrets.DOCKER_USERNAME }}/squid-exporter:${{ github.ref_name }} prometheus-squid-exporter-1.10.4+ds/.github/workflows/release.yml000066400000000000000000000025731444107275700251450ustar00rootroot00000000000000name: Makefile CI on: push: tags: - "v*" branches: - "master" jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Setup Go environment uses: actions/setup-go@v4.0.0 with: # Path to the go.mod or go.work file. go-version-file: go.mod - name: Build run: make - name: upload uses: actions/upload-artifact@master with: name: binary path: bin/squid-exporter release: runs-on: ubuntu-latest steps: - name: Download binaries for release uses: actions/download-artifact@v3 with: name: binary path: bin - name: Release latest version uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} asset_name: squid-exporter file: bin/squid-exporter tag: unstable overwrite: true body: "pre-release" prerelease: true - name: Release tag version if: startsWith(github.ref, 'refs/tags/v') uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: bin/squid-exporter asset_name: squid-exporter tag: ${{ github.ref }} overwrite: true body: "Stable release" needs: [build] prometheus-squid-exporter-1.10.4+ds/.gitignore000066400000000000000000000000331444107275700213620ustar00rootroot00000000000000bin/* squid-exporter *.swp prometheus-squid-exporter-1.10.4+ds/.gitpod.yml000066400000000000000000000001271444107275700214650ustar00rootroot00000000000000tasks: - init: go get && go build ./... && go test ./... && make command: go run prometheus-squid-exporter-1.10.4+ds/.travis.yml000066400000000000000000000004161444107275700215100ustar00rootroot00000000000000language: go services: - docker arch: - amd64 os: linux dist: xenial go: - 1.16.x deploy: - provider: script on: tags: true script: bash ./deploy.sh - provider: releases skip_cleanup: true token: $GH_TOKEN file: bin/squid-exporter on: tags: true prometheus-squid-exporter-1.10.4+ds/CODE_OF_CONDUCT.md000066400000000000000000000062151444107275700222010ustar00rootroot00000000000000# Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at boynux@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ prometheus-squid-exporter-1.10.4+ds/Dockerfile000066400000000000000000000007461444107275700213770ustar00rootroot00000000000000FROM golang:alpine as builder WORKDIR /go/src/github.com/boynux/squid-exporter COPY . . # Compile the binary statically, so it can be run without libraries. RUN CGO_ENABLED=0 GOOS=linux go install -a -ldflags '-extldflags "-s -w -static"' . FROM scratch COPY --from=builder /go/bin/squid-exporter /usr/local/bin/squid-exporter # Allow /etc/hosts to be used for DNS COPY --from=builder /etc/nsswitch.conf /etc/nsswitch.conf EXPOSE 9301 ENTRYPOINT ["/usr/local/bin/squid-exporter"] prometheus-squid-exporter-1.10.4+ds/LICENSE000066400000000000000000000020561444107275700204060ustar00rootroot00000000000000MIT License Copyright (c) 2017 Mohammad Arab Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. prometheus-squid-exporter-1.10.4+ds/Makefile000066400000000000000000000013301444107275700210330ustar00rootroot00000000000000.PHONY: all fmt vet test build docker clean all: fmt vet test build EXE = ./bin/squid-exporter SRC = $(shell find . -type f -name '*.go') VERSION ?= $(shell cat VERSION) REVISION = $(shell git rev-parse HEAD) BRANCH = $(shell git rev-parse --abbrev-ref HEAD) LDFLAGS = -extldflags "-s -w -static" \ -X github.com/prometheus/common/version.Version=$(VERSION) \ -X github.com/prometheus/common/version.Revision=$(REVISION) \ -X github.com/prometheus/common/version.Branch=$(BRANCH) $(EXE): $(SRC) CGO_ENABLED=0 GOOS=linux go build -a -ldflags '$(LDFLAGS)' -o $(EXE) . fmt: go fmt ./... vet: go vet ./... test: go test -v ./... build: $(EXE) docker: docker build -t squid-exporter . clean: rm -f $(EXE) prometheus-squid-exporter-1.10.4+ds/README.md000066400000000000000000000113401444107275700206540ustar00rootroot00000000000000[![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/boynux/squid-exporter) [![Github Actions](https://github.com/boynux/squid-exporter/actions/workflows/release.yml/badge.svg)](https://github.com/boynux/squid-exporter/actions/workflows/release.yml) [![Github Docker](https://github.com/boynux/squid-exporter/actions/workflows/docker.yml/badge.svg)](https://github.com/boynux/squid-exporter/actions/workflows/docker.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/boynux/squid-exporter)](https://goreportcard.com/report/github.com/boynux/squid-exporter) [![Maintainability](https://api.codeclimate.com/v1/badges/a99a88d28ad37a79dbf6/maintainability)](https://codeclimate.com/github/boynux/squid-exporter) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3TH7YAMMEC5L4&source=url) Squid Prometheus exporter -------------------------- Exports squid metrics in Prometheus format **NOTE**: From release 1.0 metric names and some parameters has changed. Make sure you check the docs and update your deployments accordingly! New ----- * Using environment variables to configure the exporter * Adding custom labels to metrics Usage: ------ Simple usage: squid-exporter -squid-hostname "localhost" -squid-port 3128 [Configure Prometheus](https://github.com/boynux/squid-exporter/blob/master/prometheus/prometheus.yml) to scrape metrics from `localhost:9301/metrics` - job_name: squid # squid-exporter is installed, grab stats about the local # squid instance. target_groups: - targets: ['localhost:9301'] To get all the parameteres, command line arguments always override default and environment variables configs: squid-exporter -help The following environment variables can be used to override default parameters: ``` SQUID_EXPORTER_LISTEN SQUID_EXPORTER_METRICS_PATH SQUID_HOSTNAME SQUID_PORT SQUID_LOGIN SQUID_PASSWORD SQUID_EXTRACTSERVICETIMES ``` Usage with docker: ------ Basic setup assuming Squid is running on the same machine: docker run --net=host -d boynux/squid-exporter Setup with Squid running on a different host docker run -p 9301:9301 -d boynux/squid-exporter -squid-hostname "192.168.0.2" -squid-port 3128 -listen ":9301" With environment variables docker run -p 9301:9301 -d -e SQUID_PORT="3128" -e SQUID_HOSTNAME="192.168.0.2" -e SQUID_EXPORTER_LISTEN=":9301" boynux/squid-exporter Build: -------- This project is written in Go, so all the usual methods for building (or cross compiling) a Go application would work. If you are not very familiar with Go you can download the binary from [releases](https://github.com/boynux/squid-exporter/releases). Or build it for your OS: `go install https://github.com/boynux/squid-exporter` then you can find the binary in: `$GOPATH/bin/squid-exporter` Features: --------- - [ ] Expose Squid counters - [x] Client HTTP - [x] Server HTTP - [x] Server ALL - [x] Server FTP - [x] Server Other - [ ] ICP - [ ] CD - [x] Swap - [ ] Page Faults - [ ] Others - [ ] Expose Squid service times - [x] HTTP requests - [x] Cache misses - [x] Cache hits - [x] Near hits - [ ] Not-Modified replies - [x] DNS lookups - [ ] ICP queries - [ ] Histograms - [ ] Other metrics - [x] Squid Authentication (Basic Auth) FAQ: -------- - Q: Metrics are not reported by exporter - A: That usually means the exporter cannot reach squid server or the config manager permissions are not set corretly. To debug and mitigate: - First make sure the exporter service can reach to squid server IP Address (you can use telnet to test that) - Make sure you allow exporter to query the squid server in config you will need something like this (`172.20.0.0/16` is the network for exporter, you can also use a single IP if needed): ``` #http_access allow manager localhost acl prometheus src 172.20.0.0/16 http_access allow manager prometheus ``` - Q: Why `process_open_fds` metric is not exported? - A: This usualy means exporter don't have permission to read `/proc//fd` folder. You can either 1. _[recommended]_ Set `CAP_DAC_READ_SEARCH` capability for squid exporter process (or docker). (eg. `sudo setcap 'cap_dac_read_search+ep' ./bin/squid-exporter`) 2. _[not recommended]_ Run the exporter as root. Contribution: ------------- Pull request and issues are very welcome. If you found this program useful please consider donations [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3TH7YAMMEC5L4&source=url) Copyright: ---------- [MIT License](https://opensource.org/licenses/MIT) prometheus-squid-exporter-1.10.4+ds/VERSION000066400000000000000000000000071444107275700204430ustar00rootroot000000000000001.10.4 prometheus-squid-exporter-1.10.4+ds/_config.yml000066400000000000000000000000331444107275700215210ustar00rootroot00000000000000theme: jekyll-theme-minimalprometheus-squid-exporter-1.10.4+ds/collector/000077500000000000000000000000001444107275700213645ustar00rootroot00000000000000prometheus-squid-exporter-1.10.4+ds/collector/client.go000066400000000000000000000125571444107275700232030ustar00rootroot00000000000000package collector import ( "bufio" "encoding/base64" "errors" "fmt" "io" "log" "net" "net/http" "strconv" "strings" "github.com/boynux/squid-exporter/types" ) /*CacheObjectClient holds information about squid manager */ type CacheObjectClient struct { ch connectionHandler basicAuthString string headers []string } type connectionHandler interface { connect() (net.Conn, error) } type connectionHandlerImpl struct { hostname string port int } /*SquidClient provides functionality to fetch squid metrics */ type SquidClient interface { GetCounters() (types.Counters, error) GetServiceTimes() (types.Counters, error) } const ( requestProtocol = "GET cache_object://localhost/%s HTTP/1.0" ) func buildBasicAuthString(login string, password string) string { if len(login) == 0 { return "" } else { return base64.StdEncoding.EncodeToString([]byte(login + ":" + password)) } } type CacheObjectRequest struct { Hostname string Port int Login string Password string Headers []string } /*NewCacheObjectClient initializes a new cache client */ func NewCacheObjectClient(cor *CacheObjectRequest) *CacheObjectClient { return &CacheObjectClient{ &connectionHandlerImpl{ cor.Hostname, cor.Port, }, buildBasicAuthString(cor.Login, cor.Password), cor.Headers, } } func (c *CacheObjectClient) readFromSquid(endpoint string) (*bufio.Reader, error) { conn, err := c.ch.connect() if err != nil { return nil, err } r, err := get(conn, endpoint, c.basicAuthString, c.headers) if err != nil { return nil, err } if r.StatusCode != 200 { return nil, fmt.Errorf("Non success code %d while fetching metrics", r.StatusCode) } return bufio.NewReader(r.Body), err } func readLines(reader *bufio.Reader, lines chan<- string) { for { line, err := reader.ReadString('\n') if err == io.EOF { break } if err != nil { log.Printf("error reading from the bufio.Reader: %v", err) break } lines <- line } close(lines) } /*GetCounters fetches counters from squid cache manager */ func (c *CacheObjectClient) GetCounters() (types.Counters, error) { var counters types.Counters reader, err := c.readFromSquid("counters") if err != nil { return nil, fmt.Errorf("error getting counters: %v", err) } lines := make(chan string) go readLines(reader, lines) for line := range lines { c, err := decodeCounterStrings(line) if err != nil { log.Println(err) } else { counters = append(counters, c) } } return counters, err } /*GetServiceTimes fetches service times from squid cache manager */ func (c *CacheObjectClient) GetServiceTimes() (types.Counters, error) { var serviceTimes types.Counters reader, err := c.readFromSquid("service_times") if err != nil { return nil, fmt.Errorf("error getting service times: %v", err) } lines := make(chan string) go readLines(reader, lines) for line := range lines { s, err := decodeServiceTimeStrings(line) if err != nil { log.Println(err) } else { if s.Key != "" { serviceTimes = append(serviceTimes, s) } } } return serviceTimes, err } func (ch *connectionHandlerImpl) connect() (net.Conn, error) { return net.Dial("tcp", fmt.Sprintf("%s:%d", ch.hostname, ch.port)) } func get(conn net.Conn, path string, basicAuthString string, headers []string) (*http.Response, error) { rBody := append(headers, []string{ fmt.Sprintf(requestProtocol, path), "Host: localhost", "User-Agent: squidclient/3.5.12", }...) if len(basicAuthString) > 0 { rBody = append(rBody, "Proxy-Authorization: Basic "+basicAuthString) rBody = append(rBody, "Authorization: Basic "+basicAuthString) } rBody = append(rBody, "Accept: */*", "\r\n") request := strings.Join(rBody, "\r\n") fmt.Fprint(conn, request) return http.ReadResponse(bufio.NewReader(conn), nil) } func decodeCounterStrings(line string) (types.Counter, error) { if equal := strings.Index(line, "="); equal >= 0 { if key := strings.TrimSpace(line[:equal]); len(key) > 0 { value := "" if len(line) > equal { value = strings.TrimSpace(line[equal+1:]) } // Remove additional formating string from `sample_time` if slices := strings.Split(value, " "); len(slices) > 0 { value = slices[0] } if i, err := strconv.ParseFloat(value, 64); err == nil { return types.Counter{Key: key, Value: i}, nil } } } return types.Counter{}, errors.New("counter - could not parse line: " + line) } func decodeServiceTimeStrings(line string) (types.Counter, error) { if strings.HasSuffix(line, ":\n") { // A header line isn't a metric return types.Counter{}, nil } if equal := strings.Index(line, ":"); equal >= 0 { if key := strings.TrimSpace(line[:equal]); len(key) > 0 { value := "" if len(line) > equal { value = strings.TrimSpace(line[equal+1:]) } key = strings.Replace(key, " ", "_", -1) key = strings.Replace(key, "(", "", -1) key = strings.Replace(key, ")", "", -1) if equalTwo := strings.Index(value, "%"); equalTwo >= 0 { if keyTwo := strings.TrimSpace(value[:equalTwo]); len(keyTwo) > 0 { if len(value) > equalTwo { value = strings.Split(strings.TrimSpace(value[equalTwo+1:]), " ")[0] } key = key + "_" + keyTwo } } if value, err := strconv.ParseFloat(value, 64); err == nil { return types.Counter{Key: key, Value: value}, nil } } } return types.Counter{}, errors.New("service times - could not parse line: " + line) } prometheus-squid-exporter-1.10.4+ds/collector/client_test.go000066400000000000000000000042051444107275700242310ustar00rootroot00000000000000package collector import ( "net" "testing" "github.com/boynux/squid-exporter/types" "github.com/stretchr/testify/assert" ) type mockConnectionHandler struct { server net.Conn buffer []byte } func (c *mockConnectionHandler) connect() (net.Conn, error) { var client net.Conn c.server, client = net.Pipe() return client, nil } func TestBuildBasicAuth(t *testing.T) { u := "test_username" p := "test_password" expectedAuthString := "dGVzdF91c2VybmFtZTp0ZXN0X3Bhc3N3b3Jk" ba := buildBasicAuthString(u, p) assert.Equal(t, expectedAuthString, ba, "Basic Auth format doesn't match") } func TestReadFromSquid(t *testing.T) { ch := &mockConnectionHandler{} go func() { b := make([]byte, 256) n, _ := ch.server.Read(b) ch.buffer = append(ch.buffer, b[:n]...) ch.server.Write(b[n:]) ch.server.Close() }() coc := &CacheObjectClient{ ch, "", []string{}, } expected := "GET cache_object://localhost/test HTTP/1.0\r\nHost: localhost\r\nUser-Agent: squidclient/3.5.12\r\nAccept: */*\r\n\r\n" coc.readFromSquid("test") assert.Equal(t, expected, string(ch.buffer)) } func TestDecodeMetricStrings(t *testing.T) { tests := []struct { s string c types.Counter e string d func(string) (types.Counter, error) }{ {"swap.files_cleaned=1", types.Counter{Key: "swap.files_cleaned", Value: 1}, "", decodeCounterStrings}, {"client.http_requests=1", types.Counter{Key: "client.http_requests", Value: 1}, "", decodeCounterStrings}, {"# test for invalid metric line", types.Counter{}, "counter - could not parse line: # test for invalid metric line", decodeCounterStrings}, {" HTTP Requests (All): 70% 10.00000 9.50000\n", types.Counter{Key: "HTTP_Requests_All_70", Value: 10}, "", decodeServiceTimeStrings}, {" Not-Modified Replies: 5% 12.00000 10.00000\n", types.Counter{Key: "Not-Modified_Replies_5", Value: 12}, "", decodeServiceTimeStrings}, {" ICP Queries: 85% 900.00000 1200.00000\n", types.Counter{Key: "ICP_Queries_85", Value: 900}, "", decodeServiceTimeStrings}, } for _, tc := range tests { c, err := tc.d(tc.s) if tc.e != "" { assert.EqualError(t, err, tc.e) } assert.Equal(t, tc.c, c) } } prometheus-squid-exporter-1.10.4+ds/collector/counters.go000066400000000000000000000055241444107275700235630ustar00rootroot00000000000000package collector import ( "fmt" "strings" "github.com/prometheus/client_golang/prometheus" ) type squidCounter struct { Section string Counter string Suffix string Description string } var squidCounters = []squidCounter{ {"client_http", "requests", "total", "The total number of client requests"}, {"client_http", "hits", "total", "The total number of client cache hits"}, {"client_http", "errors", "total", "The total number of client http errors"}, {"client_http", "kbytes_in", "kbytes_total", "The total number of client kbytes received"}, {"client_http", "kbytes_out", "kbytes_total", "The total number of client kbytes transferred"}, {"client_http", "hit_kbytes_out", "bytes_total", "The total number of client kbytes cache hit"}, {"server.http", "requests", "total", "The total number of server http requests"}, {"server.http", "errors", "total", "The total number of server http errors"}, {"server.http", "kbytes_in", "kbytes_total", "The total number of server http kbytes received"}, {"server.http", "kbytes_out", "kbytes_total", "The total number of server http kbytes transferred"}, {"server.all", "requests", "total", "The total number of server all requests"}, {"server.all", "errors", "total", "The total number of server all errors"}, {"server.all", "kbytes_in", "kbytes_total", "The total number of server kbytes received"}, {"server.all", "kbytes_out", "kbytes_total", "The total number of server kbytes transferred"}, {"server.ftp", "requests", "total", "The total number of server ftp requests"}, {"server.ftp", "errors", "total", "The total number of server ftp errors"}, {"server.ftp", "kbytes_in", "kbytes_total", "The total number of server ftp kbytes received"}, {"server.ftp", "kbytes_out", "kbytes_total", "The total number of server ftp kbytes transferred"}, {"server.other", "requests", "total", "The total number of server other requests"}, {"server.other", "errors", "total", "The total number of server other errors"}, {"server.other", "kbytes_in", "kbytes_total", "The total number of server other kbytes received"}, {"server.other", "kbytes_out", "kbytes_total", "The total number of server other kbytes transferred"}, {"swap", "ins", "total", "The number of objects read from disk"}, {"swap", "outs", "total", "The number of objects saved to disk"}, {"swap", "files_cleaned", "total", "The number of orphaned cache files removed by the periodic cleanup procedure"}, } func generateSquidCounters(labels []string) descMap { counters := descMap{} for i := range squidCounters { counter := squidCounters[i] counters[fmt.Sprintf("%s.%s", counter.Section, counter.Counter)] = prometheus.NewDesc( prometheus.BuildFQName(namespace, strings.Replace(counter.Section, ".", "_", -1), fmt.Sprintf("%s_%s", counter.Counter, counter.Suffix)), counter.Description, labels, nil, ) } return counters } prometheus-squid-exporter-1.10.4+ds/collector/metrics.go000066400000000000000000000050201444107275700233560ustar00rootroot00000000000000package collector import ( "log" "time" "github.com/boynux/squid-exporter/config" "github.com/prometheus/client_golang/prometheus" ) type descMap map[string]*prometheus.Desc const ( namespace = "squid" timeout = 10 * time.Second ) var ( counters descMap serviceTimes descMap // ExtractServiceTimes decides if we want to extract service times ExtractServiceTimes bool ) /*Exporter entry point to squid exporter */ type Exporter struct { client SquidClient hostname string port int labels config.Labels up *prometheus.GaugeVec } type CollectorConfig struct { Hostname string Port int Login string Password string Labels config.Labels Headers []string } /*New initializes a new exporter */ func New(c *CollectorConfig) *Exporter { counters = generateSquidCounters(c.Labels.Keys) if ExtractServiceTimes { serviceTimes = generateSquidServiceTimes(c.Labels.Keys) } return &Exporter{ NewCacheObjectClient(&CacheObjectRequest{ c.Hostname, c.Port, c.Login, c.Password, c.Headers, }), c.Hostname, c.Port, c.Labels, prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Name: "up", Help: "Was the last query of squid successful?", }, []string{"host"}), } } // Describe describes all the metrics ever exported by the ECS exporter. It // implements prometheus.Collector. func (e *Exporter) Describe(ch chan<- *prometheus.Desc) { e.up.Describe(ch) for _, v := range counters { ch <- v } if ExtractServiceTimes { for _, v := range serviceTimes { ch <- v } } } /*Collect fetches metrics from squid manager and pushes them to promethus */ func (e *Exporter) Collect(c chan<- prometheus.Metric) { insts, err := e.client.GetCounters() if err == nil { e.up.With(prometheus.Labels{"host": e.hostname}).Set(1) for i := range insts { if d, ok := counters[insts[i].Key]; ok { c <- prometheus.MustNewConstMetric(d, prometheus.CounterValue, insts[i].Value, e.labels.Values...) } } } else { e.up.With(prometheus.Labels{"host": e.hostname}).Set(0) log.Println("Could not fetch counter metrics from squid instance: ", err) } if ExtractServiceTimes { insts, err = e.client.GetServiceTimes() if err == nil { for i := range insts { if d, ok := serviceTimes[insts[i].Key]; ok { c <- prometheus.MustNewConstMetric(d, prometheus.GaugeValue, insts[i].Value, e.labels.Values...) } } } else { log.Println("Could not fetch service times metrics from squid instance: ", err) } } e.up.Collect(c) } prometheus-squid-exporter-1.10.4+ds/collector/service_times.go000066400000000000000000000155541444107275700245660ustar00rootroot00000000000000package collector import ( "fmt" "strings" "github.com/prometheus/client_golang/prometheus" ) type squidServiceTimes struct { Section string Counter string Suffix string Description string } var squidServiceTimess = []squidServiceTimes{ {"HTTP_Requests", "All", "5", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "10", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "15", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "20", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "25", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "30", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "35", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "40", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "45", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "50", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "55", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "60", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "65", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "70", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "75", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "80", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "85", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "90", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "95", "Service Time Percentiles 5min"}, {"HTTP_Requests", "All", "100", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "5", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "10", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "15", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "20", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "25", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "30", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "35", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "40", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "45", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "50", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "55", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "60", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "65", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "70", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "75", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "80", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "85", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "90", "Service Time Percentiles 5min"}, {"Cache_Misses", "", "95", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "5", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "10", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "15", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "20", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "25", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "30", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "35", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "40", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "45", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "50", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "55", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "60", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "65", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "70", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "75", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "80", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "85", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "90", "Service Time Percentiles 5min"}, {"Cache_Hits", "", "95", "Service Time Percentiles 5min"}, {"Near_Hits", "", "5", "Service Time Percentiles 5min"}, {"Near_Hits", "", "10", "Service Time Percentiles 5min"}, {"Near_Hits", "", "15", "Service Time Percentiles 5min"}, {"Near_Hits", "", "20", "Service Time Percentiles 5min"}, {"Near_Hits", "", "25", "Service Time Percentiles 5min"}, {"Near_Hits", "", "30", "Service Time Percentiles 5min"}, {"Near_Hits", "", "35", "Service Time Percentiles 5min"}, {"Near_Hits", "", "40", "Service Time Percentiles 5min"}, {"Near_Hits", "", "45", "Service Time Percentiles 5min"}, {"Near_Hits", "", "50", "Service Time Percentiles 5min"}, {"Near_Hits", "", "55", "Service Time Percentiles 5min"}, {"Near_Hits", "", "60", "Service Time Percentiles 5min"}, {"Near_Hits", "", "65", "Service Time Percentiles 5min"}, {"Near_Hits", "", "70", "Service Time Percentiles 5min"}, {"Near_Hits", "", "75", "Service Time Percentiles 5min"}, {"Near_Hits", "", "80", "Service Time Percentiles 5min"}, {"Near_Hits", "", "85", "Service Time Percentiles 5min"}, {"Near_Hits", "", "90", "Service Time Percentiles 5min"}, {"Near_Hits", "", "95", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "5", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "10", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "15", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "20", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "25", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "30", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "35", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "40", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "45", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "50", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "55", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "60", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "65", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "70", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "75", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "80", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "85", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "90", "Service Time Percentiles 5min"}, {"DNS_Lookups", "", "95", "Service Time Percentiles 5min"}, } func generateSquidServiceTimes(labels []string) descMap { serviceTimes := descMap{} for i := range squidServiceTimess { serviceTime := squidServiceTimess[i] var key string var name string if serviceTime.Counter != "" { key = fmt.Sprintf("%s_%s_%s", serviceTime.Section, serviceTime.Counter, serviceTime.Suffix) name = prometheus.BuildFQName(namespace, strings.Replace(serviceTime.Section, ".", "_", -1), fmt.Sprintf("%s_%s", serviceTime.Counter, serviceTime.Suffix)) } else { key = fmt.Sprintf("%s_%s", serviceTime.Section, serviceTime.Suffix) name = prometheus.BuildFQName(namespace, strings.Replace(serviceTime.Section, ".", "_", -1), fmt.Sprintf("%s", serviceTime.Suffix)) } serviceTimes[key] = prometheus.NewDesc( name, serviceTime.Description, labels, nil, ) } return serviceTimes } prometheus-squid-exporter-1.10.4+ds/config/000077500000000000000000000000001444107275700206435ustar00rootroot00000000000000prometheus-squid-exporter-1.10.4+ds/config/config.go000066400000000000000000000077001444107275700224430ustar00rootroot00000000000000package config import ( "flag" "fmt" "log" "os" "strconv" "strings" ) const ( defaultListenAddress = "127.0.0.1:9301" defaultListenPort = 9301 defaultMetricsPath = "/metrics" defaultSquidHostname = "localhost" defaultSquidPort = 3128 defaultExtractServiceTimes = true defaultUseProxyHeader = false ) const ( squidExporterListenKey = "SQUID_EXPORTER_LISTEN" squidExporterMetricsPathKey = "SQUID_EXPORTER_METRICS_PATH" squidHostnameKey = "SQUID_HOSTNAME" squidPortKey = "SQUID_PORT" squidLoginKey = "SQUID_LOGIN" squidPasswordKey = "SQUID_PASSWORD" squidPidfile = "SQUID_PIDFILE" squidExtractServiceTimes = "SQUID_EXTRACTSERVICETIMES" squidUseProxyHeader = "SQUID_USE_PRODXY_HEADER" ) var ( VersionFlag *bool ) type Labels struct { Keys []string Values []string } /*Config configurations for exporter */ type Config struct { ListenAddress string MetricPath string Labels Labels ExtractServiceTimes bool SquidHostname string SquidPort int Login string Password string Pidfile string UseProxyHeader bool } /*NewConfig creates a new config object from command line args */ func NewConfig() *Config { c := &Config{} flag.StringVar(&c.ListenAddress, "listen", loadEnvStringVar(squidExporterListenKey, defaultListenAddress), "Address and Port to bind exporter, in host:port format") flag.StringVar(&c.MetricPath, "metrics-path", loadEnvStringVar(squidExporterMetricsPathKey, defaultMetricsPath), "Metrics path to expose prometheus metrics") flag.BoolVar(&c.ExtractServiceTimes, "extractservicetimes", loadEnvBoolVar(squidExtractServiceTimes, defaultExtractServiceTimes), "Extract service times metrics") flag.Var(&c.Labels, "label", "Custom metrics to attach to metrics, use -label multiple times for each additional label") flag.StringVar(&c.SquidHostname, "squid-hostname", loadEnvStringVar(squidHostnameKey, defaultSquidHostname), "Squid hostname") flag.IntVar(&c.SquidPort, "squid-port", loadEnvIntVar(squidPortKey, defaultSquidPort), "Squid port to read metrics") flag.StringVar(&c.Login, "squid-login", loadEnvStringVar(squidLoginKey, ""), "Login to squid service") flag.StringVar(&c.Password, "squid-password", loadEnvStringVar(squidPasswordKey, ""), "Password to squid service") flag.StringVar(&c.Pidfile, "squid-pidfile", loadEnvStringVar(squidPidfile, ""), "Optional path to the squid PID file for additional metrics") flag.BoolVar(&c.UseProxyHeader, "squid-use-proxy-header", loadEnvBoolVar(squidUseProxyHeader, defaultUseProxyHeader), "Use proxy headers when fetching metrics") VersionFlag = flag.Bool("version", false, "Print the version and exit") flag.Parse() return c } func loadEnvBoolVar(key string, def bool) bool { val := os.Getenv(key) if val == "" { return def } switch strings.ToLower(val) { case "true": return true case "false": return false default: return def } } func loadEnvStringVar(key, def string) string { val := os.Getenv(key) if val == "" { return def } return val } func loadEnvIntVar(key string, def int) int { valStr := os.Getenv(key) if valStr != "" { val, err := strconv.ParseInt(valStr, 0, 32) if err == nil { return int(val) } log.Printf("Error parsing %s='%s'. Integer value expected", key, valStr) } return def } func (l *Labels) String() string { var lbls []string for i := range l.Keys { lbls = append(lbls, l.Keys[i]+"="+l.Values[i]) } return strings.Join(lbls, ", ") } func (l *Labels) Set(value string) error { args := strings.Split(value, "=") if len(args) != 2 || len(args[1]) < 1 { return fmt.Errorf("Label must be in 'key=value' format") } for _, key := range l.Keys { if key == args[0] { return fmt.Errorf("Labels must be distinct, found duplicated key %s", args[0]) } } l.Keys = append(l.Keys, args[0]) l.Values = append(l.Values, args[1]) return nil } prometheus-squid-exporter-1.10.4+ds/dashboards/000077500000000000000000000000001444107275700215105ustar00rootroot00000000000000prometheus-squid-exporter-1.10.4+ds/dashboards/squid-sample-dashboard.json000066400000000000000000000330031444107275700267330ustar00rootroot00000000000000{ "__inputs": [], "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", "version": "5.2.4" }, { "type": "panel", "id": "graph", "name": "Graph", "version": "5.0.0" }, { "type": "panel", "id": "singlestat", "name": "Singlestat", "version": "5.0.0" }, { "type": "panel", "id": "text", "name": "Text", "version": "5.0.0" } ], "annotations": { "list": [ { "builtIn": 1, "datasource": "-- Grafana --", "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" } ] }, "editable": true, "gnetId": null, "graphTooltip": 0, "id": null, "iteration": 1536353270000, "links": [], "panels": [ { "content": "

Squid Sample Dashboard

", "gridPos": { "h": 3, "w": 6, "x": 0, "y": 0 }, "id": 10, "links": [], "mode": "html", "title": "", "type": "text" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "#d44a3a", "rgba(237, 129, 40, 0.89)", "#299c46" ], "datasource": "$datasource", "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 6, "x": 6, "y": 0 }, "id": 14, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "postfix": "", "postfixFontSize": "200%", "prefix": "", "prefixFontSize": "200%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "up{job='squid'}", "format": "time_series", "intervalFactor": 1, "legendFormat": "", "refId": "A" } ], "thresholds": "0,1", "title": "Services Up", "type": "singlestat", "valueFontSize": "200%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "#299c46", "rgba(237, 129, 40, 0.89)", "#d44a3a" ], "datasource": "$datasource", "format": "percentunit", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 4, "x": 12, "y": 0 }, "id": 8, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "squid_client_http_hit_kbytes_out_bytes_total / squid_client_http_kbytes_out_kbytes_total", "format": "time_series", "intervalFactor": 1, "refId": "A" } ], "thresholds": "", "title": "Bytes Hit Rate", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "avg" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "#299c46", "rgba(237, 129, 40, 0.89)", "#d44a3a" ], "datasource": "$datasource", "format": "percentunit", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 4, "x": 16, "y": 0 }, "id": 6, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "squid_client_http_hits_total / squid_client_http_requests_total", "format": "time_series", "intervalFactor": 1, "legendFormat": "Hit rate", "refId": "A" } ], "thresholds": "", "title": "Catch Hit Rate", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "avg" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "#299c46", "rgba(237, 129, 40, 0.89)", "#d44a3a" ], "datasource": "$datasource", "format": "percentunit", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 4, "x": 20, "y": 0 }, "id": 12, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "squid_client_http_errors_total / squid_client_http_requests_total", "format": "time_series", "intervalFactor": 1, "refId": "A" } ], "thresholds": "", "title": "Error Rate", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "avg" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "$datasource", "fill": 1, "gridPos": { "h": 6, "w": 12, "x": 0, "y": 3 }, "id": 2, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "rate(squid_client_http_requests_total[5m])", "format": "time_series", "interval": "", "intervalFactor": 1, "legendFormat": "Total Requests", "refId": "B" }, { "expr": "rate(squid_client_http_hits_total[5m])", "format": "time_series", "interval": "", "intervalFactor": 1, "legendFormat": "Total HTTP hits", "refId": "A" }, { "expr": "rate(squid_client_http_errors_total[5m])", "format": "time_series", "intervalFactor": 1, "legendFormat": "Total Errors", "refId": "C" } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Client Requests", "tooltip": { "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "reqps", "label": null, "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "$datasource", "fill": 1, "gridPos": { "h": 6, "w": 12, "x": 12, "y": 3 }, "id": 4, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "rate(squid_client_http_kbytes_in_kbytes_total[5m]) * -1", "format": "time_series", "interval": "", "intervalFactor": 1, "legendFormat": "HTTP Traffic in", "refId": "A" }, { "expr": "rate(squid_client_http_kbytes_out_kbytes_total[5m])", "format": "time_series", "intervalFactor": 1, "legendFormat": "HTTP Traffic Out", "refId": "B" }, { "expr": "rate(squid_client_http_hit_kbytes_out_bytes_total[5m])", "format": "time_series", "interval": "", "intervalFactor": 1, "legendFormat": "HTTP Traffic Out Hits", "refId": "C" } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Client Traffic", "tooltip": { "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "KBs", "label": null, "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } } ], "schemaVersion": 16, "style": "dark", "tags": [], "templating": { "list": [ { "current": { "text": "default", "value": "default" }, "hide": 0, "label": null, "name": "datasource", "options": [], "query": "prometheus", "refresh": 1, "regex": "", "type": "datasource" } ] }, "time": { "from": "now-6h", "to": "now" }, "timepicker": { "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ] }, "timezone": "", "title": "Squid Sample Dashboard", "uid": "yRc_Bj2ik", "version": 3 }prometheus-squid-exporter-1.10.4+ds/deploy.sh000066400000000000000000000005371444107275700212330ustar00rootroot00000000000000#!/bin/bash # Travis Docker deploy script IMAGE_NAME="boynux/squid-exporter" IMAGE_TAG=${TRAVIS_TAG:-latest} docker --version docker build -t $IMAGE_NAME:$IMAGE_TAG . docker tag $IMAGE_NAME:$IMAGE_TAG $IMAGE_NAME:latest echo $DOCKER_API_KEY | docker login -u boynux --password-stdin docker push $IMAGE_NAME:$IMAGE_TAG docker push $IMAGE_NAME:latest prometheus-squid-exporter-1.10.4+ds/go.mod000066400000000000000000000014651444107275700205120ustar00rootroot00000000000000module github.com/boynux/squid-exporter go 1.19 require ( github.com/pires/go-proxyproto v0.6.2 github.com/prometheus/client_golang v1.12.2 github.com/prometheus/common v0.34.0 github.com/stretchr/testify v1.7.0 ) require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/procfs v0.7.3 // indirect golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) prometheus-squid-exporter-1.10.4+ds/go.sum000066400000000000000000001371271444107275700205440ustar00rootroot00000000000000cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8= github.com/pires/go-proxyproto v0.6.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.34.0 h1:RBmGO9d/FVjqHT0yUGQwBJhkwKV+wPCn7KGpvfab0uE= github.com/prometheus/common v0.34.0/go.mod h1:gB3sOl7P0TvJabZpLY5uQMpUqRCPPCyRLCZYc7JZTNE= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d h1:Zu/JngovGLVi6t2J3nmAf3AoTDwuzw85YZ3b9o4yU7s= golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= prometheus-squid-exporter-1.10.4+ds/helm/000077500000000000000000000000001444107275700203235ustar00rootroot00000000000000prometheus-squid-exporter-1.10.4+ds/helm/.helmignore000066400000000000000000000005351444107275700224600ustar00rootroot00000000000000# Patterns to ignore when building packages. # This supports shell glob matching, relative path matching, and # negation (prefixed with !). Only one pattern per line. .DS_Store # Common VCS dirs .git/ .gitignore .bzr/ .bzrignore .hg/ .hgignore .svn/ # Common backup files *.swp *.bak *.tmp *.orig *~ # Various IDEs .project .idea/ *.tmproj .vscode/ prometheus-squid-exporter-1.10.4+ds/helm/Chart.yaml000066400000000000000000000002171444107275700222500ustar00rootroot00000000000000apiVersion: v2 name: squid-exporter description: A helm chart to deploy Squid Exporter. type: application version: 0.1.0 appVersion: "v1.10.3" prometheus-squid-exporter-1.10.4+ds/helm/templates/000077500000000000000000000000001444107275700223215ustar00rootroot00000000000000prometheus-squid-exporter-1.10.4+ds/helm/templates/NOTES.txt000066400000000000000000000033571444107275700237620ustar00rootroot000000000000001. Get the application URL by running these commands: {{- if .Values.ingress.enabled }} {{- range $host := .Values.ingress.hosts }} {{- range .paths }} http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} {{- end }} {{- end }} {{- else if contains "NodePort" .Values.service.type }} export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "squid-exporter.fullname" . }}) export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") echo http://$NODE_IP:$NODE_PORT {{- else if contains "LoadBalancer" .Values.service.type }} NOTE: It may take a few minutes for the LoadBalancer IP to be available. You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "squid-exporter.fullname" . }}' export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "squid-exporter.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") echo http://$SERVICE_IP:{{ .Values.service.port }} {{- else if contains "ClusterIP" .Values.service.type }} export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "squid-exporter.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") echo "Visit http://127.0.0.1:8080 to use your application" kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT {{- end }} prometheus-squid-exporter-1.10.4+ds/helm/templates/_helpers.tpl000066400000000000000000000037261444107275700246530ustar00rootroot00000000000000{{/* Expand the name of the chart. */}} {{- define "squid-exporter.name" -}} {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} {{- end }} {{/* Create a default fully qualified app name. We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). If release name contains chart name it will be used as a full name. */}} {{- define "squid-exporter.fullname" -}} {{- if .Values.fullnameOverride }} {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} {{- else }} {{- $name := default .Chart.Name .Values.nameOverride }} {{- if contains $name .Release.Name }} {{- .Release.Name | trunc 63 | trimSuffix "-" }} {{- else }} {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} {{- end }} {{- end }} {{- end }} {{/* Create chart name and version as used by the chart label. */}} {{- define "squid-exporter.chart" -}} {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} {{- end }} {{/* Common labels */}} {{- define "squid-exporter.labels" -}} helm.sh/chart: {{ include "squid-exporter.chart" . }} {{ include "squid-exporter.selectorLabels" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} app.kubernetes.io/managed-by: {{ .Release.Service }} squid-exporter.boynux.com/proxy-hostname: {{ .Values.squidConfig.hostname }} squid-exporter.boynux.com/proxy-port: {{ .Values.squidConfig.port | quote }} {{- end }} {{/* Selector labels */}} {{- define "squid-exporter.selectorLabels" -}} app.kubernetes.io/name: {{ include "squid-exporter.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} {{/* Create the name of the service account to use */}} {{- define "squid-exporter.serviceAccountName" -}} {{- if .Values.serviceAccount.create }} {{- default (include "squid-exporter.fullname" .) .Values.serviceAccount.name }} {{- else }} {{- default "default" .Values.serviceAccount.name }} {{- end }} {{- end }} prometheus-squid-exporter-1.10.4+ds/helm/templates/deployment.yaml000066400000000000000000000046061444107275700253730ustar00rootroot00000000000000apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "squid-exporter.fullname" . }} labels: {{- include "squid-exporter.labels" . | nindent 4 }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: {{- include "squid-exporter.selectorLabels" . | nindent 6 }} template: metadata: annotations: checksum/config: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} {{- with .Values.podAnnotations }} {{- toYaml . | nindent 8 }} {{- end }} labels: {{- include "squid-exporter.selectorLabels" . | nindent 8 }} spec: {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} serviceAccountName: {{ include "squid-exporter.serviceAccountName" . }} securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} containers: - name: {{ .Chart.Name }} securityContext: {{- toYaml .Values.securityContext | nindent 12 }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} envFrom: - secretRef: name: {{ include "squid-exporter.fullname" . }} env: - name: SQUID_EXPORTER_LISTEN value: "0.0.0.0:9301" - name: SQUID_EXPORTER_METRICS_PATH value: /metrics - name: SQUID_HOSTNAME value: {{ required ".Values.squidConfig.hostname must be defined" .Values.squidConfig.hostname }} - name: SQUID_PORT value: {{ .Values.squidConfig.port | quote }} ports: - name: metrics containerPort: 9301 protocol: TCP livenessProbe: httpGet: path: / port: metrics readinessProbe: httpGet: path: / port: metrics resources: {{- toYaml .Values.resources | nindent 12 }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.affinity }} affinity: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} {{- end }} prometheus-squid-exporter-1.10.4+ds/helm/templates/ingress.yaml000066400000000000000000000040551444107275700246630ustar00rootroot00000000000000{{- if .Values.ingress.enabled -}} {{- $fullName := include "squid-exporter.fullname" . -}} {{- $svcPort := .Values.service.port -}} {{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} {{- end }} {{- end }} {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} apiVersion: networking.k8s.io/v1 {{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} apiVersion: networking.k8s.io/v1beta1 {{- else -}} apiVersion: extensions/v1beta1 {{- end }} kind: Ingress metadata: name: {{ $fullName }} labels: {{- include "squid-exporter.labels" . | nindent 4 }} {{- with .Values.ingress.annotations }} annotations: {{- toYaml . | nindent 4 }} {{- end }} spec: {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} ingressClassName: {{ .Values.ingress.className }} {{- end }} {{- if .Values.ingress.tls }} tls: {{- range .Values.ingress.tls }} - hosts: {{- range .hosts }} - {{ . | quote }} {{- end }} secretName: {{ .secretName }} {{- end }} {{- end }} rules: {{- range .Values.ingress.hosts }} - host: {{ .host | quote }} http: paths: {{- range .paths }} - path: {{ .path }} {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} pathType: {{ .pathType }} {{- end }} backend: {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} service: name: {{ $fullName }} port: number: {{ $svcPort }} {{- else }} serviceName: {{ $fullName }} servicePort: {{ $svcPort }} {{- end }} {{- end }} {{- end }} {{- end }} prometheus-squid-exporter-1.10.4+ds/helm/templates/prometheusrules.yaml000066400000000000000000000007351444107275700264600ustar00rootroot00000000000000{{- if .Values.serviceMonitor.rules }} apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: name: {{ include "squid-exporter.fullname" . }} labels: {{- include "squid-exporter.labels" . | nindent 4 }} {{- with .Values.serviceMonitor.labels }} {{- . | toYaml | nindent 4 }} {{- end }} spec: groups: - name: {{ include "squid-exporter.fullname" . }} rules: {{- .Values.serviceMonitor.rules | toYaml | nindent 8 }} {{- end }}prometheus-squid-exporter-1.10.4+ds/helm/templates/secret.yaml000066400000000000000000000004261444107275700244740ustar00rootroot00000000000000apiVersion: v1 kind: Secret metadata: name: {{ include "squid-exporter.fullname" . }} labels: {{- include "squid-exporter.labels" . | nindent 4 }} data: SQUID_LOGIN: {{ .Values.squidConfig.login | b64enc }} SQUID_PASSWORD: {{ .Values.squidConfig.password | b64enc }}prometheus-squid-exporter-1.10.4+ds/helm/templates/service.yaml000066400000000000000000000014151444107275700246460ustar00rootroot00000000000000apiVersion: v1 kind: Service metadata: name: {{ include "squid-exporter.fullname" . }} labels: {{- include "squid-exporter.labels" . | nindent 4 }} spec: type: {{ .Values.service.type }} {{- if or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer") }} externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy }} {{- end }} sessionAffinity: {{ .Values.service.sessionAffinity }} ports: - port: {{ .Values.service.port }} targetPort: metrics protocol: TCP name: metrics {{- if or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer") }} nodePort: {{ .Values.service.nodePort }} {{- end }} selector: {{- include "squid-exporter.selectorLabels" . | nindent 4 }} prometheus-squid-exporter-1.10.4+ds/helm/templates/serviceaccount.yaml000066400000000000000000000005161444107275700262240ustar00rootroot00000000000000{{- if .Values.serviceAccount.create -}} apiVersion: v1 kind: ServiceAccount metadata: name: {{ include "squid-exporter.serviceAccountName" . }} labels: {{- include "squid-exporter.labels" . | nindent 4 }} {{- with .Values.serviceAccount.annotations }} annotations: {{- toYaml . | nindent 4 }} {{- end }} {{- end }} prometheus-squid-exporter-1.10.4+ds/helm/templates/servicemonitor.yaml000066400000000000000000000017421444107275700262610ustar00rootroot00000000000000apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: {{ include "squid-exporter.fullname" . }} labels: {{- include "squid-exporter.labels" . | nindent 4 }} {{- with .Values.serviceMonitor.labels }} {{- . | toYaml | nindent 4 }} {{- end }} spec: endpoints: - port: metrics interval: {{ .Values.serviceMonitor.interval }} metricRelabelings: {{- .Values.serviceMonitor.additionalMetricsRelabels | toYaml | nindent 10 }} path: "/metrics" relabelings: {{- .Values.serviceMonitor.additionalRelabeling | toYaml | nindent 10 }} scheme: http scrapeTimeout: {{ .Values.serviceMonitor.scrapeTimeout }} targetLabels: {{- range $label, $val := .Values.serviceMonitor.labels }} - {{ $label }} {{- end }} - squid-exporter.boynux.com/proxy-hostname - squid-exporter.boynux.com/proxy-port selector: matchLabels: {{- include "squid-exporter.selectorLabels" . | nindent 8 }}prometheus-squid-exporter-1.10.4+ds/helm/values.yaml000066400000000000000000000065471444107275700225220ustar00rootroot00000000000000# Default values for squid-exporter. # This is a YAML-formatted file. # Declare variables to be passed into your templates. squidConfig: login: "" password: "" hostname: "" port: 3128 # Under normal circumstances one replica is needed. replicaCount: 1 image: repository: boynux/squid-exporter pullPolicy: IfNotPresent # Overrides the image tag whose default is the chart appVersion. tag: "" imagePullSecrets: [] nameOverride: "" fullnameOverride: "" serviceAccount: # Specifies whether a service account should be created create: true # Annotations to add to the service account annotations: {} # The name of the service account to use. # If not set and create is true, a name is generated using the fullname template name: "" podAnnotations: {} podSecurityContext: {} # fsGroup: 2000 securityContext: {} # capabilities: # drop: # - ALL # readOnlyRootFilesystem: true # runAsNonRoot: true # runAsUser: 1000 service: # Kubernetes Service type, one of [ClusterIP, NodePort, LoadBalancer] type: ClusterIP port: 80 # Supports either ClientIP or None. # Used to maintain session affinity. # Enable client IP based session affinity. # https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies sessionAffinity: ClientIP # Service settings below are applicable only if # service.type is one of [LoadBalancer, NodePort] and not ClusterIP. # Possible values are [Cluster, Local]. # If set to Local, then the Service's port will be available only on Kubernetes # Nodes which have the Squid Pods so no Kubernetes Node-to-Node traffic will be forwarded. # If set to Cluster, then the Service's port will be available on any Node of # a Kubernetes cluster. The drawback is that Kubernetes will use double NAT # so it will hide the Client source IP from Squid. externalTrafficPolicy: Cluster # Node port to listen on. Typically, Kubernetes allows ports in range 30000-32767 # see https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport # for more information. nodePort: "" ingress: enabled: false className: "" annotations: {} # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" hosts: - host: chart-example.local paths: - path: / pathType: ImplementationSpecific tls: [] # - secretName: chart-example-tls # hosts: # - chart-example.local resources: {} # We usually recommend not to specify default resources and to leave this as a conscious # choice for the user. This also increases chances charts run on environments with little # resources, such as Minikube. If you do want to specify resources, uncomment the following # lines, adjust them as necessary, and remove the curly braces after 'resources:'. # limits: # cpu: 100m # memory: 128Mi # requests: # cpu: 100m # memory: 128Mi nodeSelector: {} tolerations: [] affinity: {} serviceMonitor: enabled: false additionalMetricsRelabels: [] additionalRelabeling: [] labels: {} interval: 30s scrapeTimeout: 30s # Prometheus Operator rules to install rules: [] # - alert: SquidDown # annotations: # message: Exporter can not collect metrics from Squid proxy server {{ $labels.host }} # expr: squid_up == 0 # for: 5m # labels: # severity: critical prometheus-squid-exporter-1.10.4+ds/helpers.go000066400000000000000000000024741444107275700213760ustar00rootroot00000000000000package main import ( "log" "net" "strconv" "strings" "github.com/boynux/squid-exporter/config" proxyproto "github.com/pires/go-proxyproto" ) func createProxyHeader(cfg *config.Config) string { la := strings.Split(cfg.ListenAddress, ":") if len(la) < 2 { log.Printf("Cannot parse listen address (%s). Failed to create proxy header\n", cfg.ListenAddress) return "" } spt, err := strconv.Atoi(la[1]) if err != nil { log.Printf("Failed to create proxy header: %v\n", err.Error()) return "" } sip, err := net.LookupIP(la[0]) if err != nil { log.Printf("Failed to create proxy header: %v\n", err.Error()) return "" } dip, err := net.LookupIP(cfg.SquidHostname) if err != nil { log.Printf("Failed to create proxy header: %v\n", err.Error()) return "" } ph := &proxyproto.Header{ Version: 1, Command: proxyproto.PROXY, TransportProtocol: proxyproto.TCPv4, SourceAddr: &net.TCPAddr{ IP: sip[0], Port: spt, }, DestinationAddr: &net.TCPAddr{ IP: dip[0], Port: cfg.SquidPort, }, } phs, err := ph.Format() if err != nil { log.Printf("Failed to create proxy header: %v\n", err.Error()) } // proxyproto adds crlf to the end of the header string, but we will add this later // we are triming it here. return strings.TrimSuffix(string(phs), "\r\n") } prometheus-squid-exporter-1.10.4+ds/helpers_test.go000066400000000000000000000007031444107275700224260ustar00rootroot00000000000000package main import ( "testing" "github.com/stretchr/testify/assert" "github.com/boynux/squid-exporter/config" ) func TestCreatProxyHelper(t *testing.T) { cfg := &config.Config{ ListenAddress: "192.0.2.1:3192", SquidHostname: "127.0.0.1", SquidPort: 3128, } expectedHProxyString := "PROXY TCP4 192.0.2.1 127.0.0.1 3192 3128" p := createProxyHeader(cfg) assert.Equal(t, expectedHProxyString, p, "Proxy headers do not match!") } prometheus-squid-exporter-1.10.4+ds/main.go000066400000000000000000000041511444107275700206520ustar00rootroot00000000000000package main import ( "fmt" "io/ioutil" "log" "net/http" "os" "strconv" "strings" "github.com/boynux/squid-exporter/collector" "github.com/boynux/squid-exporter/config" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/common/version" ) const indexContent = ` Squid Exporter

Squid Exporter

Metrics

` func init() { prometheus.MustRegister(version.NewCollector("squid_exporter")) } func main() { cfg := config.NewConfig() if *config.VersionFlag { log.Println(version.Print("squid_exporter")) os.Exit(0) } collector.ExtractServiceTimes = cfg.ExtractServiceTimes headers := []string{} if cfg.UseProxyHeader { headers = append(headers, createProxyHeader(cfg)) } log.Println("Scraping metrics from", fmt.Sprintf("%s:%d", cfg.SquidHostname, cfg.SquidPort)) e := collector.New(&collector.CollectorConfig{ Hostname: cfg.SquidHostname, Port: cfg.SquidPort, Login: cfg.Login, Password: cfg.Password, Labels: cfg.Labels, Headers: headers, }) prometheus.MustRegister(e) if cfg.Pidfile != "" { procExporter := prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{ PidFn: func() (int, error) { content, err := ioutil.ReadFile(cfg.Pidfile) if err != nil { return 0, fmt.Errorf("can't read pid file %q: %s", cfg.Pidfile, err) } value, err := strconv.Atoi(strings.TrimSpace(string(content))) if err != nil { return 0, fmt.Errorf("can't parse pid file %q: %s", cfg.Pidfile, err) } return value, nil }, Namespace: "squid", }) prometheus.MustRegister(procExporter) } // Serve metrics http.Handle(cfg.MetricPath, promhttp.Handler()) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte(indexContent)) }) log.Println("Listening on", fmt.Sprintf("%s", cfg.ListenAddress)) log.Fatal(http.ListenAndServe(fmt.Sprintf("%s", cfg.ListenAddress), nil)) } prometheus-squid-exporter-1.10.4+ds/prometheus/000077500000000000000000000000001444107275700215715ustar00rootroot00000000000000prometheus-squid-exporter-1.10.4+ds/prometheus/prometheus.yml000066400000000000000000000016301444107275700245070ustar00rootroot00000000000000# my global config global: scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. # scrape_timeout is set to the global default (10s). # Alertmanager configuration alerting: alertmanagers: - static_configs: - targets: # - alertmanager:9093 # Load rules once and periodically evaluate them according to the global 'evaluation_interval'. rule_files: # - "first_rules.yml" # - "second_rules.yml" # A scrape configuration containing exactly one endpoint to scrape: # Here it's Prometheus itself. scrape_configs: # The job name is added as a label `job=` to any timeseries scraped from this config. - job_name: 'squid' # metrics_path defaults to '/metrics' # scheme defaults to 'http' static_configs: - targets: ['localhost:9301'] prometheus-squid-exporter-1.10.4+ds/types/000077500000000000000000000000001444107275700205425ustar00rootroot00000000000000prometheus-squid-exporter-1.10.4+ds/types/types.go000066400000000000000000000002621444107275700222350ustar00rootroot00000000000000package types /*Counter maps a squid conters */ type Counter struct { Key string Value float64 } /*Counters is a list of multiple squid counters */ type Counters []Counter