Merge tag 'upstream/0.12.0' into unvendored
Guillem Jover
3 years ago
0 | 0 | --- |
1 | version: 2 | |
1 | version: 2.1 | |
2 | ||
3 | orbs: | |
4 | prometheus: prometheus/prometheus@0.4.0 | |
2 | 5 | |
3 | 6 | jobs: |
4 | 7 | test: |
8 | # Whenever the Go version is updated here, .promu.yml | |
9 | # should also be updated. | |
5 | 10 | docker: |
6 | - image: circleci/golang:1.10 | |
7 | working_directory: /go/src/github.com/prometheus/haproxy_exporter | |
11 | - image: circleci/golang:1.15 | |
8 | 12 | |
9 | 13 | steps: |
10 | - checkout | |
14 | - prometheus/setup_environment | |
11 | 15 | - setup_remote_docker |
12 | - run: make promu | |
13 | 16 | - run: make |
14 | - run: rm -f haproxy_exporter | |
15 | ||
16 | build: | |
17 | machine: true | |
18 | working_directory: /home/circleci/.go_workspace/src/github.com/prometheus/haproxy_exporter | |
19 | ||
20 | steps: | |
21 | - checkout | |
22 | - run: make promu | |
23 | - run: promu crossbuild -v | |
24 | - persist_to_workspace: | |
25 | root: . | |
26 | paths: | |
27 | - .build | |
28 | ||
29 | docker_hub_master: | |
30 | docker: | |
31 | - image: circleci/golang:1.10 | |
32 | working_directory: /go/src/github.com/prometheus/haproxy_exporter | |
33 | ||
34 | environment: | |
35 | DOCKER_IMAGE_NAME: prom/haproxy-exporter | |
36 | QUAY_IMAGE_NAME: quay.io/prometheus/haproxy-exporter | |
37 | ||
38 | steps: | |
39 | - checkout | |
40 | - setup_remote_docker | |
41 | - attach_workspace: | |
42 | at: . | |
43 | - run: ln -s .build/linux-amd64/haproxy_exporter haproxy_exporter | |
44 | - run: make docker DOCKER_IMAGE_NAME=$DOCKER_IMAGE_NAME | |
45 | - run: make docker DOCKER_IMAGE_NAME=$QUAY_IMAGE_NAME | |
46 | - run: docker images | |
47 | - run: docker login -u $DOCKER_LOGIN -p $DOCKER_PASSWORD | |
48 | - run: docker login -u $QUAY_LOGIN -p $QUAY_PASSWORD quay.io | |
49 | - run: docker push $DOCKER_IMAGE_NAME | |
50 | - run: docker push $QUAY_IMAGE_NAME | |
51 | ||
52 | docker_hub_release_tags: | |
53 | docker: | |
54 | - image: circleci/golang:1.10 | |
55 | working_directory: /go/src/github.com/prometheus/haproxy_exporter | |
56 | ||
57 | environment: | |
58 | DOCKER_IMAGE_NAME: prom/haproxy-exporter | |
59 | QUAY_IMAGE_NAME: quay.io/prometheus/haproxy-exporter | |
60 | ||
61 | steps: | |
62 | - checkout | |
63 | - setup_remote_docker | |
64 | - run: mkdir -v -p ${HOME}/bin | |
65 | - run: curl -L 'https://github.com/aktau/github-release/releases/download/v0.7.2/linux-amd64-github-release.tar.bz2' | tar xvjf - --strip-components 3 -C ${HOME}/bin | |
66 | - run: echo 'export PATH=${HOME}/bin:${PATH}' >> ${BASH_ENV} | |
67 | - attach_workspace: | |
68 | at: . | |
69 | - run: make promu | |
70 | - run: promu crossbuild tarballs | |
71 | - run: promu checksum .tarballs | |
72 | - run: promu release .tarballs | |
73 | - store_artifacts: | |
74 | path: .tarballs | |
75 | destination: releases | |
76 | - run: ln -s .build/linux-amd64/haproxy_exporter haproxy_exporter | |
77 | - run: make docker DOCKER_IMAGE_NAME=$DOCKER_IMAGE_NAME DOCKER_IMAGE_TAG=$CIRCLE_TAG | |
78 | - run: make docker DOCKER_IMAGE_NAME=$QUAY_IMAGE_NAME DOCKER_IMAGE_TAG=$CIRCLE_TAG | |
79 | - run: docker login -u $DOCKER_LOGIN -p $DOCKER_PASSWORD | |
80 | - run: docker login -u $QUAY_LOGIN -p $QUAY_PASSWORD quay.io | |
81 | - run: | | |
82 | if [[ "$CIRCLE_TAG" =~ ^v[0-9]+(\.[0-9]+){2}$ ]]; then | |
83 | docker tag "$DOCKER_IMAGE_NAME:$CIRCLE_TAG" "$DOCKER_IMAGE_NAME:latest" | |
84 | docker tag "$QUAY_IMAGE_NAME:$CIRCLE_TAG" "$QUAY_IMAGE_NAME:latest" | |
85 | fi | |
86 | - run: docker push $DOCKER_IMAGE_NAME | |
87 | - run: docker push $QUAY_IMAGE_NAME | |
17 | - prometheus/store_artifact: | |
18 | file: haproxy_exporter | |
88 | 19 | |
89 | 20 | workflows: |
90 | 21 | version: 2 |
94 | 25 | filters: |
95 | 26 | tags: |
96 | 27 | only: /.*/ |
97 | - build: | |
28 | - prometheus/build: | |
29 | name: build | |
98 | 30 | filters: |
99 | 31 | tags: |
100 | 32 | only: /.*/ |
101 | - docker_hub_master: | |
33 | - prometheus/publish_master: | |
34 | context: org-context | |
102 | 35 | requires: |
103 | 36 | - test |
104 | 37 | - build |
105 | 38 | filters: |
106 | 39 | branches: |
107 | 40 | only: master |
108 | - docker_hub_release_tags: | |
41 | - prometheus/publish_release: | |
42 | context: org-context | |
109 | 43 | requires: |
110 | 44 | - test |
111 | 45 | - build |
0 | run: | |
1 | modules-download-mode: vendor | |
2 | ||
3 | # Run only staticcheck for now. Additional linters will be enabled one-by-one. | |
4 | linters: | |
5 | enable: | |
6 | - staticcheck | |
7 | disable-all: true |
0 | go: | |
1 | # Whenever the Go version is updated here, | |
2 | # .circle/config.yml should also be updated. | |
3 | version: 1.15 | |
0 | 4 | repository: |
1 | 5 | path: github.com/prometheus/haproxy_exporter |
2 | 6 | build: |
3 | flags: -a -tags netgo | |
7 | flags: -mod=vendor -a -tags netgo | |
4 | 8 | ldflags: | |
5 | -X {{repoPath}}/vendor/github.com/prometheus/common/version.Version={{.Version}} | |
6 | -X {{repoPath}}/vendor/github.com/prometheus/common/version.Revision={{.Revision}} | |
7 | -X {{repoPath}}/vendor/github.com/prometheus/common/version.Branch={{.Branch}} | |
8 | -X {{repoPath}}/vendor/github.com/prometheus/common/version.BuildUser={{user}}@{{host}} | |
9 | -X {{repoPath}}/vendor/github.com/prometheus/common/version.BuildDate={{date "20060102-15:04:05"}} | |
9 | -X github.com/prometheus/common/version.Version={{.Version}} | |
10 | -X github.com/prometheus/common/version.Revision={{.Revision}} | |
11 | -X github.com/prometheus/common/version.Branch={{.Branch}} | |
12 | -X github.com/prometheus/common/version.BuildUser={{user}}@{{host}} | |
13 | -X github.com/prometheus/common/version.BuildDate={{date "20060102-15:04:05"}} | |
10 | 14 | tarball: |
11 | 15 | files: |
12 | 16 | - LICENSE |
0 | ## 0.12.0 / 2020-12-09 | |
1 | ||
2 | * [ENHANCEMENT] Add --version flag #189 | |
3 | * [BUGFIX] Use newest Go version to fix random panic in the runtime | |
4 | * [BUGFIX] Fix typos in log messages #188 #191 | |
5 | ||
6 | ## 0.11.0 / 2020-06-21 | |
7 | ||
8 | * [CHANGE] Switch logging to go-kit #171 | |
9 | * [CHANGE] Fix metric types #182 | |
10 | * [CHANGE] Fix unit of time metric #183 | |
11 | * [FEATURE] Add filtering on server status #160 | |
12 | * [ENHANCEMENT] Add compression and server selection metrics #154 | |
13 | * [ENHANCEMENT] Add client/server abort metrics #167 | |
14 | * [ENHANCEMENT] Add version info metric (when using UNIX sockets) #180 | |
15 | ||
16 | Note: This release fixes the metric types of counters and renames the following metrics: | |
17 | ||
18 | * `haproxy_exporter_csv_parse_failures` -> `haproxy_exporter_csv_parse_failures_total` | |
19 | * `haproxy_exporter_total_scrapes` -> `haproxy_exporter_scrapes_total` | |
20 | * `haproxy_server_check_duration_milliseconds` -> `haproxy_server_check_duration_seconds` | |
21 | ||
22 | ## 0.10.0 / 2019-01-15 | |
23 | ||
24 | * [ENHANCEMENT] Convert metrics collection to Const metrics #139 | |
25 | * [BUGFIX] Fix silent dropping of metrics for older versions of haproxy #139 | |
26 | ||
27 | ## 0.9.0 / 2018-01-23 | |
28 | ||
29 | * [CHANGE] Rename `*_connections_total` to `*_sessions_total` following the changes in HAProxy 1.7 | |
30 | * [ENHANCEMENT] Add new `haproxy_server_connections_total` metric | |
31 | * [ENHANCEMENT] Add new `--haproxy.ssl-verify` flag | |
32 | * [BUGFIX] Convert latency metrics to correct unit. | |
33 | ||
34 | ## 0.8.0 / 2017-08-24 | |
35 | ||
36 | * [CHANGE] New flag handling (double dashs are required) | |
37 | * [FEATURE] Add metric for session limit. | |
38 | * [FEATURE] Add metrics for average HTTP request latency | |
39 | ||
40 | ## 0.7.1 / 2016-10-12 | |
41 | ||
42 | * [BUGFIX] Fix timeout behavior when reusing HTTP connections | |
43 | * [BUGFIX] Remove usage of undocumented golang type assertion behavior | |
44 | ||
45 | ## 0.7.0 / 2016-06-08 | |
46 | ||
47 | * [FEATURE] Add support for unix sockets | |
48 | ||
49 | ## 0.6.0 / 2016-05-13 | |
50 | ||
51 | * [CHANGE] Use new build process, changes the structure of the tarball. | |
52 | * [FIX] Abort on non-200 status code from HAProxy. | |
53 | * [ENHANCEMENT] Add -version flag and version metric. | |
54 | * [ENHANCEMENT] Add chkfail and downtime server metrics. | |
55 | * [ENHANCEMENT] Remove locks and unnecessary channel communication. | |
56 | ||
57 | ## 0.5.2 / 2016-04-05 | |
58 | ||
59 | * [FIX] Limit graceful CSV error handling to parse errors | |
60 | ||
61 | ## 0.5.1 / 2016-03-31 | |
62 | ||
63 | * [FIX] Handle invalid CSV lines gracefully | |
64 | ||
65 | ## 0.5.0 / 2015-12-23 | |
66 | ||
67 | * [CHANGE] New Dockerfile | |
68 | * [ENHANCEMENT] Export haproxy_check_duration_milliseconds | |
69 | * [ENHANCEMENT] Export haproxy_limit_sessions | |
70 | * [ENHANCEMENT] Export haproxy_limit_session_rate | |
71 | * [ENHANCEMENT] Allow complete deactivation of server metrics | |
72 | * [ENHANCEMENT] Use common prometheus logging | |
73 | * [FIX] Fix status field parsing of servers in MAINT status |
0 | ## Prometheus Community Code of Conduct | |
1 | ||
2 | Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). |
0 | ARG ARCH="amd64" | |
1 | ARG OS="linux" | |
0 | 2 | FROM quay.io/prometheus/busybox:latest |
1 | 3 | LABEL maintainer="The Prometheus Authors <prometheus-developers@googlegroups.com>" |
2 | 4 | |
3 | COPY haproxy_exporter /bin/haproxy_exporter | |
5 | ARG ARCH="amd64" | |
6 | ARG OS="linux" | |
7 | COPY .build/${OS}-${ARCH}/haproxy_exporter /bin/haproxy_exporter | |
4 | 8 | |
9 | USER nobody | |
5 | 10 | ENTRYPOINT ["/bin/haproxy_exporter"] |
6 | 11 | EXPOSE 9101 |
10 | 10 | # See the License for the specific language governing permissions and |
11 | 11 | # limitations under the License. |
12 | 12 | |
13 | # Needs to be defined before including Makefile.common to auto-generate targets | |
14 | DOCKER_ARCHS ?= amd64 armv7 arm64 | |
15 | DOCKER_IMAGE_NAME ?= haproxy-exporter | |
16 | ||
17 | all:: vet checkmetrics common-all | |
18 | ||
13 | 19 | include Makefile.common |
14 | 20 | |
15 | DOCKER_IMAGE_NAME ?= haproxy-exporter | |
21 | PROMTOOL_DOCKER_IMAGE ?= $(shell docker pull -q quay.io/prometheus/prometheus:latest || echo quay.io/prometheus/prometheus:latest) | |
22 | PROMTOOL ?= docker run -i --rm -w "$(PWD)" -v "$(PWD):$(PWD)" --entrypoint promtool $(PROMTOOL_DOCKER_IMAGE) | |
23 | ||
24 | .PHONY: checkmetrics | |
25 | checkmetrics: | |
26 | @echo ">> checking metrics for correctness" | |
27 | for file in test/*.metrics; do $(PROMTOOL) check metrics < $$file || exit 1; done |
15 | 15 | # !!! Open PRs only against the prometheus/prometheus/Makefile.common repository! |
16 | 16 | |
17 | 17 | # Example usage : |
18 | # Create the main Makefile in the root project directory. | |
18 | # Create the main Makefile in the root project directory. | |
19 | 19 | # include Makefile.common |
20 | 20 | # customTarget: |
21 | 21 | # @echo ">> Running customTarget" |
27 | 27 | GO ?= go |
28 | 28 | GOFMT ?= $(GO)fmt |
29 | 29 | FIRST_GOPATH := $(firstword $(subst :, ,$(shell $(GO) env GOPATH))) |
30 | GOOPTS ?= | |
31 | GOHOSTOS ?= $(shell $(GO) env GOHOSTOS) | |
32 | GOHOSTARCH ?= $(shell $(GO) env GOHOSTARCH) | |
33 | ||
34 | GO_VERSION ?= $(shell $(GO) version) | |
35 | GO_VERSION_NUMBER ?= $(word 3, $(GO_VERSION)) | |
36 | PRE_GO_111 ?= $(shell echo $(GO_VERSION_NUMBER) | grep -E 'go1\.(10|[0-9])\.') | |
37 | ||
38 | GOVENDOR := | |
39 | GO111MODULE := | |
40 | ifeq (, $(PRE_GO_111)) | |
41 | ifneq (,$(wildcard go.mod)) | |
42 | # Enforce Go modules support just in case the directory is inside GOPATH (and for Travis CI). | |
43 | GO111MODULE := on | |
44 | ||
45 | ifneq (,$(wildcard vendor)) | |
46 | # Always use the local vendor/ directory to satisfy the dependencies. | |
47 | GOOPTS := $(GOOPTS) -mod=vendor | |
48 | endif | |
49 | endif | |
50 | else | |
51 | ifneq (,$(wildcard go.mod)) | |
52 | ifneq (,$(wildcard vendor)) | |
53 | $(warning This repository requires Go >= 1.11 because of Go modules) | |
54 | $(warning Some recipes may not work as expected as the current Go runtime is '$(GO_VERSION_NUMBER)') | |
55 | endif | |
56 | else | |
57 | # This repository isn't using Go modules (yet). | |
58 | GOVENDOR := $(FIRST_GOPATH)/bin/govendor | |
59 | endif | |
60 | endif | |
30 | 61 | PROMU := $(FIRST_GOPATH)/bin/promu |
31 | STATICCHECK := $(FIRST_GOPATH)/bin/staticcheck | |
32 | GOVENDOR := $(FIRST_GOPATH)/bin/govendor | |
33 | 62 | pkgs = ./... |
63 | ||
64 | ifeq (arm, $(GOHOSTARCH)) | |
65 | GOHOSTARM ?= $(shell GOARM= $(GO) env GOARM) | |
66 | GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH)v$(GOHOSTARM) | |
67 | else | |
68 | GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH) | |
69 | endif | |
70 | ||
71 | GOTEST := $(GO) test | |
72 | GOTEST_DIR := | |
73 | ifneq ($(CIRCLE_JOB),) | |
74 | ifneq ($(shell which gotestsum),) | |
75 | GOTEST_DIR := test-results | |
76 | GOTEST := gotestsum --junitfile $(GOTEST_DIR)/unit-tests.xml -- | |
77 | endif | |
78 | endif | |
79 | ||
80 | PROMU_VERSION ?= 0.7.0 | |
81 | PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz | |
82 | ||
83 | GOLANGCI_LINT := | |
84 | GOLANGCI_LINT_OPTS ?= | |
85 | GOLANGCI_LINT_VERSION ?= v1.18.0 | |
86 | # golangci-lint only supports linux, darwin and windows platforms on i386/amd64. | |
87 | # windows isn't included here because of the path separator being different. | |
88 | ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin)) | |
89 | ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386)) | |
90 | GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint | |
91 | endif | |
92 | endif | |
34 | 93 | |
35 | 94 | PREFIX ?= $(shell pwd) |
36 | 95 | BIN_DIR ?= $(shell pwd) |
37 | 96 | DOCKER_IMAGE_TAG ?= $(subst /,-,$(shell git rev-parse --abbrev-ref HEAD)) |
38 | ||
39 | .PHONY: all | |
40 | all: style staticcheck unused build test | |
41 | ||
42 | .PHONY: style | |
43 | style: | |
97 | DOCKERFILE_PATH ?= ./Dockerfile | |
98 | DOCKERBUILD_CONTEXT ?= ./ | |
99 | DOCKER_REPO ?= prom | |
100 | ||
101 | DOCKER_ARCHS ?= amd64 | |
102 | ||
103 | BUILD_DOCKER_ARCHS = $(addprefix common-docker-,$(DOCKER_ARCHS)) | |
104 | PUBLISH_DOCKER_ARCHS = $(addprefix common-docker-publish-,$(DOCKER_ARCHS)) | |
105 | TAG_DOCKER_ARCHS = $(addprefix common-docker-tag-latest-,$(DOCKER_ARCHS)) | |
106 | ||
107 | ifeq ($(GOHOSTARCH),amd64) | |
108 | ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux freebsd darwin windows)) | |
109 | # Only supported on amd64 | |
110 | test-flags := -race | |
111 | endif | |
112 | endif | |
113 | ||
114 | # This rule is used to forward a target like "build" to "common-build". This | |
115 | # allows a new "build" target to be defined in a Makefile which includes this | |
116 | # one and override "common-build" without override warnings. | |
117 | %: common-% ; | |
118 | ||
119 | .PHONY: common-all | |
120 | common-all: precheck style check_license lint unused build test | |
121 | ||
122 | .PHONY: common-style | |
123 | common-style: | |
44 | 124 | @echo ">> checking code style" |
45 | ! $(GOFMT) -d $$(find . -path ./vendor -prune -o -name '*.go' -print) | grep '^' | |
46 | ||
47 | .PHONY: check_license | |
48 | check_license: | |
125 | @fmtRes=$$($(GOFMT) -d $$(find . -path ./vendor -prune -o -name '*.go' -print)); \ | |
126 | if [ -n "$${fmtRes}" ]; then \ | |
127 | echo "gofmt checking failed!"; echo "$${fmtRes}"; echo; \ | |
128 | echo "Please ensure you are using $$($(GO) version) for formatting code."; \ | |
129 | exit 1; \ | |
130 | fi | |
131 | ||
132 | .PHONY: common-check_license | |
133 | common-check_license: | |
49 | 134 | @echo ">> checking license header" |
50 | 135 | @licRes=$$(for file in $$(find . -type f -iname '*.go' ! -path './vendor/*') ; do \ |
51 | 136 | awk 'NR<=3' $$file | grep -Eq "(Copyright|generated|GENERATED)" || echo $$file; \ |
55 | 140 | exit 1; \ |
56 | 141 | fi |
57 | 142 | |
58 | .PHONY: test-short | |
59 | test-short: | |
143 | .PHONY: common-deps | |
144 | common-deps: | |
145 | @echo ">> getting dependencies" | |
146 | ifdef GO111MODULE | |
147 | GO111MODULE=$(GO111MODULE) $(GO) mod download | |
148 | else | |
149 | $(GO) get $(GOOPTS) -t ./... | |
150 | endif | |
151 | ||
152 | .PHONY: update-go-deps | |
153 | update-go-deps: | |
154 | @echo ">> updating Go dependencies" | |
155 | @for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \ | |
156 | $(GO) get $$m; \ | |
157 | done | |
158 | GO111MODULE=$(GO111MODULE) $(GO) mod tidy | |
159 | ifneq (,$(wildcard vendor)) | |
160 | GO111MODULE=$(GO111MODULE) $(GO) mod vendor | |
161 | endif | |
162 | ||
163 | .PHONY: common-test-short | |
164 | common-test-short: $(GOTEST_DIR) | |
60 | 165 | @echo ">> running short tests" |
61 | $(GO) test -short $(pkgs) | |
62 | ||
63 | .PHONY: test | |
64 | test: | |
166 | GO111MODULE=$(GO111MODULE) $(GOTEST) -short $(GOOPTS) $(pkgs) | |
167 | ||
168 | .PHONY: common-test | |
169 | common-test: $(GOTEST_DIR) | |
65 | 170 | @echo ">> running all tests" |
66 | $(GO) test -race $(pkgs) | |
67 | ||
68 | .PHONY: format | |
69 | format: | |
171 | GO111MODULE=$(GO111MODULE) $(GOTEST) $(test-flags) $(GOOPTS) $(pkgs) | |
172 | ||
173 | $(GOTEST_DIR): | |
174 | @mkdir -p $@ | |
175 | ||
176 | .PHONY: common-format | |
177 | common-format: | |
70 | 178 | @echo ">> formatting code" |
71 | $(GO) fmt $(pkgs) | |
72 | ||
73 | .PHONY: vet | |
74 | vet: | |
179 | GO111MODULE=$(GO111MODULE) $(GO) fmt $(pkgs) | |
180 | ||
181 | .PHONY: common-vet | |
182 | common-vet: | |
75 | 183 | @echo ">> vetting code" |
76 | $(GO) vet $(pkgs) | |
77 | ||
78 | .PHONY: staticcheck | |
79 | staticcheck: $(STATICCHECK) | |
80 | @echo ">> running staticcheck" | |
81 | $(STATICCHECK) -ignore "$(STATICCHECK_IGNORE)" $(pkgs) | |
82 | ||
83 | .PHONY: unused | |
84 | unused: $(GOVENDOR) | |
184 | GO111MODULE=$(GO111MODULE) $(GO) vet $(GOOPTS) $(pkgs) | |
185 | ||
186 | .PHONY: common-lint | |
187 | common-lint: $(GOLANGCI_LINT) | |
188 | ifdef GOLANGCI_LINT | |
189 | @echo ">> running golangci-lint" | |
190 | ifdef GO111MODULE | |
191 | # 'go list' needs to be executed before staticcheck to prepopulate the modules cache. | |
192 | # Otherwise staticcheck might fail randomly for some reason not yet explained. | |
193 | GO111MODULE=$(GO111MODULE) $(GO) list -e -compiled -test=true -export=false -deps=true -find=false -tags= -- ./... > /dev/null | |
194 | GO111MODULE=$(GO111MODULE) $(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs) | |
195 | else | |
196 | $(GOLANGCI_LINT) run $(pkgs) | |
197 | endif | |
198 | endif | |
199 | ||
200 | # For backward-compatibility. | |
201 | .PHONY: common-staticcheck | |
202 | common-staticcheck: lint | |
203 | ||
204 | .PHONY: common-unused | |
205 | common-unused: $(GOVENDOR) | |
206 | ifdef GOVENDOR | |
85 | 207 | @echo ">> running check for unused packages" |
86 | 208 | @$(GOVENDOR) list +unused | grep . && exit 1 || echo 'No unused packages' |
87 | ||
88 | .PHONY: build | |
89 | build: promu | |
209 | else | |
210 | ifdef GO111MODULE | |
211 | @echo ">> running check for unused/missing packages in go.mod" | |
212 | GO111MODULE=$(GO111MODULE) $(GO) mod tidy | |
213 | ifeq (,$(wildcard vendor)) | |
214 | @git diff --exit-code -- go.sum go.mod | |
215 | else | |
216 | @echo ">> running check for unused packages in vendor/" | |
217 | GO111MODULE=$(GO111MODULE) $(GO) mod vendor | |
218 | @git diff --exit-code -- go.sum go.mod vendor/ | |
219 | endif | |
220 | endif | |
221 | endif | |
222 | ||
223 | .PHONY: common-build | |
224 | common-build: promu | |
90 | 225 | @echo ">> building binaries" |
91 | $(PROMU) build --prefix $(PREFIX) | |
92 | ||
93 | .PHONY: tarball | |
94 | tarball: promu | |
226 | GO111MODULE=$(GO111MODULE) $(PROMU) build --prefix $(PREFIX) $(PROMU_BINARIES) | |
227 | ||
228 | .PHONY: common-tarball | |
229 | common-tarball: promu | |
95 | 230 | @echo ">> building release tarball" |
96 | 231 | $(PROMU) tarball --prefix $(PREFIX) $(BIN_DIR) |
97 | 232 | |
98 | .PHONY: docker | |
99 | docker: | |
100 | docker build -t "$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)" . | |
233 | .PHONY: common-docker $(BUILD_DOCKER_ARCHS) | |
234 | common-docker: $(BUILD_DOCKER_ARCHS) | |
235 | $(BUILD_DOCKER_ARCHS): common-docker-%: | |
236 | docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" \ | |
237 | -f $(DOCKERFILE_PATH) \ | |
238 | --build-arg ARCH="$*" \ | |
239 | --build-arg OS="linux" \ | |
240 | $(DOCKERBUILD_CONTEXT) | |
241 | ||
242 | .PHONY: common-docker-publish $(PUBLISH_DOCKER_ARCHS) | |
243 | common-docker-publish: $(PUBLISH_DOCKER_ARCHS) | |
244 | $(PUBLISH_DOCKER_ARCHS): common-docker-publish-%: | |
245 | docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" | |
246 | ||
247 | DOCKER_MAJOR_VERSION_TAG = $(firstword $(subst ., ,$(shell cat VERSION))) | |
248 | .PHONY: common-docker-tag-latest $(TAG_DOCKER_ARCHS) | |
249 | common-docker-tag-latest: $(TAG_DOCKER_ARCHS) | |
250 | $(TAG_DOCKER_ARCHS): common-docker-tag-latest-%: | |
251 | docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest" | |
252 | docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)" | |
253 | ||
254 | .PHONY: common-docker-manifest | |
255 | common-docker-manifest: | |
256 | DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)" $(foreach ARCH,$(DOCKER_ARCHS),$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$(ARCH):$(DOCKER_IMAGE_TAG)) | |
257 | DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)" | |
101 | 258 | |
102 | 259 | .PHONY: promu |
103 | promu: | |
104 | GOOS= GOARCH= $(GO) get -u github.com/prometheus/promu | |
105 | ||
106 | .PHONY: $(STATICCHECK) | |
107 | $(STATICCHECK): | |
108 | GOOS= GOARCH= $(GO) get -u honnef.co/go/tools/cmd/staticcheck | |
109 | ||
260 | promu: $(PROMU) | |
261 | ||
262 | $(PROMU): | |
263 | $(eval PROMU_TMP := $(shell mktemp -d)) | |
264 | curl -s -L $(PROMU_URL) | tar -xvzf - -C $(PROMU_TMP) | |
265 | mkdir -p $(FIRST_GOPATH)/bin | |
266 | cp $(PROMU_TMP)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM)/promu $(FIRST_GOPATH)/bin/promu | |
267 | rm -r $(PROMU_TMP) | |
268 | ||
269 | .PHONY: proto | |
270 | proto: | |
271 | @echo ">> generating code from proto files" | |
272 | @./scripts/genproto.sh | |
273 | ||
274 | ifdef GOLANGCI_LINT | |
275 | $(GOLANGCI_LINT): | |
276 | mkdir -p $(FIRST_GOPATH)/bin | |
277 | curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/$(GOLANGCI_LINT_VERSION)/install.sh \ | |
278 | | sed -e '/install -d/d' \ | |
279 | | sh -s -- -b $(FIRST_GOPATH)/bin $(GOLANGCI_LINT_VERSION) | |
280 | endif | |
281 | ||
282 | ifdef GOVENDOR | |
110 | 283 | .PHONY: $(GOVENDOR) |
111 | 284 | $(GOVENDOR): |
112 | 285 | GOOS= GOARCH= $(GO) get -u github.com/kardianos/govendor |
286 | endif | |
287 | ||
288 | .PHONY: precheck | |
289 | precheck:: | |
290 | ||
291 | define PRECHECK_COMMAND_template = | |
292 | precheck:: $(1)_precheck | |
293 | ||
294 | PRECHECK_COMMAND_$(1) ?= $(1) $$(strip $$(PRECHECK_OPTIONS_$(1))) | |
295 | .PHONY: $(1)_precheck | |
296 | $(1)_precheck: | |
297 | @if ! $$(PRECHECK_COMMAND_$(1)) 1>/dev/null 2>&1; then \ | |
298 | echo "Execution of '$$(PRECHECK_COMMAND_$(1))' command failed. Is $(1) installed?"; \ | |
299 | exit 1; \ | |
300 | fi | |
301 | endef |
1 | 1 | |
2 | 2 | This is a simple server that scrapes HAProxy stats and exports them via HTTP for |
3 | 3 | Prometheus consumption. |
4 | ||
5 | ***Note:** since HAProxy 2.0.0, the official source includes a Prometheus exporter module that can be built into your binary with a single flag during build time and offers an exporter-free Prometheus endpoint. More information [down below](#official-prometheus-exporter).* | |
4 | 6 | |
5 | 7 | ## Getting Started |
6 | 8 | |
49 | 51 | ``` |
50 | 52 | |
51 | 53 | You can also scrape HTTPS URLs. Certificate validation is enabled by default, but |
52 | you can disable it using the `--haproxy.ssl-verify=false` flag: | |
54 | you can disable it using the `--no-haproxy.ssl-verify` flag: | |
53 | 55 | |
54 | 56 | ```bash |
55 | 57 | haproxy_exporter --no-haproxy.ssl-verify --haproxy.scrape-uri="https://haproxy.example.com/haproxy?stats;csv" |
80 | 82 | To run the haproxy exporter as a Docker container, run: |
81 | 83 | |
82 | 84 | ```bash |
83 | docker run -p 9101:9101 quay.io/prometheus/haproxy-exporter:v0.9.0 --haproxy.scrape-uri="http://user:pass@haproxy.example.com/haproxy?stats;csv" | |
85 | docker run -p 9101:9101 quay.io/prometheus/haproxy-exporter:v0.12.0 --haproxy.scrape-uri="http://user:pass@haproxy.example.com/haproxy?stats;csv" | |
84 | 86 | ``` |
85 | 87 | |
86 | 88 | [hub]: https://hub.docker.com/r/prom/haproxy-exporter/ |
115 | 117 | ## License |
116 | 118 | |
117 | 119 | Apache License 2.0, see [LICENSE](https://github.com/prometheus/haproxy_exporter/blob/master/LICENSE). |
120 | ||
121 | ## Alternatives | |
122 | ||
123 | ### Official Prometheus exporter | |
124 | ||
125 | As of 2.0.0, HAProxy includes a Prometheus exporter module that can be built into your binary during build time. | |
126 | ||
127 | To build with the official Prometheus exporter module, `make` with the following `EXTRA_OBJS` flag: | |
128 | ||
129 | ```bash | |
130 | make TARGET=linux-glibc EXTRA_OBJS="contrib/prometheus-exporter/service-prometheus.o" | |
131 | ``` | |
132 | ||
133 | Once built, you can enable and configure the Prometheus endpoint from your `haproxy.cfg` file as a typical frontend: | |
134 | ||
135 | ```haproxy | |
136 | frontend stats | |
137 | bind *:8404 | |
138 | http-request use-service prometheus-exporter if { path /metrics } | |
139 | stats enable | |
140 | stats uri /stats | |
141 | stats refresh 10s | |
142 | ``` | |
143 | ||
144 | For more information, see [this official blog post](https://www.haproxy.com/blog/haproxy-exposes-a-prometheus-metrics-endpoint/). |
0 | module github.com/prometheus/haproxy_exporter | |
1 | ||
2 | go 1.14 | |
3 | ||
4 | require ( | |
5 | github.com/alecthomas/units v0.0.0-20201120081800-1786d5ef83d4 // indirect | |
6 | github.com/go-kit/kit v0.10.0 | |
7 | github.com/prometheus/client_golang v1.8.0 | |
8 | github.com/prometheus/common v0.15.0 | |
9 | golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d // indirect | |
10 | google.golang.org/protobuf v1.25.0 // indirect | |
11 | gopkg.in/alecthomas/kingpin.v2 v2.2.6 | |
12 | ) |
0 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= | |
1 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= | |
2 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | |
3 | github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= | |
4 | github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= | |
5 | github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= | |
6 | github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= | |
7 | github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= | |
8 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= | |
9 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= | |
10 | github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= | |
11 | github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= | |
12 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= | |
13 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= | |
14 | github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E= | |
15 | github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= | |
16 | github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= | |
17 | github.com/alecthomas/units v0.0.0-20201120081800-1786d5ef83d4 h1:EBTWhcAX7rNQ80RLwLCpHZBBrJuzallFHnF+yMXo928= | |
18 | github.com/alecthomas/units v0.0.0-20201120081800-1786d5ef83d4/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= | |
19 | github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= | |
20 | github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= | |
21 | github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= | |
22 | github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= | |
23 | github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= | |
24 | github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= | |
25 | github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= | |
26 | github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= | |
27 | github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= | |
28 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= | |
29 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= | |
30 | github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= | |
31 | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= | |
32 | github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= | |
33 | github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= | |
34 | github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= | |
35 | github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= | |
36 | github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= | |
37 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= | |
38 | github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= | |
39 | github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= | |
40 | github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= | |
41 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= | |
42 | github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= | |
43 | github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= | |
44 | github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= | |
45 | github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= | |
46 | github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= | |
47 | github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= | |
48 | github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= | |
49 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | |
50 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | |
51 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | |
52 | github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= | |
53 | github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= | |
54 | github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= | |
55 | github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= | |
56 | github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= | |
57 | github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= | |
58 | github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= | |
59 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= | |
60 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= | |
61 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= | |
62 | github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= | |
63 | github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= | |
64 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= | |
65 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= | |
66 | github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= | |
67 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= | |
68 | github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= | |
69 | github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= | |
70 | github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= | |
71 | github.com/go-logfmt/logfmt v0.3.0 h1:8HUsc87TaSWLKwrnumgC8/YconD2fJQsRJAsWaPg2ic= | |
72 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= | |
73 | github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= | |
74 | github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= | |
75 | github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= | |
76 | github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= | |
77 | github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= | |
78 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= | |
79 | github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= | |
80 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= | |
81 | github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= | |
82 | github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= | |
83 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= | |
84 | github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= | |
85 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= | |
86 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= | |
87 | github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= | |
88 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | |
89 | github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= | |
90 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | |
91 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | |
92 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= | |
93 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= | |
94 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= | |
95 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= | |
96 | github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ= | |
97 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= | |
98 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= | |
99 | github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= | |
100 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= | |
101 | github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= | |
102 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= | |
103 | github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= | |
104 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | |
105 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | |
106 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= | |
107 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | |
108 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | |
109 | github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= | |
110 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | |
111 | github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= | |
112 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | |
113 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | |
114 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= | |
115 | github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | |
116 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= | |
117 | github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= | |
118 | github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= | |
119 | github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= | |
120 | github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= | |
121 | github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= | |
122 | github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= | |
123 | github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= | |
124 | github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= | |
125 | github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= | |
126 | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= | |
127 | github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= | |
128 | github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= | |
129 | github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= | |
130 | github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= | |
131 | github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= | |
132 | github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= | |
133 | github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= | |
134 | github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | |
135 | github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | |
136 | github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | |
137 | github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= | |
138 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | |
139 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | |
140 | github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= | |
141 | github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= | |
142 | github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= | |
143 | github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= | |
144 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= | |
145 | github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= | |
146 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= | |
147 | github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= | |
148 | github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= | |
149 | github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= | |
150 | github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= | |
151 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= | |
152 | github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | |
153 | github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | |
154 | github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | |
155 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= | |
156 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= | |
157 | github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= | |
158 | github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= | |
159 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= | |
160 | github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= | |
161 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | |
162 | github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | |
163 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= | |
164 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= | |
165 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= | |
166 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= | |
167 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | |
168 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= | |
169 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | |
170 | github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= | |
171 | github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= | |
172 | github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= | |
173 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= | |
174 | github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= | |
175 | github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= | |
176 | github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= | |
177 | github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= | |
178 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= | |
179 | github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= | |
180 | github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= | |
181 | github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= | |
182 | github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= | |
183 | github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= | |
184 | github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= | |
185 | github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= | |
186 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= | |
187 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | |
188 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | |
189 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | |
190 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | |
191 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= | |
192 | github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= | |
193 | github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= | |
194 | github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= | |
195 | github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= | |
196 | github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= | |
197 | github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= | |
198 | github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= | |
199 | github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= | |
200 | github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= | |
201 | github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= | |
202 | github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= | |
203 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= | |
204 | github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= | |
205 | github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= | |
206 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= | |
207 | github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= | |
208 | github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= | |
209 | github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= | |
210 | github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= | |
211 | github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= | |
212 | github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= | |
213 | github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= | |
214 | github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= | |
215 | github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= | |
216 | github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= | |
217 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= | |
218 | github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= | |
219 | github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= | |
220 | github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= | |
221 | github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= | |
222 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | |
223 | github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= | |
224 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | |
225 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= | |
226 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | |
227 | github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= | |
228 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | |
229 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | |
230 | github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= | |
231 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= | |
232 | github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= | |
233 | github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM= | |
234 | github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= | |
235 | github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= | |
236 | github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= | |
237 | github.com/prometheus/client_golang v1.8.0 h1:zvJNkoCFAnYFNC24FV8nW4JdRJ3GIFcLbg65lL/JDcw= | |
238 | github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM= | |
239 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8= | |
240 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= | |
241 | github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= | |
242 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= | |
243 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | |
244 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | |
245 | github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | |
246 | github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= | |
247 | github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | |
248 | github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= | |
249 | github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= | |
250 | github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= | |
251 | github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= | |
252 | github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= | |
253 | github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= | |
254 | github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= | |
255 | github.com/prometheus/common v0.15.0 h1:4fgOnadei3EZvgRwxJ7RMpG1k1pOZth5Pc13tyspaKM= | |
256 | github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= | |
257 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= | |
258 | github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= | |
259 | github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= | |
260 | github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= | |
261 | github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= | |
262 | github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8= | |
263 | github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= | |
264 | github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4= | |
265 | github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= | |
266 | github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= | |
267 | github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= | |
268 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= | |
269 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | |
270 | github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= | |
271 | github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= | |
272 | github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= | |
273 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= | |
274 | github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= | |
275 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= | |
276 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= | |
277 | github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= | |
278 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= | |
279 | github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= | |
280 | github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= | |
281 | github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= | |
282 | github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= | |
283 | github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | |
284 | github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= | |
285 | github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= | |
286 | github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= | |
287 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | |
288 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | |
289 | github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= | |
290 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | |
291 | github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= | |
292 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | |
293 | github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= | |
294 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | |
295 | github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= | |
296 | github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= | |
297 | github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= | |
298 | github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= | |
299 | go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= | |
300 | go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= | |
301 | go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= | |
302 | go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= | |
303 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= | |
304 | go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= | |
305 | go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= | |
306 | go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= | |
307 | go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= | |
308 | go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= | |
309 | go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= | |
310 | go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= | |
311 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I= | |
312 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | |
313 | golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | |
314 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | |
315 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | |
316 | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | |
317 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | |
318 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | |
319 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= | |
320 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | |
321 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= | |
322 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | |
323 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= | |
324 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= | |
325 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= | |
326 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= | |
327 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | |
328 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | |
329 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | |
330 | golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | |
331 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | |
332 | golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | |
333 | golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | |
334 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | |
335 | golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | |
336 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | |
337 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | |
338 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | |
339 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= | |
340 | golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | |
341 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | |
342 | golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | |
343 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= | |
344 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= | |
345 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | |
346 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | |
347 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ= | |
348 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | |
349 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | |
350 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | |
351 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | |
352 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | |
353 | golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | |
354 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | |
355 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | |
356 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | |
357 | golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | |
358 | golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | |
359 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5 h1:mzjBh+S5frKOsOBobWIMAbXavqjmgO17k/2puhcFR94= | |
360 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | |
361 | golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | |
362 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | |
363 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |
364 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |
365 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |
366 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |
367 | golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |
368 | golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |
369 | golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |
370 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |
371 | golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= | |
372 | golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |
373 | golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |
374 | golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |
375 | golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d h1:MiWWjyhUzZ+jvhZvloX6ZrUsdEghn8a64Upd8EMHglE= | |
376 | golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |
377 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | |
378 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | |
379 | golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | |
380 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | |
381 | golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | |
382 | golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | |
383 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | |
384 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | |
385 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= | |
386 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | |
387 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | |
388 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | |
389 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= | |
390 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= | |
391 | golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | |
392 | golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | |
393 | golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= | |
394 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | |
395 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | |
396 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= | |
397 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | |
398 | google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= | |
399 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= | |
400 | google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= | |
401 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= | |
402 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= | |
403 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= | |
404 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= | |
405 | google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= | |
406 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= | |
407 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= | |
408 | google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= | |
409 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= | |
410 | google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= | |
411 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= | |
412 | google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= | |
413 | google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= | |
414 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= | |
415 | google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= | |
416 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= | |
417 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= | |
418 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= | |
419 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= | |
420 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= | |
421 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= | |
422 | google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw= | |
423 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= | |
424 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= | |
425 | google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= | |
426 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= | |
427 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= | |
428 | google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= | |
429 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= | |
430 | gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= | |
431 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= | |
432 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | |
433 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | |
434 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= | |
435 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | |
436 | gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= | |
437 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= | |
438 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= | |
439 | gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= | |
440 | gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= | |
441 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= | |
442 | gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= | |
443 | gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= | |
444 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | |
445 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | |
446 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | |
447 | gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c= | |
448 | gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | |
449 | gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= | |
450 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | |
451 | honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | |
452 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | |
453 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | |
454 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= | |
455 | sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= | |
456 | sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= |
13 | 13 | package main |
14 | 14 | |
15 | 15 | import ( |
16 | "bufio" | |
16 | 17 | "crypto/tls" |
17 | 18 | "encoding/csv" |
18 | 19 | "errors" |
23 | 24 | "net/http" |
24 | 25 | _ "net/http/pprof" |
25 | 26 | "net/url" |
27 | "os" | |
26 | 28 | "sort" |
27 | 29 | "strconv" |
28 | 30 | "strings" |
29 | 31 | "sync" |
30 | 32 | "time" |
31 | 33 | |
34 | "github.com/go-kit/kit/log" | |
35 | "github.com/go-kit/kit/log/level" | |
32 | 36 | "github.com/prometheus/client_golang/prometheus" |
33 | 37 | "github.com/prometheus/client_golang/prometheus/promhttp" |
34 | "github.com/prometheus/common/log" | |
38 | "github.com/prometheus/common/promlog" | |
39 | "github.com/prometheus/common/promlog/flag" | |
35 | 40 | "github.com/prometheus/common/version" |
36 | 41 | "gopkg.in/alecthomas/kingpin.v2" |
37 | 42 | ) |
48 | 53 | // HAProxy 1.7 |
49 | 54 | // pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,comp_in,comp_out,comp_byp,comp_rsp,lastsess,last_chk,last_agt,qtime,ctime,rtime,ttime,agent_status,agent_code,agent_duration,check_desc,agent_desc,check_rise,check_fall,check_health,agent_rise,agent_fall,agent_health,addr,cookie,mode,algo,conn_rate,conn_rate_max,conn_tot,intercepted,dcon,dses |
50 | 55 | minimumCsvFieldCount = 33 |
51 | statusField = 17 | |
52 | qtimeMsField = 58 | |
53 | ctimeMsField = 59 | |
54 | rtimeMsField = 60 | |
55 | ttimeMsField = 61 | |
56 | ||
57 | pxnameField = 0 | |
58 | svnameField = 1 | |
59 | statusField = 17 | |
60 | typeField = 32 | |
61 | checkDurationField = 38 | |
62 | qtimeMsField = 58 | |
63 | ctimeMsField = 59 | |
64 | rtimeMsField = 60 | |
65 | ttimeMsField = 61 | |
66 | ||
67 | excludedServerStates = "" | |
68 | showStatCmd = "show stat\n" | |
69 | showInfoCmd = "show info\n" | |
56 | 70 | ) |
57 | 71 | |
58 | 72 | var ( |
61 | 75 | serverLabelNames = []string{"backend", "server"} |
62 | 76 | ) |
63 | 77 | |
64 | func newFrontendMetric(metricName string, docString string, constLabels prometheus.Labels) *prometheus.GaugeVec { | |
65 | return prometheus.NewGaugeVec( | |
66 | prometheus.GaugeOpts{ | |
67 | Namespace: namespace, | |
68 | Name: "frontend_" + metricName, | |
69 | Help: docString, | |
70 | ConstLabels: constLabels, | |
71 | }, | |
72 | frontendLabelNames, | |
73 | ) | |
74 | } | |
75 | ||
76 | func newBackendMetric(metricName string, docString string, constLabels prometheus.Labels) *prometheus.GaugeVec { | |
77 | return prometheus.NewGaugeVec( | |
78 | prometheus.GaugeOpts{ | |
79 | Namespace: namespace, | |
80 | Name: "backend_" + metricName, | |
81 | Help: docString, | |
82 | ConstLabels: constLabels, | |
83 | }, | |
84 | backendLabelNames, | |
85 | ) | |
86 | } | |
87 | ||
88 | func newServerMetric(metricName string, docString string, constLabels prometheus.Labels) *prometheus.GaugeVec { | |
89 | return prometheus.NewGaugeVec( | |
90 | prometheus.GaugeOpts{ | |
91 | Namespace: namespace, | |
92 | Name: "server_" + metricName, | |
93 | Help: docString, | |
94 | ConstLabels: constLabels, | |
95 | }, | |
96 | serverLabelNames, | |
97 | ) | |
98 | } | |
99 | ||
100 | type metrics map[int]*prometheus.GaugeVec | |
78 | type metricInfo struct { | |
79 | Desc *prometheus.Desc | |
80 | Type prometheus.ValueType | |
81 | } | |
82 | ||
83 | func newFrontendMetric(metricName string, docString string, t prometheus.ValueType, constLabels prometheus.Labels) metricInfo { | |
84 | return metricInfo{ | |
85 | Desc: prometheus.NewDesc( | |
86 | prometheus.BuildFQName(namespace, "frontend", metricName), | |
87 | docString, | |
88 | frontendLabelNames, | |
89 | constLabels, | |
90 | ), | |
91 | Type: t, | |
92 | } | |
93 | } | |
94 | ||
95 | func newBackendMetric(metricName string, docString string, t prometheus.ValueType, constLabels prometheus.Labels) metricInfo { | |
96 | return metricInfo{ | |
97 | Desc: prometheus.NewDesc( | |
98 | prometheus.BuildFQName(namespace, "backend", metricName), | |
99 | docString, | |
100 | backendLabelNames, | |
101 | constLabels, | |
102 | ), | |
103 | Type: t, | |
104 | } | |
105 | } | |
106 | ||
107 | func newServerMetric(metricName string, docString string, t prometheus.ValueType, constLabels prometheus.Labels) metricInfo { | |
108 | return metricInfo{ | |
109 | Desc: prometheus.NewDesc( | |
110 | prometheus.BuildFQName(namespace, "server", metricName), | |
111 | docString, | |
112 | serverLabelNames, | |
113 | constLabels, | |
114 | ), | |
115 | Type: t, | |
116 | } | |
117 | } | |
118 | ||
119 | type metrics map[int]metricInfo | |
101 | 120 | |
102 | 121 | func (m metrics) String() string { |
103 | 122 | keys := make([]int, 0, len(m)) |
114 | 133 | |
115 | 134 | var ( |
116 | 135 | serverMetrics = metrics{ |
117 | 2: newServerMetric("current_queue", "Current number of queued requests assigned to this server.", nil), | |
118 | 3: newServerMetric("max_queue", "Maximum observed number of queued requests assigned to this server.", nil), | |
119 | 4: newServerMetric("current_sessions", "Current number of active sessions.", nil), | |
120 | 5: newServerMetric("max_sessions", "Maximum observed number of active sessions.", nil), | |
121 | 6: newServerMetric("limit_sessions", "Configured session limit.", nil), | |
122 | 7: newServerMetric("sessions_total", "Total number of sessions.", nil), | |
123 | 8: newServerMetric("bytes_in_total", "Current total of incoming bytes.", nil), | |
124 | 9: newServerMetric("bytes_out_total", "Current total of outgoing bytes.", nil), | |
125 | 13: newServerMetric("connection_errors_total", "Total of connection errors.", nil), | |
126 | 14: newServerMetric("response_errors_total", "Total of response errors.", nil), | |
127 | 15: newServerMetric("retry_warnings_total", "Total of retry warnings.", nil), | |
128 | 16: newServerMetric("redispatch_warnings_total", "Total of redispatch warnings.", nil), | |
129 | 17: newServerMetric("up", "Current health status of the server (1 = UP, 0 = DOWN).", nil), | |
130 | 18: newServerMetric("weight", "Current weight of the server.", nil), | |
131 | 21: newServerMetric("check_failures_total", "Total number of failed health checks.", nil), | |
132 | 24: newServerMetric("downtime_seconds_total", "Total downtime in seconds.", nil), | |
133 | 33: newServerMetric("current_session_rate", "Current number of sessions per second over last elapsed second.", nil), | |
134 | 35: newServerMetric("max_session_rate", "Maximum observed number of sessions per second.", nil), | |
135 | 38: newServerMetric("check_duration_milliseconds", "Previously run health check duration, in milliseconds", nil), | |
136 | 39: newServerMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "1xx"}), | |
137 | 40: newServerMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "2xx"}), | |
138 | 41: newServerMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "3xx"}), | |
139 | 42: newServerMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "4xx"}), | |
140 | 43: newServerMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "5xx"}), | |
141 | 44: newServerMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "other"}), | |
142 | } | |
136 | 2: newServerMetric("current_queue", "Current number of queued requests assigned to this server.", prometheus.GaugeValue, nil), | |
137 | 3: newServerMetric("max_queue", "Maximum observed number of queued requests assigned to this server.", prometheus.GaugeValue, nil), | |
138 | 4: newServerMetric("current_sessions", "Current number of active sessions.", prometheus.GaugeValue, nil), | |
139 | 5: newServerMetric("max_sessions", "Maximum observed number of active sessions.", prometheus.GaugeValue, nil), | |
140 | 6: newServerMetric("limit_sessions", "Configured session limit.", prometheus.GaugeValue, nil), | |
141 | 7: newServerMetric("sessions_total", "Total number of sessions.", prometheus.CounterValue, nil), | |
142 | 8: newServerMetric("bytes_in_total", "Current total of incoming bytes.", prometheus.CounterValue, nil), | |
143 | 9: newServerMetric("bytes_out_total", "Current total of outgoing bytes.", prometheus.CounterValue, nil), | |
144 | 13: newServerMetric("connection_errors_total", "Total of connection errors.", prometheus.CounterValue, nil), | |
145 | 14: newServerMetric("response_errors_total", "Total of response errors.", prometheus.CounterValue, nil), | |
146 | 15: newServerMetric("retry_warnings_total", "Total of retry warnings.", prometheus.CounterValue, nil), | |
147 | 16: newServerMetric("redispatch_warnings_total", "Total of redispatch warnings.", prometheus.CounterValue, nil), | |
148 | 17: newServerMetric("up", "Current health status of the server (1 = UP, 0 = DOWN).", prometheus.GaugeValue, nil), | |
149 | 18: newServerMetric("weight", "Current weight of the server.", prometheus.GaugeValue, nil), | |
150 | 21: newServerMetric("check_failures_total", "Total number of failed health checks.", prometheus.CounterValue, nil), | |
151 | 24: newServerMetric("downtime_seconds_total", "Total downtime in seconds.", prometheus.CounterValue, nil), | |
152 | 30: newServerMetric("server_selected_total", "Total number of times a server was selected, either for new sessions, or when re-dispatching.", prometheus.CounterValue, nil), | |
153 | 33: newServerMetric("current_session_rate", "Current number of sessions per second over last elapsed second.", prometheus.GaugeValue, nil), | |
154 | 35: newServerMetric("max_session_rate", "Maximum observed number of sessions per second.", prometheus.GaugeValue, nil), | |
155 | 38: newServerMetric("check_duration_seconds", "Previously run health check duration, in seconds", prometheus.GaugeValue, nil), | |
156 | 39: newServerMetric("http_responses_total", "Total of HTTP responses.", prometheus.CounterValue, prometheus.Labels{"code": "1xx"}), | |
157 | 40: newServerMetric("http_responses_total", "Total of HTTP responses.", prometheus.CounterValue, prometheus.Labels{"code": "2xx"}), | |
158 | 41: newServerMetric("http_responses_total", "Total of HTTP responses.", prometheus.CounterValue, prometheus.Labels{"code": "3xx"}), | |
159 | 42: newServerMetric("http_responses_total", "Total of HTTP responses.", prometheus.CounterValue, prometheus.Labels{"code": "4xx"}), | |
160 | 43: newServerMetric("http_responses_total", "Total of HTTP responses.", prometheus.CounterValue, prometheus.Labels{"code": "5xx"}), | |
161 | 44: newServerMetric("http_responses_total", "Total of HTTP responses.", prometheus.CounterValue, prometheus.Labels{"code": "other"}), | |
162 | 49: newServerMetric("client_aborts_total", "Total number of data transfers aborted by the client.", prometheus.CounterValue, nil), | |
163 | 50: newServerMetric("server_aborts_total", "Total number of data transfers aborted by the server.", prometheus.CounterValue, nil), | |
164 | } | |
165 | ||
166 | frontendMetrics = metrics{ | |
167 | 4: newFrontendMetric("current_sessions", "Current number of active sessions.", prometheus.GaugeValue, nil), | |
168 | 5: newFrontendMetric("max_sessions", "Maximum observed number of active sessions.", prometheus.GaugeValue, nil), | |
169 | 6: newFrontendMetric("limit_sessions", "Configured session limit.", prometheus.GaugeValue, nil), | |
170 | 7: newFrontendMetric("sessions_total", "Total number of sessions.", prometheus.CounterValue, nil), | |
171 | 8: newFrontendMetric("bytes_in_total", "Current total of incoming bytes.", prometheus.CounterValue, nil), | |
172 | 9: newFrontendMetric("bytes_out_total", "Current total of outgoing bytes.", prometheus.CounterValue, nil), | |
173 | 10: newFrontendMetric("requests_denied_total", "Total of requests denied for security.", prometheus.CounterValue, nil), | |
174 | 12: newFrontendMetric("request_errors_total", "Total of request errors.", prometheus.CounterValue, nil), | |
175 | 33: newFrontendMetric("current_session_rate", "Current number of sessions per second over last elapsed second.", prometheus.GaugeValue, nil), | |
176 | 34: newFrontendMetric("limit_session_rate", "Configured limit on new sessions per second.", prometheus.GaugeValue, nil), | |
177 | 35: newFrontendMetric("max_session_rate", "Maximum observed number of sessions per second.", prometheus.GaugeValue, nil), | |
178 | 39: newFrontendMetric("http_responses_total", "Total of HTTP responses.", prometheus.CounterValue, prometheus.Labels{"code": "1xx"}), | |
179 | 40: newFrontendMetric("http_responses_total", "Total of HTTP responses.", prometheus.CounterValue, prometheus.Labels{"code": "2xx"}), | |
180 | 41: newFrontendMetric("http_responses_total", "Total of HTTP responses.", prometheus.CounterValue, prometheus.Labels{"code": "3xx"}), | |
181 | 42: newFrontendMetric("http_responses_total", "Total of HTTP responses.", prometheus.CounterValue, prometheus.Labels{"code": "4xx"}), | |
182 | 43: newFrontendMetric("http_responses_total", "Total of HTTP responses.", prometheus.CounterValue, prometheus.Labels{"code": "5xx"}), | |
183 | 44: newFrontendMetric("http_responses_total", "Total of HTTP responses.", prometheus.CounterValue, prometheus.Labels{"code": "other"}), | |
184 | 48: newFrontendMetric("http_requests_total", "Total HTTP requests.", prometheus.CounterValue, nil), | |
185 | 51: newFrontendMetric("compressor_bytes_in_total", "Number of HTTP response bytes fed to the compressor", prometheus.CounterValue, nil), | |
186 | 52: newFrontendMetric("compressor_bytes_out_total", "Number of HTTP response bytes emitted by the compressor", prometheus.CounterValue, nil), | |
187 | 53: newFrontendMetric("compressor_bytes_bypassed_total", "Number of bytes that bypassed the HTTP compressor", prometheus.CounterValue, nil), | |
188 | 54: newFrontendMetric("http_responses_compressed_total", "Number of HTTP responses that were compressed", prometheus.CounterValue, nil), | |
189 | 79: newFrontendMetric("connections_total", "Total number of connections", prometheus.CounterValue, nil), | |
190 | } | |
191 | backendMetrics = metrics{ | |
192 | 2: newBackendMetric("current_queue", "Current number of queued requests not assigned to any server.", prometheus.GaugeValue, nil), | |
193 | 3: newBackendMetric("max_queue", "Maximum observed number of queued requests not assigned to any server.", prometheus.GaugeValue, nil), | |
194 | 4: newBackendMetric("current_sessions", "Current number of active sessions.", prometheus.GaugeValue, nil), | |
195 | 5: newBackendMetric("max_sessions", "Maximum observed number of active sessions.", prometheus.GaugeValue, nil), | |
196 | 6: newBackendMetric("limit_sessions", "Configured session limit.", prometheus.GaugeValue, nil), | |
197 | 7: newBackendMetric("sessions_total", "Total number of sessions.", prometheus.CounterValue, nil), | |
198 | 8: newBackendMetric("bytes_in_total", "Current total of incoming bytes.", prometheus.CounterValue, nil), | |
199 | 9: newBackendMetric("bytes_out_total", "Current total of outgoing bytes.", prometheus.CounterValue, nil), | |
200 | 13: newBackendMetric("connection_errors_total", "Total of connection errors.", prometheus.CounterValue, nil), | |
201 | 14: newBackendMetric("response_errors_total", "Total of response errors.", prometheus.CounterValue, nil), | |
202 | 15: newBackendMetric("retry_warnings_total", "Total of retry warnings.", prometheus.CounterValue, nil), | |
203 | 16: newBackendMetric("redispatch_warnings_total", "Total of redispatch warnings.", prometheus.CounterValue, nil), | |
204 | 17: newBackendMetric("up", "Current health status of the backend (1 = UP, 0 = DOWN).", prometheus.GaugeValue, nil), | |
205 | 18: newBackendMetric("weight", "Total weight of the servers in the backend.", prometheus.GaugeValue, nil), | |
206 | 19: newBackendMetric("current_server", "Current number of active servers", prometheus.GaugeValue, nil), | |
207 | 30: newBackendMetric("server_selected_total", "Total number of times a server was selected, either for new sessions, or when re-dispatching.", prometheus.CounterValue, nil), | |
208 | 33: newBackendMetric("current_session_rate", "Current number of sessions per second over last elapsed second.", prometheus.GaugeValue, nil), | |
209 | 35: newBackendMetric("max_session_rate", "Maximum number of sessions per second.", prometheus.GaugeValue, nil), | |
210 | 39: newBackendMetric("http_responses_total", "Total of HTTP responses.", prometheus.CounterValue, prometheus.Labels{"code": "1xx"}), | |
211 | 40: newBackendMetric("http_responses_total", "Total of HTTP responses.", prometheus.CounterValue, prometheus.Labels{"code": "2xx"}), | |
212 | 41: newBackendMetric("http_responses_total", "Total of HTTP responses.", prometheus.CounterValue, prometheus.Labels{"code": "3xx"}), | |
213 | 42: newBackendMetric("http_responses_total", "Total of HTTP responses.", prometheus.CounterValue, prometheus.Labels{"code": "4xx"}), | |
214 | 43: newBackendMetric("http_responses_total", "Total of HTTP responses.", prometheus.CounterValue, prometheus.Labels{"code": "5xx"}), | |
215 | 44: newBackendMetric("http_responses_total", "Total of HTTP responses.", prometheus.CounterValue, prometheus.Labels{"code": "other"}), | |
216 | 49: newBackendMetric("client_aborts_total", "Total number of data transfers aborted by the client.", prometheus.CounterValue, nil), | |
217 | 50: newBackendMetric("server_aborts_total", "Total number of data transfers aborted by the server.", prometheus.CounterValue, nil), | |
218 | 51: newBackendMetric("compressor_bytes_in_total", "Number of HTTP response bytes fed to the compressor", prometheus.CounterValue, nil), | |
219 | 52: newBackendMetric("compressor_bytes_out_total", "Number of HTTP response bytes emitted by the compressor", prometheus.CounterValue, nil), | |
220 | 53: newBackendMetric("compressor_bytes_bypassed_total", "Number of bytes that bypassed the HTTP compressor", prometheus.CounterValue, nil), | |
221 | 54: newBackendMetric("http_responses_compressed_total", "Number of HTTP responses that were compressed", prometheus.CounterValue, nil), | |
222 | 58: newBackendMetric("http_queue_time_average_seconds", "Avg. HTTP queue time for last 1024 successful connections.", prometheus.GaugeValue, nil), | |
223 | 59: newBackendMetric("http_connect_time_average_seconds", "Avg. HTTP connect time for last 1024 successful connections.", prometheus.GaugeValue, nil), | |
224 | 60: newBackendMetric("http_response_time_average_seconds", "Avg. HTTP response time for last 1024 successful connections.", prometheus.GaugeValue, nil), | |
225 | 61: newBackendMetric("http_total_time_average_seconds", "Avg. HTTP total time for last 1024 successful connections.", prometheus.GaugeValue, nil), | |
226 | } | |
227 | ||
228 | haproxyInfo = prometheus.NewDesc(prometheus.BuildFQName(namespace, "version", "info"), "HAProxy version info.", []string{"release_date", "version"}, nil) | |
229 | haproxyUp = prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "up"), "Was the last scrape of HAProxy successful.", nil, nil) | |
143 | 230 | ) |
144 | 231 | |
145 | 232 | // Exporter collects HAProxy stats from the given URI and exports them using |
146 | 233 | // the prometheus metrics package. |
147 | 234 | type Exporter struct { |
148 | URI string | |
149 | mutex sync.RWMutex | |
150 | fetch func() (io.ReadCloser, error) | |
151 | ||
152 | up prometheus.Gauge | |
153 | totalScrapes, csvParseFailures prometheus.Counter | |
154 | frontendMetrics, backendMetrics, serverMetrics map[int]*prometheus.GaugeVec | |
235 | URI string | |
236 | mutex sync.RWMutex | |
237 | fetchInfo func() (io.ReadCloser, error) | |
238 | fetchStat func() (io.ReadCloser, error) | |
239 | ||
240 | up prometheus.Gauge | |
241 | totalScrapes, csvParseFailures prometheus.Counter | |
242 | serverMetrics map[int]metricInfo | |
243 | excludedServerStates map[string]struct{} | |
244 | logger log.Logger | |
155 | 245 | } |
156 | 246 | |
157 | 247 | // NewExporter returns an initialized Exporter. |
158 | func NewExporter(uri string, sslVerify bool, selectedServerMetrics map[int]*prometheus.GaugeVec, timeout time.Duration) (*Exporter, error) { | |
248 | func NewExporter(uri string, sslVerify bool, selectedServerMetrics map[int]metricInfo, excludedServerStates string, timeout time.Duration, logger log.Logger) (*Exporter, error) { | |
159 | 249 | u, err := url.Parse(uri) |
160 | 250 | if err != nil { |
161 | 251 | return nil, err |
162 | 252 | } |
163 | 253 | |
164 | var fetch func() (io.ReadCloser, error) | |
254 | var fetchInfo func() (io.ReadCloser, error) | |
255 | var fetchStat func() (io.ReadCloser, error) | |
165 | 256 | switch u.Scheme { |
166 | 257 | case "http", "https", "file": |
167 | fetch = fetchHTTP(uri, sslVerify, timeout) | |
258 | fetchStat = fetchHTTP(uri, sslVerify, timeout) | |
168 | 259 | case "unix": |
169 | fetch = fetchUnix(u, timeout) | |
260 | fetchInfo = fetchUnix(u, showInfoCmd, timeout) | |
261 | fetchStat = fetchUnix(u, showStatCmd, timeout) | |
170 | 262 | default: |
171 | 263 | return nil, fmt.Errorf("unsupported scheme: %q", u.Scheme) |
172 | 264 | } |
173 | 265 | |
266 | excludedServerStatesMap := map[string]struct{}{} | |
267 | for _, f := range strings.Split(excludedServerStates, ",") { | |
268 | excludedServerStatesMap[f] = struct{}{} | |
269 | } | |
270 | ||
174 | 271 | return &Exporter{ |
175 | URI: uri, | |
176 | fetch: fetch, | |
272 | URI: uri, | |
273 | fetchInfo: fetchInfo, | |
274 | fetchStat: fetchStat, | |
177 | 275 | up: prometheus.NewGauge(prometheus.GaugeOpts{ |
178 | 276 | Namespace: namespace, |
179 | 277 | Name: "up", |
181 | 279 | }), |
182 | 280 | totalScrapes: prometheus.NewCounter(prometheus.CounterOpts{ |
183 | 281 | Namespace: namespace, |
184 | Name: "exporter_total_scrapes", | |
282 | Name: "exporter_scrapes_total", | |
185 | 283 | Help: "Current total HAProxy scrapes.", |
186 | 284 | }), |
187 | 285 | csvParseFailures: prometheus.NewCounter(prometheus.CounterOpts{ |
188 | 286 | Namespace: namespace, |
189 | Name: "exporter_csv_parse_failures", | |
287 | Name: "exporter_csv_parse_failures_total", | |
190 | 288 | Help: "Number of errors while parsing CSV.", |
191 | 289 | }), |
192 | frontendMetrics: map[int]*prometheus.GaugeVec{ | |
193 | 4: newFrontendMetric("current_sessions", "Current number of active sessions.", nil), | |
194 | 5: newFrontendMetric("max_sessions", "Maximum observed number of active sessions.", nil), | |
195 | 6: newFrontendMetric("limit_sessions", "Configured session limit.", nil), | |
196 | 7: newFrontendMetric("sessions_total", "Total number of sessions.", nil), | |
197 | 8: newFrontendMetric("bytes_in_total", "Current total of incoming bytes.", nil), | |
198 | 9: newFrontendMetric("bytes_out_total", "Current total of outgoing bytes.", nil), | |
199 | 10: newFrontendMetric("requests_denied_total", "Total of requests denied for security.", nil), | |
200 | 12: newFrontendMetric("request_errors_total", "Total of request errors.", nil), | |
201 | 33: newFrontendMetric("current_session_rate", "Current number of sessions per second over last elapsed second.", nil), | |
202 | 34: newFrontendMetric("limit_session_rate", "Configured limit on new sessions per second.", nil), | |
203 | 35: newFrontendMetric("max_session_rate", "Maximum observed number of sessions per second.", nil), | |
204 | 39: newFrontendMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "1xx"}), | |
205 | 40: newFrontendMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "2xx"}), | |
206 | 41: newFrontendMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "3xx"}), | |
207 | 42: newFrontendMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "4xx"}), | |
208 | 43: newFrontendMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "5xx"}), | |
209 | 44: newFrontendMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "other"}), | |
210 | 48: newFrontendMetric("http_requests_total", "Total HTTP requests.", nil), | |
211 | 79: newFrontendMetric("connections_total", "Total number of connections", nil), | |
212 | }, | |
213 | backendMetrics: map[int]*prometheus.GaugeVec{ | |
214 | 2: newBackendMetric("current_queue", "Current number of queued requests not assigned to any server.", nil), | |
215 | 3: newBackendMetric("max_queue", "Maximum observed number of queued requests not assigned to any server.", nil), | |
216 | 4: newBackendMetric("current_sessions", "Current number of active sessions.", nil), | |
217 | 5: newBackendMetric("max_sessions", "Maximum observed number of active sessions.", nil), | |
218 | 6: newBackendMetric("limit_sessions", "Configured session limit.", nil), | |
219 | 7: newBackendMetric("sessions_total", "Total number of sessions.", nil), | |
220 | 8: newBackendMetric("bytes_in_total", "Current total of incoming bytes.", nil), | |
221 | 9: newBackendMetric("bytes_out_total", "Current total of outgoing bytes.", nil), | |
222 | 13: newBackendMetric("connection_errors_total", "Total of connection errors.", nil), | |
223 | 14: newBackendMetric("response_errors_total", "Total of response errors.", nil), | |
224 | 15: newBackendMetric("retry_warnings_total", "Total of retry warnings.", nil), | |
225 | 16: newBackendMetric("redispatch_warnings_total", "Total of redispatch warnings.", nil), | |
226 | 17: newBackendMetric("up", "Current health status of the backend (1 = UP, 0 = DOWN).", nil), | |
227 | 18: newBackendMetric("weight", "Total weight of the servers in the backend.", nil), | |
228 | 19: newBackendMetric("current_server", "Current number of active servers", nil), | |
229 | 33: newBackendMetric("current_session_rate", "Current number of sessions per second over last elapsed second.", nil), | |
230 | 35: newBackendMetric("max_session_rate", "Maximum number of sessions per second.", nil), | |
231 | 39: newBackendMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "1xx"}), | |
232 | 40: newBackendMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "2xx"}), | |
233 | 41: newBackendMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "3xx"}), | |
234 | 42: newBackendMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "4xx"}), | |
235 | 43: newBackendMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "5xx"}), | |
236 | 44: newBackendMetric("http_responses_total", "Total of HTTP responses.", prometheus.Labels{"code": "other"}), | |
237 | 58: newBackendMetric("http_queue_time_average_seconds", "Avg. HTTP queue time for last 1024 successful connections.", nil), | |
238 | 59: newBackendMetric("http_connect_time_average_seconds", "Avg. HTTP connect time for last 1024 successful connections.", nil), | |
239 | 60: newBackendMetric("http_response_time_average_seconds", "Avg. HTTP response time for last 1024 successful connections.", nil), | |
240 | 61: newBackendMetric("http_total_time_average_seconds", "Avg. HTTP total time for last 1024 successful connections.", nil), | |
241 | }, | |
242 | serverMetrics: selectedServerMetrics, | |
290 | serverMetrics: selectedServerMetrics, | |
291 | excludedServerStates: excludedServerStatesMap, | |
292 | logger: logger, | |
243 | 293 | }, nil |
244 | 294 | } |
245 | 295 | |
246 | 296 | // Describe describes all the metrics ever exported by the HAProxy exporter. It |
247 | 297 | // implements prometheus.Collector. |
248 | 298 | func (e *Exporter) Describe(ch chan<- *prometheus.Desc) { |
249 | for _, m := range e.frontendMetrics { | |
250 | m.Describe(ch) | |
251 | } | |
252 | for _, m := range e.backendMetrics { | |
253 | m.Describe(ch) | |
299 | for _, m := range frontendMetrics { | |
300 | ch <- m.Desc | |
301 | } | |
302 | for _, m := range backendMetrics { | |
303 | ch <- m.Desc | |
254 | 304 | } |
255 | 305 | for _, m := range e.serverMetrics { |
256 | m.Describe(ch) | |
257 | } | |
258 | ch <- e.up.Desc() | |
306 | ch <- m.Desc | |
307 | } | |
308 | ch <- haproxyInfo | |
309 | ch <- haproxyUp | |
259 | 310 | ch <- e.totalScrapes.Desc() |
260 | 311 | ch <- e.csvParseFailures.Desc() |
261 | 312 | } |
266 | 317 | e.mutex.Lock() // To protect metrics from concurrent collects. |
267 | 318 | defer e.mutex.Unlock() |
268 | 319 | |
269 | e.resetMetrics() | |
270 | e.scrape() | |
271 | ||
272 | ch <- e.up | |
320 | up := e.scrape(ch) | |
321 | ||
322 | ch <- prometheus.MustNewConstMetric(haproxyUp, prometheus.GaugeValue, up) | |
273 | 323 | ch <- e.totalScrapes |
274 | 324 | ch <- e.csvParseFailures |
275 | e.collectMetrics(ch) | |
276 | 325 | } |
277 | 326 | |
278 | 327 | func fetchHTTP(uri string, sslVerify bool, timeout time.Duration) func() (io.ReadCloser, error) { |
295 | 344 | } |
296 | 345 | } |
297 | 346 | |
298 | func fetchUnix(u *url.URL, timeout time.Duration) func() (io.ReadCloser, error) { | |
347 | func fetchUnix(u *url.URL, cmd string, timeout time.Duration) func() (io.ReadCloser, error) { | |
299 | 348 | return func() (io.ReadCloser, error) { |
300 | 349 | f, err := net.DialTimeout("unix", u.Path, timeout) |
301 | 350 | if err != nil { |
305 | 354 | f.Close() |
306 | 355 | return nil, err |
307 | 356 | } |
308 | cmd := "show stat\n" | |
309 | 357 | n, err := io.WriteString(f, cmd) |
310 | 358 | if err != nil { |
311 | 359 | f.Close() |
319 | 367 | } |
320 | 368 | } |
321 | 369 | |
322 | func (e *Exporter) scrape() { | |
370 | func (e *Exporter) scrape(ch chan<- prometheus.Metric) (up float64) { | |
323 | 371 | e.totalScrapes.Inc() |
324 | ||
325 | body, err := e.fetch() | |
372 | var err error | |
373 | ||
374 | if e.fetchInfo != nil { | |
375 | infoReader, err := e.fetchInfo() | |
376 | if err != nil { | |
377 | level.Error(e.logger).Log("msg", "Can't scrape HAProxy", "err", err) | |
378 | return 0 | |
379 | } | |
380 | defer infoReader.Close() | |
381 | ||
382 | info, err := e.parseInfo(infoReader) | |
383 | if err != nil { | |
384 | level.Debug(e.logger).Log("msg", "Failed parsing show info", "err", err) | |
385 | } else { | |
386 | ch <- prometheus.MustNewConstMetric(haproxyInfo, prometheus.GaugeValue, 1, info.ReleaseDate, info.Version) | |
387 | } | |
388 | } | |
389 | ||
390 | body, err := e.fetchStat() | |
326 | 391 | if err != nil { |
327 | e.up.Set(0) | |
328 | log.Errorf("Can't scrape HAProxy: %v", err) | |
329 | return | |
392 | level.Error(e.logger).Log("msg", "Can't scrape HAProxy", "err", err) | |
393 | return 0 | |
330 | 394 | } |
331 | 395 | defer body.Close() |
332 | e.up.Set(1) | |
333 | 396 | |
334 | 397 | reader := csv.NewReader(body) |
335 | 398 | reader.TrailingComma = true |
344 | 407 | break loop |
345 | 408 | default: |
346 | 409 | if _, ok := err.(*csv.ParseError); ok { |
347 | log.Errorf("Can't read CSV: %v", err) | |
410 | level.Error(e.logger).Log("msg", "Can't read CSV", "err", err) | |
348 | 411 | e.csvParseFailures.Inc() |
349 | 412 | continue loop |
350 | 413 | } |
351 | log.Errorf("Unexpected error while reading CSV: %v", err) | |
352 | e.up.Set(0) | |
353 | break loop | |
354 | } | |
355 | e.parseRow(row) | |
356 | } | |
357 | } | |
358 | ||
359 | func (e *Exporter) resetMetrics() { | |
360 | for _, m := range e.frontendMetrics { | |
361 | m.Reset() | |
362 | } | |
363 | for _, m := range e.backendMetrics { | |
364 | m.Reset() | |
365 | } | |
366 | for _, m := range e.serverMetrics { | |
367 | m.Reset() | |
368 | } | |
369 | } | |
370 | ||
371 | func (e *Exporter) collectMetrics(metrics chan<- prometheus.Metric) { | |
372 | for _, m := range e.frontendMetrics { | |
373 | m.Collect(metrics) | |
374 | } | |
375 | for _, m := range e.backendMetrics { | |
376 | m.Collect(metrics) | |
377 | } | |
378 | for _, m := range e.serverMetrics { | |
379 | m.Collect(metrics) | |
380 | } | |
381 | } | |
382 | ||
383 | func (e *Exporter) parseRow(csvRow []string) { | |
414 | level.Error(e.logger).Log("msg", "Unexpected error while reading CSV", "err", err) | |
415 | return 0 | |
416 | } | |
417 | e.parseRow(row, ch) | |
418 | } | |
419 | return 1 | |
420 | } | |
421 | ||
422 | type versionInfo struct { | |
423 | ReleaseDate string | |
424 | Version string | |
425 | } | |
426 | ||
427 | func (e *Exporter) parseInfo(i io.Reader) (versionInfo, error) { | |
428 | var version, releaseDate string | |
429 | s := bufio.NewScanner(i) | |
430 | for s.Scan() { | |
431 | line := s.Text() | |
432 | if !strings.Contains(line, ":") { | |
433 | continue | |
434 | } | |
435 | ||
436 | field := strings.SplitN(line, ": ", 2) | |
437 | switch field[0] { | |
438 | case "Release_date": | |
439 | releaseDate = field[1] | |
440 | case "Version": | |
441 | version = field[1] | |
442 | } | |
443 | } | |
444 | return versionInfo{ReleaseDate: releaseDate, Version: version}, s.Err() | |
445 | } | |
446 | ||
447 | func (e *Exporter) parseRow(csvRow []string, ch chan<- prometheus.Metric) { | |
384 | 448 | if len(csvRow) < minimumCsvFieldCount { |
385 | log.Errorf("Parser expected at least %d CSV fields, but got: %d", minimumCsvFieldCount, len(csvRow)) | |
449 | level.Error(e.logger).Log("msg", "Parser received unexpected number of CSV fields", "min", minimumCsvFieldCount, "received", len(csvRow)) | |
386 | 450 | e.csvParseFailures.Inc() |
387 | 451 | return |
388 | 452 | } |
389 | 453 | |
390 | pxname, svname, typ := csvRow[0], csvRow[1], csvRow[32] | |
454 | pxname, svname, status, typ := csvRow[pxnameField], csvRow[svnameField], csvRow[statusField], csvRow[typeField] | |
391 | 455 | |
392 | 456 | const ( |
393 | 457 | frontend = "0" |
394 | 458 | backend = "1" |
395 | 459 | server = "2" |
396 | listener = "3" | |
397 | 460 | ) |
398 | 461 | |
399 | 462 | switch typ { |
400 | 463 | case frontend: |
401 | e.exportCsvFields(e.frontendMetrics, csvRow, pxname) | |
464 | e.exportCsvFields(frontendMetrics, csvRow, ch, pxname) | |
402 | 465 | case backend: |
403 | e.exportCsvFields(e.backendMetrics, csvRow, pxname) | |
466 | e.exportCsvFields(backendMetrics, csvRow, ch, pxname) | |
404 | 467 | case server: |
405 | e.exportCsvFields(e.serverMetrics, csvRow, pxname, svname) | |
468 | ||
469 | if _, ok := e.excludedServerStates[status]; !ok { | |
470 | e.exportCsvFields(e.serverMetrics, csvRow, ch, pxname, svname) | |
471 | } | |
406 | 472 | } |
407 | 473 | } |
408 | 474 | |
409 | 475 | func parseStatusField(value string) int64 { |
410 | 476 | switch value { |
411 | case "UP", "UP 1/3", "UP 2/3", "OPEN", "no check": | |
477 | case "UP", "UP 1/3", "UP 2/3", "OPEN", "no check", "DRAIN": | |
412 | 478 | return 1 |
413 | case "DOWN", "DOWN 1/2", "NOLB", "MAINT": | |
479 | case "DOWN", "DOWN 1/2", "NOLB", "MAINT", "MAINT(via)", "MAINT(resolution)": | |
414 | 480 | return 0 |
415 | } | |
416 | return 0 | |
417 | } | |
418 | ||
419 | func (e *Exporter) exportCsvFields(metrics map[int]*prometheus.GaugeVec, csvRow []string, labels ...string) { | |
481 | default: | |
482 | return 0 | |
483 | } | |
484 | } | |
485 | ||
486 | func (e *Exporter) exportCsvFields(metrics map[int]metricInfo, csvRow []string, ch chan<- prometheus.Metric, labels ...string) { | |
420 | 487 | for fieldIdx, metric := range metrics { |
421 | 488 | if fieldIdx > len(csvRow)-1 { |
422 | break | |
489 | // We can't break here because we are not looping over the fields in sorted order. | |
490 | continue | |
423 | 491 | } |
424 | 492 | valueStr := csvRow[fieldIdx] |
425 | 493 | if valueStr == "" { |
434 | 502 | case statusField: |
435 | 503 | valueInt = parseStatusField(valueStr) |
436 | 504 | value = float64(valueInt) |
437 | case qtimeMsField, ctimeMsField, rtimeMsField, ttimeMsField: | |
505 | case checkDurationField, qtimeMsField, ctimeMsField, rtimeMsField, ttimeMsField: | |
438 | 506 | value, err = strconv.ParseFloat(valueStr, 64) |
439 | 507 | value /= 1000 |
440 | 508 | default: |
442 | 510 | value = float64(valueInt) |
443 | 511 | } |
444 | 512 | if err != nil { |
445 | log.Errorf("Can't parse CSV field value %s: %v", valueStr, err) | |
513 | level.Error(e.logger).Log("msg", "Can't parse CSV field value", "value", valueStr, "err", err) | |
446 | 514 | e.csvParseFailures.Inc() |
447 | 515 | continue |
448 | 516 | } |
449 | metric.WithLabelValues(labels...).Set(value) | |
517 | ch <- prometheus.MustNewConstMetric(metric.Desc, metric.Type, value, labels...) | |
450 | 518 | } |
451 | 519 | } |
452 | 520 | |
453 | 521 | // filterServerMetrics returns the set of server metrics specified by the comma |
454 | 522 | // separated filter. |
455 | func filterServerMetrics(filter string) (map[int]*prometheus.GaugeVec, error) { | |
456 | metrics := map[int]*prometheus.GaugeVec{} | |
523 | func filterServerMetrics(filter string) (map[int]metricInfo, error) { | |
524 | metrics := map[int]metricInfo{} | |
457 | 525 | if len(filter) == 0 { |
458 | 526 | return metrics, nil |
459 | 527 | } |
460 | 528 | |
461 | selected := map[int]struct{}{} | |
462 | 529 | for _, f := range strings.Split(filter, ",") { |
463 | 530 | field, err := strconv.Atoi(f) |
464 | 531 | if err != nil { |
465 | 532 | return nil, fmt.Errorf("invalid server metric field number: %v", f) |
466 | 533 | } |
467 | selected[field] = struct{}{} | |
468 | } | |
469 | ||
470 | for field, metric := range serverMetrics { | |
471 | if _, ok := selected[field]; ok { | |
534 | if metric, ok := serverMetrics[field]; ok { | |
472 | 535 | metrics[field] = metric |
473 | 536 | } |
474 | 537 | } |
538 | ||
475 | 539 | return metrics, nil |
476 | 540 | } |
477 | 541 | |
486 | 550 | https://prometheus.io/docs/instrumenting/writing_clientlibs/#process-metrics.` |
487 | 551 | |
488 | 552 | var ( |
489 | listenAddress = kingpin.Flag("web.listen-address", "Address to listen on for web interface and telemetry.").Default(":9101").String() | |
490 | metricsPath = kingpin.Flag("web.telemetry-path", "Path under which to expose metrics.").Default("/metrics").String() | |
491 | haProxyScrapeURI = kingpin.Flag("haproxy.scrape-uri", "URI on which to scrape HAProxy.").Default("http://localhost/;csv").String() | |
492 | haProxySSLVerify = kingpin.Flag("haproxy.ssl-verify", "Flag that enables SSL certificate verification for the scrape URI").Default("true").Bool() | |
493 | haProxyServerMetricFields = kingpin.Flag("haproxy.server-metric-fields", "Comma-separated list of exported server metrics. See http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#9.1").Default(serverMetrics.String()).String() | |
494 | haProxyTimeout = kingpin.Flag("haproxy.timeout", "Timeout for trying to get stats from HAProxy.").Default("5s").Duration() | |
495 | haProxyPidFile = kingpin.Flag("haproxy.pid-file", pidFileHelpText).Default("").String() | |
553 | listenAddress = kingpin.Flag("web.listen-address", "Address to listen on for web interface and telemetry.").Default(":9101").String() | |
554 | metricsPath = kingpin.Flag("web.telemetry-path", "Path under which to expose metrics.").Default("/metrics").String() | |
555 | haProxyScrapeURI = kingpin.Flag("haproxy.scrape-uri", "URI on which to scrape HAProxy.").Default("http://localhost/;csv").String() | |
556 | haProxySSLVerify = kingpin.Flag("haproxy.ssl-verify", "Flag that enables SSL certificate verification for the scrape URI").Default("true").Bool() | |
557 | haProxyServerMetricFields = kingpin.Flag("haproxy.server-metric-fields", "Comma-separated list of exported server metrics. See http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#9.1").Default(serverMetrics.String()).String() | |
558 | haProxyServerExcludeStates = kingpin.Flag("haproxy.server-exclude-states", "Comma-separated list of exported server states to exclude. See https://cbonte.github.io/haproxy-dconv/1.8/management.html#9.1, field 17 statuus").Default(excludedServerStates).String() | |
559 | haProxyTimeout = kingpin.Flag("haproxy.timeout", "Timeout for trying to get stats from HAProxy.").Default("5s").Duration() | |
560 | haProxyPidFile = kingpin.Flag("haproxy.pid-file", pidFileHelpText).Default("").String() | |
496 | 561 | ) |
497 | 562 | |
498 | log.AddFlags(kingpin.CommandLine) | |
563 | promlogConfig := &promlog.Config{} | |
564 | flag.AddFlags(kingpin.CommandLine, promlogConfig) | |
499 | 565 | kingpin.Version(version.Print("haproxy_exporter")) |
500 | 566 | kingpin.HelpFlag.Short('h') |
501 | 567 | kingpin.Parse() |
568 | logger := promlog.New(promlogConfig) | |
502 | 569 | |
503 | 570 | selectedServerMetrics, err := filterServerMetrics(*haProxyServerMetricFields) |
504 | 571 | if err != nil { |
505 | log.Fatal(err) | |
506 | } | |
507 | ||
508 | log.Infoln("Starting haproxy_exporter", version.Info()) | |
509 | log.Infoln("Build context", version.BuildContext()) | |
510 | ||
511 | exporter, err := NewExporter(*haProxyScrapeURI, *haProxySSLVerify, selectedServerMetrics, *haProxyTimeout) | |
572 | level.Error(logger).Log("msg", "Error filtering server metrics", "err", err) | |
573 | os.Exit(1) | |
574 | } | |
575 | ||
576 | level.Info(logger).Log("msg", "Starting haproxy_exporter", "version", version.Info()) | |
577 | level.Info(logger).Log("msg", "Build context", "context", version.BuildContext()) | |
578 | ||
579 | exporter, err := NewExporter(*haProxyScrapeURI, *haProxySSLVerify, selectedServerMetrics, *haProxyServerExcludeStates, *haProxyTimeout, logger) | |
512 | 580 | if err != nil { |
513 | log.Fatal(err) | |
581 | level.Error(logger).Log("msg", "Error creating an exporter", "err", err) | |
582 | os.Exit(1) | |
514 | 583 | } |
515 | 584 | prometheus.MustRegister(exporter) |
516 | 585 | prometheus.MustRegister(version.NewCollector("haproxy_exporter")) |
520 | 589 | PidFn: func() (int, error) { |
521 | 590 | content, err := ioutil.ReadFile(*haProxyPidFile) |
522 | 591 | if err != nil { |
523 | return 0, fmt.Errorf("Can't read pid file: %s", err) | |
592 | return 0, fmt.Errorf("can't read pid file: %s", err) | |
524 | 593 | } |
525 | 594 | value, err := strconv.Atoi(strings.TrimSpace(string(content))) |
526 | 595 | if err != nil { |
527 | return 0, fmt.Errorf("Can't parse pid file: %s", err) | |
596 | return 0, fmt.Errorf("can't parse pid file: %s", err) | |
528 | 597 | } |
529 | 598 | return value, nil |
530 | 599 | }, |
533 | 602 | prometheus.MustRegister(procExporter) |
534 | 603 | } |
535 | 604 | |
536 | log.Infoln("Listening on", *listenAddress) | |
605 | level.Info(logger).Log("msg", "Listening on address", "address", *listenAddress) | |
537 | 606 | http.Handle(*metricsPath, promhttp.Handler()) |
538 | 607 | http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { |
539 | 608 | w.Write([]byte(`<html> |
544 | 613 | </body> |
545 | 614 | </html>`)) |
546 | 615 | }) |
547 | log.Fatal(http.ListenAndServe(*listenAddress, nil)) | |
548 | } | |
616 | if err := http.ListenAndServe(*listenAddress, nil); err != nil { | |
617 | level.Error(logger).Log("msg", "Error starting HTTP server", "err", err) | |
618 | os.Exit(1) | |
619 | } | |
620 | } |
20 | 20 | "net/http" |
21 | 21 | "net/http/httptest" |
22 | 22 | "os" |
23 | "path" | |
23 | 24 | "reflect" |
24 | 25 | "runtime" |
25 | 26 | "testing" |
26 | 27 | "time" |
27 | 28 | |
28 | dto "github.com/prometheus/client_model/go" | |
29 | ||
29 | "github.com/go-kit/kit/log" | |
30 | 30 | "github.com/prometheus/client_golang/prometheus" |
31 | "github.com/prometheus/client_golang/prometheus/testutil" | |
31 | 32 | ) |
32 | 33 | |
33 | const testSocket = "/tmp/haproxyexportertest.sock" | |
34 | const ( | |
35 | testSocket = "/tmp/haproxyexportertest.sock" | |
36 | testInfo = "Release_date: test date\nVersion: test version\n" | |
37 | ) | |
34 | 38 | |
35 | 39 | type haproxy struct { |
36 | 40 | *httptest.Server |
55 | 59 | } |
56 | 60 | } |
57 | 61 | |
58 | func readCounter(m prometheus.Counter) float64 { | |
59 | // TODO: Revisit this once client_golang offers better testing tools. | |
60 | pb := &dto.Metric{} | |
61 | m.Write(pb) | |
62 | return pb.GetCounter().GetValue() | |
63 | } | |
64 | ||
65 | func readGauge(m prometheus.Gauge) float64 { | |
66 | // TODO: Revisit this once client_golang offers better testing tools. | |
67 | pb := &dto.Metric{} | |
68 | m.Write(pb) | |
69 | return pb.GetGauge().GetValue() | |
62 | func expectMetrics(t *testing.T, c prometheus.Collector, fixture string) { | |
63 | exp, err := os.Open(path.Join("test", fixture)) | |
64 | if err != nil { | |
65 | t.Fatalf("Error opening fixture file %q: %v", fixture, err) | |
66 | } | |
67 | if err := testutil.CollectAndCompare(c, exp); err != nil { | |
68 | t.Fatal("Unexpected metrics returned:", err) | |
69 | } | |
70 | 70 | } |
71 | 71 | |
72 | 72 | func TestInvalidConfig(t *testing.T) { |
73 | 73 | h := newHaproxy([]byte("not,enough,fields")) |
74 | 74 | defer h.Close() |
75 | 75 | |
76 | e, _ := NewExporter(h.URL, true, serverMetrics, 5*time.Second) | |
77 | ch := make(chan prometheus.Metric) | |
78 | ||
79 | go func() { | |
80 | defer close(ch) | |
81 | e.Collect(ch) | |
82 | }() | |
83 | ||
84 | if expect, got := 1., readGauge((<-ch).(prometheus.Gauge)); expect != got { | |
85 | // up | |
86 | t.Errorf("expected %f up, got %f", expect, got) | |
87 | } | |
88 | if expect, got := 1., readCounter((<-ch).(prometheus.Counter)); expect != got { | |
89 | // totalScrapes | |
90 | t.Errorf("expected %f recorded scrape, got %f", expect, got) | |
91 | } | |
92 | if expect, got := 1., readCounter((<-ch).(prometheus.Counter)); expect != got { | |
93 | // csvParseFailures | |
94 | t.Errorf("expected %f csv parse failures, got %f", expect, got) | |
95 | } | |
96 | if <-ch != nil { | |
97 | t.Errorf("expected closed channel") | |
98 | } | |
76 | e, _ := NewExporter(h.URL, true, serverMetrics, excludedServerStates, 5*time.Second, log.NewNopLogger()) | |
77 | ||
78 | expectMetrics(t, e, "invalid_config.metrics") | |
99 | 79 | } |
100 | 80 | |
101 | 81 | func TestServerWithoutChecks(t *testing.T) { |
102 | 82 | h := newHaproxy([]byte("test,127.0.0.1:8080,0,0,0,0,0,0,0,0,,0,,0,0,0,0,no check,1,1,0,0,,,0,,1,1,1,,0,,2,0,,0,,,,0,0,0,0,0,0,0,,,,0,0,,,,,,,,,,,")) |
103 | 83 | defer h.Close() |
104 | 84 | |
105 | e, _ := NewExporter(h.URL, true, serverMetrics, 5*time.Second) | |
106 | ch := make(chan prometheus.Metric) | |
107 | ||
108 | go func() { | |
109 | defer close(ch) | |
110 | e.Collect(ch) | |
111 | }() | |
112 | ||
113 | if expect, got := 1., readGauge((<-ch).(prometheus.Gauge)); expect != got { | |
114 | // up | |
115 | t.Errorf("expected %f up, got %f", expect, got) | |
116 | } | |
117 | if expect, got := 1., readCounter((<-ch).(prometheus.Counter)); expect != got { | |
118 | // totalScrapes | |
119 | t.Errorf("expected %f recorded scrape, got %f", expect, got) | |
120 | } | |
121 | if expect, got := 0., readCounter((<-ch).(prometheus.Counter)); expect != got { | |
122 | // csvParseFailures | |
123 | t.Errorf("expected %f csv parse failures, got %f", expect, got) | |
124 | } | |
125 | ||
126 | got := 0 | |
127 | for range ch { | |
128 | got++ | |
129 | } | |
130 | if expect := len(e.serverMetrics) - 1; got != expect { | |
131 | t.Errorf("expected %d metrics, got %d", expect, got) | |
132 | } | |
85 | e, _ := NewExporter(h.URL, true, serverMetrics, excludedServerStates, 5*time.Second, log.NewNopLogger()) | |
86 | ||
87 | expectMetrics(t, e, "server_without_checks.metrics") | |
133 | 88 | } |
134 | 89 | |
135 | 90 | // TestServerBrokenCSV ensures bugs in CSV format are handled gracefully. List of known bugs: |
145 | 100 | h := newHaproxy([]byte(data)) |
146 | 101 | defer h.Close() |
147 | 102 | |
148 | e, _ := NewExporter(h.URL, true, serverMetrics, 5*time.Second) | |
149 | ch := make(chan prometheus.Metric) | |
150 | ||
151 | go func() { | |
152 | defer close(ch) | |
153 | e.Collect(ch) | |
154 | }() | |
155 | ||
156 | if expect, got := 1., readGauge((<-ch).(prometheus.Gauge)); expect != got { | |
157 | // up | |
158 | t.Errorf("expected %f up, got %f", expect, got) | |
159 | } | |
160 | if expect, got := 1., readCounter((<-ch).(prometheus.Counter)); expect != got { | |
161 | // totalScrapes | |
162 | t.Errorf("expected %f recorded scrape, got %f", expect, got) | |
163 | } | |
164 | if expect, got := 1., readCounter((<-ch).(prometheus.Counter)); expect != got { | |
165 | // csvParseFailures | |
166 | t.Errorf("expected %f csv parse failures, got %f", expect, got) | |
167 | } | |
168 | ||
169 | got := 0 | |
170 | for range ch { | |
171 | got++ | |
172 | } | |
173 | if expect := len(e.frontendMetrics) + len(e.backendMetrics); got < expect { | |
174 | t.Errorf("expected at least %d metrics, got %d", expect, got) | |
175 | } | |
103 | e, _ := NewExporter(h.URL, true, serverMetrics, excludedServerStates, 5*time.Second, log.NewNopLogger()) | |
104 | ||
105 | expectMetrics(t, e, "server_broken_csv.metrics") | |
176 | 106 | } |
177 | 107 | |
178 | 108 | func TestOlderHaproxyVersions(t *testing.T) { |
183 | 113 | h := newHaproxy([]byte(data)) |
184 | 114 | defer h.Close() |
185 | 115 | |
186 | e, _ := NewExporter(h.URL, true, serverMetrics, 5*time.Second) | |
187 | ch := make(chan prometheus.Metric) | |
188 | ||
189 | go func() { | |
190 | defer close(ch) | |
191 | e.Collect(ch) | |
192 | }() | |
193 | ||
194 | if expect, got := 1., readGauge((<-ch).(prometheus.Gauge)); expect != got { | |
195 | // up | |
196 | t.Errorf("expected %f up, got %f", expect, got) | |
197 | } | |
198 | if expect, got := 1., readCounter((<-ch).(prometheus.Counter)); expect != got { | |
199 | // totalScrapes | |
200 | t.Errorf("expected %f recorded scrape, got %f", expect, got) | |
201 | } | |
202 | if expect, got := 0., readCounter((<-ch).(prometheus.Counter)); expect != got { | |
203 | // csvParseFailures | |
204 | t.Errorf("expected %f csv parse failures, got %f", expect, got) | |
205 | } | |
206 | ||
207 | // Suck up the remaining metrics. | |
208 | for range ch { | |
209 | } | |
116 | e, _ := NewExporter(h.URL, true, serverMetrics, excludedServerStates, 5*time.Second, log.NewNopLogger()) | |
117 | ||
118 | expectMetrics(t, e, "older_haproxy_versions.metrics") | |
210 | 119 | } |
211 | 120 | |
212 | 121 | func TestConfigChangeDetection(t *testing.T) { |
213 | 122 | h := newHaproxy([]byte("")) |
214 | 123 | defer h.Close() |
215 | 124 | |
216 | e, _ := NewExporter(h.URL, true, serverMetrics, 5*time.Second) | |
125 | e, _ := NewExporter(h.URL, true, serverMetrics, excludedServerStates, 5*time.Second, log.NewNopLogger()) | |
217 | 126 | ch := make(chan prometheus.Metric) |
218 | 127 | |
219 | 128 | go func() { |
240 | 149 | s.Close() |
241 | 150 | }() |
242 | 151 | |
243 | e, err := NewExporter(s.URL, true, serverMetrics, 1*time.Second) | |
244 | if err != nil { | |
245 | t.Fatal(err) | |
246 | } | |
247 | ||
248 | ch := make(chan prometheus.Metric) | |
249 | go func() { | |
250 | defer close(ch) | |
251 | e.Collect(ch) | |
252 | }() | |
253 | ||
254 | if expect, got := 0., readGauge((<-ch).(prometheus.Gauge)); expect != got { | |
255 | // up | |
256 | t.Errorf("expected %f up, got %f", expect, got) | |
257 | } | |
258 | if expect, got := 1., readCounter((<-ch).(prometheus.Counter)); expect != got { | |
259 | // totalScrapes | |
260 | t.Errorf("expected %f recorded scrape, got %f", expect, got) | |
261 | } | |
262 | if expect, got := 0., readCounter((<-ch).(prometheus.Counter)); expect != got { | |
263 | // csvParseFailures | |
264 | t.Errorf("expected %f csv parse failures, got %f", expect, got) | |
265 | } | |
266 | if <-ch != nil { | |
267 | t.Errorf("expected closed channel") | |
268 | } | |
152 | e, err := NewExporter(s.URL, true, serverMetrics, excludedServerStates, 1*time.Second, log.NewNopLogger()) | |
153 | if err != nil { | |
154 | t.Fatal(err) | |
155 | } | |
156 | ||
157 | expectMetrics(t, e, "deadline.metrics") | |
269 | 158 | } |
270 | 159 | |
271 | 160 | func TestNotFound(t *testing.T) { |
272 | 161 | s := httptest.NewServer(http.NotFoundHandler()) |
273 | 162 | defer s.Close() |
274 | 163 | |
275 | e, err := NewExporter(s.URL, true, serverMetrics, 1*time.Second) | |
276 | if err != nil { | |
277 | t.Fatal(err) | |
278 | } | |
279 | ||
280 | ch := make(chan prometheus.Metric) | |
281 | go func() { | |
282 | defer close(ch) | |
283 | e.Collect(ch) | |
284 | }() | |
285 | ||
286 | if expect, got := 0., readGauge((<-ch).(prometheus.Gauge)); expect != got { | |
287 | // up | |
288 | t.Errorf("expected %f up, got %f", expect, got) | |
289 | } | |
290 | } | |
291 | ||
292 | func newHaproxyUnix(file, statsPayload string) (io.Closer, error) { | |
164 | e, err := NewExporter(s.URL, true, serverMetrics, excludedServerStates, 1*time.Second, log.NewNopLogger()) | |
165 | if err != nil { | |
166 | t.Fatal(err) | |
167 | } | |
168 | ||
169 | expectMetrics(t, e, "not_found.metrics") | |
170 | } | |
171 | ||
172 | func newHaproxyUnix(file, statsPayload string, infoPayload string) (io.Closer, error) { | |
293 | 173 | if err := os.Remove(file); err != nil && !os.IsNotExist(err) { |
294 | 174 | return nil, err |
295 | 175 | } |
312 | 192 | return |
313 | 193 | } |
314 | 194 | switch l { |
195 | case "show info\n": | |
196 | c.Write([]byte(infoPayload)) | |
197 | return | |
315 | 198 | case "show stat\n": |
316 | 199 | c.Write([]byte(statsPayload)) |
317 | 200 | return |
331 | 214 | t.Skip("not on windows") |
332 | 215 | return |
333 | 216 | } |
334 | srv, err := newHaproxyUnix(testSocket, "test,127.0.0.1:8080,0,0,0,0,0,0,0,0,,0,,0,0,0,0,no check,1,1,0,0,,,0,,1,1,1,,0,,2,0,,0,,,,0,0,0,0,0,0,0,,,,0,0,,,,,,,,,,,\n") | |
217 | srv, err := newHaproxyUnix(testSocket, "test,127.0.0.1:8080,0,0,0,0,0,0,0,0,,0,,0,0,0,0,no check,1,1,0,0,,,0,,1,1,1,,0,,2,0,,0,,,,0,0,0,0,0,0,0,,,,0,0,,,,,,,,,,,\n", testInfo) | |
335 | 218 | if err != nil { |
336 | 219 | t.Fatalf("can't start test server: %v", err) |
337 | 220 | } |
338 | 221 | defer srv.Close() |
339 | 222 | |
340 | e, err := NewExporter("unix:"+testSocket, true, serverMetrics, 5*time.Second) | |
341 | if err != nil { | |
342 | t.Fatal(err) | |
343 | } | |
344 | ch := make(chan prometheus.Metric) | |
345 | ||
346 | go func() { | |
347 | defer close(ch) | |
348 | e.Collect(ch) | |
349 | }() | |
350 | ||
351 | if expect, got := 1., readGauge((<-ch).(prometheus.Gauge)); expect != got { | |
352 | // up | |
353 | t.Errorf("expected %f up, got %f", expect, got) | |
354 | } | |
355 | if expect, got := 1., readCounter((<-ch).(prometheus.Counter)); expect != got { | |
356 | // totalScrapes | |
357 | t.Errorf("expected %f recorded scrape, got %f", expect, got) | |
358 | } | |
359 | if expect, got := 0., readCounter((<-ch).(prometheus.Counter)); expect != got { | |
360 | // csvParseFailures | |
361 | t.Errorf("expected %f csv parse failures, got %f", expect, got) | |
362 | } | |
363 | ||
364 | got := 0 | |
365 | for range ch { | |
366 | got += 1 | |
367 | } | |
368 | if expect := len(e.serverMetrics) - 1; got != expect { | |
369 | t.Errorf("expected %d metrics, got %d", expect, got) | |
370 | } | |
223 | e, err := NewExporter("unix:"+testSocket, true, serverMetrics, excludedServerStates, 5*time.Second, log.NewNopLogger()) | |
224 | if err != nil { | |
225 | t.Fatal(err) | |
226 | } | |
227 | ||
228 | expectMetrics(t, e, "unix_domain.metrics") | |
371 | 229 | } |
372 | 230 | |
373 | 231 | func TestUnixDomainNotFound(t *testing.T) { |
379 | 237 | if err := os.Remove(testSocket); err != nil && !os.IsNotExist(err) { |
380 | 238 | t.Fatal(err) |
381 | 239 | } |
382 | e, _ := NewExporter("unix:"+testSocket, true, serverMetrics, 1*time.Second) | |
383 | ch := make(chan prometheus.Metric) | |
384 | go func() { | |
385 | defer close(ch) | |
386 | e.Collect(ch) | |
387 | }() | |
388 | ||
389 | if expect, got := 0., readGauge((<-ch).(prometheus.Gauge)); expect != got { | |
390 | // up | |
391 | t.Errorf("expected %f up, got %f", expect, got) | |
392 | } | |
393 | if expect, got := 1., readCounter((<-ch).(prometheus.Counter)); expect != got { | |
394 | // totalScrapes | |
395 | t.Errorf("expected %f recorded scrape, got %f", expect, got) | |
396 | } | |
397 | if expect, got := 0., readCounter((<-ch).(prometheus.Counter)); expect != got { | |
398 | // csvParseFailures | |
399 | t.Errorf("expected %f csv parse failures, got %f", expect, got) | |
400 | } | |
401 | if <-ch != nil { | |
402 | t.Errorf("expected closed channel") | |
403 | } | |
240 | e, _ := NewExporter("unix:"+testSocket, true, serverMetrics, excludedServerStates, 1*time.Second, log.NewNopLogger()) | |
241 | expectMetrics(t, e, "unix_domain_not_found.metrics") | |
404 | 242 | } |
405 | 243 | |
406 | 244 | func TestUnixDomainDeadline(t *testing.T) { |
432 | 270 | } |
433 | 271 | }() |
434 | 272 | |
435 | e, _ := NewExporter("unix:"+testSocket, true, serverMetrics, 1*time.Second) | |
436 | ch := make(chan prometheus.Metric) | |
437 | go func() { | |
438 | defer close(ch) | |
439 | e.Collect(ch) | |
440 | }() | |
441 | ||
442 | if expect, got := 0., readGauge((<-ch).(prometheus.Gauge)); expect != got { | |
443 | // up | |
444 | t.Errorf("expected %f up, got %f", expect, got) | |
445 | } | |
446 | if expect, got := 1., readCounter((<-ch).(prometheus.Counter)); expect != got { | |
447 | // totalScrapes | |
448 | t.Errorf("expected %f recorded scrape, got %f", expect, got) | |
449 | } | |
450 | if expect, got := 0., readCounter((<-ch).(prometheus.Counter)); expect != got { | |
451 | // csvParseFailures | |
452 | t.Errorf("expected %f csv parse failures, got %f", expect, got) | |
453 | } | |
454 | if <-ch != nil { | |
455 | t.Errorf("expected closed channel") | |
456 | } | |
273 | e, _ := NewExporter("unix:"+testSocket, true, serverMetrics, excludedServerStates, 1*time.Second, log.NewNopLogger()) | |
274 | ||
275 | expectMetrics(t, e, "unix_domain_deadline.metrics") | |
457 | 276 | } |
458 | 277 | |
459 | 278 | func TestInvalidScheme(t *testing.T) { |
460 | e, err := NewExporter("gopher://gopher.quux.org", true, serverMetrics, 1*time.Second) | |
279 | e, err := NewExporter("gopher://gopher.quux.org", true, serverMetrics, excludedServerStates, 1*time.Second, log.NewNopLogger()) | |
461 | 280 | if expect, got := (*Exporter)(nil), e; expect != got { |
462 | 281 | t.Errorf("expected %v, got %v", expect, got) |
463 | 282 | } |
500 | 319 | func TestFilterServerMetrics(t *testing.T) { |
501 | 320 | tests := []struct { |
502 | 321 | input string |
503 | want map[int]*prometheus.GaugeVec | |
322 | want map[int]metricInfo | |
504 | 323 | }{ |
505 | {input: "", want: map[int]*prometheus.GaugeVec{}}, | |
506 | {input: "8", want: map[int]*prometheus.GaugeVec{8: serverMetrics[8]}}, | |
324 | {input: "", want: map[int]metricInfo{}}, | |
325 | {input: "8", want: map[int]metricInfo{8: metricInfo{Desc: serverMetrics[8].Desc, Type: prometheus.CounterValue}}}, | |
507 | 326 | {input: serverMetrics.String(), want: serverMetrics}, |
508 | 327 | } |
509 | 328 | |
532 | 351 | h := newHaproxy(config) |
533 | 352 | defer h.Close() |
534 | 353 | |
535 | e, _ := NewExporter(h.URL, true, serverMetrics, 5*time.Second) | |
354 | e, _ := NewExporter(h.URL, true, serverMetrics, excludedServerStates, 5*time.Second, log.NewNopLogger()) | |
536 | 355 | |
537 | 356 | var before, after runtime.MemStats |
538 | 357 | runtime.GC() |
0 | # HELP haproxy_exporter_csv_parse_failures_total Number of errors while parsing CSV. | |
1 | # TYPE haproxy_exporter_csv_parse_failures_total counter | |
2 | haproxy_exporter_csv_parse_failures_total 0 | |
3 | # HELP haproxy_exporter_scrapes_total Current total HAProxy scrapes. | |
4 | # TYPE haproxy_exporter_scrapes_total counter | |
5 | haproxy_exporter_scrapes_total 1 | |
6 | # HELP haproxy_up Was the last scrape of HAProxy successful. | |
7 | # TYPE haproxy_up gauge | |
8 | haproxy_up 0 |
0 | # HELP haproxy_exporter_csv_parse_failures_total Number of errors while parsing CSV. | |
1 | # TYPE haproxy_exporter_csv_parse_failures_total counter | |
2 | haproxy_exporter_csv_parse_failures_total 1 | |
3 | # HELP haproxy_exporter_scrapes_total Current total HAProxy scrapes. | |
4 | # TYPE haproxy_exporter_scrapes_total counter | |
5 | haproxy_exporter_scrapes_total 1 | |
6 | # HELP haproxy_up Was the last scrape of HAProxy successful. | |
7 | # TYPE haproxy_up gauge | |
8 | haproxy_up 1 |
0 | # HELP haproxy_exporter_csv_parse_failures_total Number of errors while parsing CSV. | |
1 | # TYPE haproxy_exporter_csv_parse_failures_total counter | |
2 | haproxy_exporter_csv_parse_failures_total 0 | |
3 | # HELP haproxy_exporter_scrapes_total Current total HAProxy scrapes. | |
4 | # TYPE haproxy_exporter_scrapes_total counter | |
5 | haproxy_exporter_scrapes_total 1 | |
6 | # HELP haproxy_up Was the last scrape of HAProxy successful. | |
7 | # TYPE haproxy_up gauge | |
8 | haproxy_up 0 |
0 | # HELP haproxy_exporter_csv_parse_failures_total Number of errors while parsing CSV. | |
1 | # TYPE haproxy_exporter_csv_parse_failures_total counter | |
2 | haproxy_exporter_csv_parse_failures_total 0 | |
3 | # HELP haproxy_exporter_scrapes_total Current total HAProxy scrapes. | |
4 | # TYPE haproxy_exporter_scrapes_total counter | |
5 | haproxy_exporter_scrapes_total 1 | |
6 | # HELP haproxy_server_bytes_in_total Current total of incoming bytes. | |
7 | # TYPE haproxy_server_bytes_in_total counter | |
8 | haproxy_server_bytes_in_total{backend="foo",server="BACKEND"} 0 | |
9 | haproxy_server_bytes_in_total{backend="foo",server="FRONTEND"} 0 | |
10 | haproxy_server_bytes_in_total{backend="foo",server="foo-instance-0"} 0 | |
11 | # HELP haproxy_server_bytes_out_total Current total of outgoing bytes. | |
12 | # TYPE haproxy_server_bytes_out_total counter | |
13 | haproxy_server_bytes_out_total{backend="foo",server="BACKEND"} 0 | |
14 | haproxy_server_bytes_out_total{backend="foo",server="FRONTEND"} 0 | |
15 | haproxy_server_bytes_out_total{backend="foo",server="foo-instance-0"} 0 | |
16 | # HELP haproxy_server_check_failures_total Total number of failed health checks. | |
17 | # TYPE haproxy_server_check_failures_total counter | |
18 | haproxy_server_check_failures_total{backend="foo",server="BACKEND"} 0 | |
19 | haproxy_server_check_failures_total{backend="foo",server="FRONTEND"} 0 | |
20 | haproxy_server_check_failures_total{backend="foo",server="foo-instance-0"} 0 | |
21 | # HELP haproxy_server_connection_errors_total Total of connection errors. | |
22 | # TYPE haproxy_server_connection_errors_total counter | |
23 | haproxy_server_connection_errors_total{backend="foo",server="BACKEND"} 0 | |
24 | haproxy_server_connection_errors_total{backend="foo",server="FRONTEND"} 0 | |
25 | haproxy_server_connection_errors_total{backend="foo",server="foo-instance-0"} 0 | |
26 | # HELP haproxy_server_current_queue Current number of queued requests assigned to this server. | |
27 | # TYPE haproxy_server_current_queue gauge | |
28 | haproxy_server_current_queue{backend="foo",server="BACKEND"} 0 | |
29 | haproxy_server_current_queue{backend="foo",server="FRONTEND"} 0 | |
30 | haproxy_server_current_queue{backend="foo",server="foo-instance-0"} 0 | |
31 | # HELP haproxy_server_current_sessions Current number of active sessions. | |
32 | # TYPE haproxy_server_current_sessions gauge | |
33 | haproxy_server_current_sessions{backend="foo",server="BACKEND"} 0 | |
34 | haproxy_server_current_sessions{backend="foo",server="FRONTEND"} 0 | |
35 | haproxy_server_current_sessions{backend="foo",server="foo-instance-0"} 0 | |
36 | # HELP haproxy_server_downtime_seconds_total Total downtime in seconds. | |
37 | # TYPE haproxy_server_downtime_seconds_total counter | |
38 | haproxy_server_downtime_seconds_total{backend="foo",server="BACKEND"} 0 | |
39 | haproxy_server_downtime_seconds_total{backend="foo",server="FRONTEND"} 0 | |
40 | haproxy_server_downtime_seconds_total{backend="foo",server="foo-instance-0"} 0 | |
41 | # HELP haproxy_server_max_queue Maximum observed number of queued requests assigned to this server. | |
42 | # TYPE haproxy_server_max_queue gauge | |
43 | haproxy_server_max_queue{backend="foo",server="BACKEND"} 0 | |
44 | haproxy_server_max_queue{backend="foo",server="FRONTEND"} 0 | |
45 | haproxy_server_max_queue{backend="foo",server="foo-instance-0"} 0 | |
46 | # HELP haproxy_server_max_sessions Maximum observed number of active sessions. | |
47 | # TYPE haproxy_server_max_sessions gauge | |
48 | haproxy_server_max_sessions{backend="foo",server="BACKEND"} 0 | |
49 | haproxy_server_max_sessions{backend="foo",server="FRONTEND"} 0 | |
50 | haproxy_server_max_sessions{backend="foo",server="foo-instance-0"} 0 | |
51 | # HELP haproxy_server_redispatch_warnings_total Total of redispatch warnings. | |
52 | # TYPE haproxy_server_redispatch_warnings_total counter | |
53 | haproxy_server_redispatch_warnings_total{backend="foo",server="BACKEND"} 0 | |
54 | haproxy_server_redispatch_warnings_total{backend="foo",server="FRONTEND"} 0 | |
55 | haproxy_server_redispatch_warnings_total{backend="foo",server="foo-instance-0"} 0 | |
56 | # HELP haproxy_server_response_errors_total Total of response errors. | |
57 | # TYPE haproxy_server_response_errors_total counter | |
58 | haproxy_server_response_errors_total{backend="foo",server="BACKEND"} 0 | |
59 | haproxy_server_response_errors_total{backend="foo",server="FRONTEND"} 0 | |
60 | haproxy_server_response_errors_total{backend="foo",server="foo-instance-0"} 0 | |
61 | # HELP haproxy_server_retry_warnings_total Total of retry warnings. | |
62 | # TYPE haproxy_server_retry_warnings_total counter | |
63 | haproxy_server_retry_warnings_total{backend="foo",server="BACKEND"} 0 | |
64 | haproxy_server_retry_warnings_total{backend="foo",server="FRONTEND"} 0 | |
65 | haproxy_server_retry_warnings_total{backend="foo",server="foo-instance-0"} 0 | |
66 | # HELP haproxy_server_server_selected_total Total number of times a server was selected, either for new sessions, or when re-dispatching. | |
67 | # TYPE haproxy_server_server_selected_total counter | |
68 | haproxy_server_server_selected_total{backend="foo",server="BACKEND"} 0 | |
69 | haproxy_server_server_selected_total{backend="foo",server="FRONTEND"} 0 | |
70 | haproxy_server_server_selected_total{backend="foo",server="foo-instance-0"} 0 | |
71 | # HELP haproxy_server_sessions_total Total number of sessions. | |
72 | # TYPE haproxy_server_sessions_total counter | |
73 | haproxy_server_sessions_total{backend="foo",server="BACKEND"} 0 | |
74 | haproxy_server_sessions_total{backend="foo",server="FRONTEND"} 0 | |
75 | haproxy_server_sessions_total{backend="foo",server="foo-instance-0"} 0 | |
76 | # HELP haproxy_server_up Current health status of the server (1 = UP, 0 = DOWN). | |
77 | # TYPE haproxy_server_up gauge | |
78 | haproxy_server_up{backend="foo",server="BACKEND"} 1 | |
79 | haproxy_server_up{backend="foo",server="FRONTEND"} 1 | |
80 | haproxy_server_up{backend="foo",server="foo-instance-0"} 1 | |
81 | # HELP haproxy_server_weight Current weight of the server. | |
82 | # TYPE haproxy_server_weight gauge | |
83 | haproxy_server_weight{backend="foo",server="BACKEND"} 1 | |
84 | haproxy_server_weight{backend="foo",server="FRONTEND"} 1 | |
85 | haproxy_server_weight{backend="foo",server="foo-instance-0"} 1 | |
86 | # HELP haproxy_up Was the last scrape of HAProxy successful. | |
87 | # TYPE haproxy_up gauge | |
88 | haproxy_up 1 |
0 | # HELP haproxy_exporter_csv_parse_failures_total Number of errors while parsing CSV. | |
1 | # TYPE haproxy_exporter_csv_parse_failures_total counter | |
2 | haproxy_exporter_csv_parse_failures_total 1 | |
3 | # HELP haproxy_exporter_scrapes_total Current total HAProxy scrapes. | |
4 | # TYPE haproxy_exporter_scrapes_total counter | |
5 | haproxy_exporter_scrapes_total 1 | |
6 | # HELP haproxy_server_bytes_in_total Current total of incoming bytes. | |
7 | # TYPE haproxy_server_bytes_in_total counter | |
8 | haproxy_server_bytes_in_total{backend="foo",server="BACKEND"} 0 | |
9 | haproxy_server_bytes_in_total{backend="foo",server="FRONTEND"} 0 | |
10 | haproxy_server_bytes_in_total{backend="foo",server="foo-instance-0"} 0 | |
11 | # HELP haproxy_server_bytes_out_total Current total of outgoing bytes. | |
12 | # TYPE haproxy_server_bytes_out_total counter | |
13 | haproxy_server_bytes_out_total{backend="foo",server="BACKEND"} 0 | |
14 | haproxy_server_bytes_out_total{backend="foo",server="FRONTEND"} 0 | |
15 | haproxy_server_bytes_out_total{backend="foo",server="foo-instance-0"} 0 | |
16 | # HELP haproxy_server_check_duration_seconds Previously run health check duration, in seconds | |
17 | # TYPE haproxy_server_check_duration_seconds gauge | |
18 | haproxy_server_check_duration_seconds{backend="foo",server="BACKEND"} 0 | |
19 | haproxy_server_check_duration_seconds{backend="foo",server="FRONTEND"} 0 | |
20 | haproxy_server_check_duration_seconds{backend="foo",server="foo-instance-0"} 0 | |
21 | # HELP haproxy_server_check_failures_total Total number of failed health checks. | |
22 | # TYPE haproxy_server_check_failures_total counter | |
23 | haproxy_server_check_failures_total{backend="foo",server="BACKEND"} 0 | |
24 | haproxy_server_check_failures_total{backend="foo",server="FRONTEND"} 0 | |
25 | haproxy_server_check_failures_total{backend="foo",server="foo-instance-0"} 0 | |
26 | # HELP haproxy_server_client_aborts_total Total number of data transfers aborted by the client. | |
27 | # TYPE haproxy_server_client_aborts_total counter | |
28 | haproxy_server_client_aborts_total{backend="foo",server="BACKEND"} 0 | |
29 | haproxy_server_client_aborts_total{backend="foo",server="FRONTEND"} 0 | |
30 | haproxy_server_client_aborts_total{backend="foo",server="foo-instance-0"} 0 | |
31 | # HELP haproxy_server_connection_errors_total Total of connection errors. | |
32 | # TYPE haproxy_server_connection_errors_total counter | |
33 | haproxy_server_connection_errors_total{backend="foo",server="BACKEND"} 0 | |
34 | haproxy_server_connection_errors_total{backend="foo",server="FRONTEND"} 0 | |
35 | haproxy_server_connection_errors_total{backend="foo",server="foo-instance-0"} 0 | |
36 | # HELP haproxy_server_current_queue Current number of queued requests assigned to this server. | |
37 | # TYPE haproxy_server_current_queue gauge | |
38 | haproxy_server_current_queue{backend="foo",server="BACKEND"} 0 | |
39 | haproxy_server_current_queue{backend="foo",server="FRONTEND"} 0 | |
40 | haproxy_server_current_queue{backend="foo",server="foo-instance-0"} 0 | |
41 | # HELP haproxy_server_current_session_rate Current number of sessions per second over last elapsed second. | |
42 | # TYPE haproxy_server_current_session_rate gauge | |
43 | haproxy_server_current_session_rate{backend="foo",server="BACKEND"} 0 | |
44 | haproxy_server_current_session_rate{backend="foo",server="FRONTEND"} 0 | |
45 | haproxy_server_current_session_rate{backend="foo",server="foo-instance-0"} 0 | |
46 | # HELP haproxy_server_current_sessions Current number of active sessions. | |
47 | # TYPE haproxy_server_current_sessions gauge | |
48 | haproxy_server_current_sessions{backend="foo",server="BACKEND"} 0 | |
49 | haproxy_server_current_sessions{backend="foo",server="FRONTEND"} 0 | |
50 | haproxy_server_current_sessions{backend="foo",server="foo-instance-0"} 0 | |
51 | # HELP haproxy_server_downtime_seconds_total Total downtime in seconds. | |
52 | # TYPE haproxy_server_downtime_seconds_total counter | |
53 | haproxy_server_downtime_seconds_total{backend="foo",server="BACKEND"} 0 | |
54 | haproxy_server_downtime_seconds_total{backend="foo",server="FRONTEND"} 0 | |
55 | haproxy_server_downtime_seconds_total{backend="foo",server="foo-instance-0"} 0 | |
56 | # HELP haproxy_server_max_queue Maximum observed number of queued requests assigned to this server. | |
57 | # TYPE haproxy_server_max_queue gauge | |
58 | haproxy_server_max_queue{backend="foo",server="BACKEND"} 0 | |
59 | haproxy_server_max_queue{backend="foo",server="FRONTEND"} 0 | |
60 | haproxy_server_max_queue{backend="foo",server="foo-instance-0"} 0 | |
61 | # HELP haproxy_server_max_session_rate Maximum observed number of sessions per second. | |
62 | # TYPE haproxy_server_max_session_rate gauge | |
63 | haproxy_server_max_session_rate{backend="foo",server="BACKEND"} 0 | |
64 | haproxy_server_max_session_rate{backend="foo",server="FRONTEND"} 0 | |
65 | haproxy_server_max_session_rate{backend="foo",server="foo-instance-0"} 0 | |
66 | # HELP haproxy_server_max_sessions Maximum observed number of active sessions. | |
67 | # TYPE haproxy_server_max_sessions gauge | |
68 | haproxy_server_max_sessions{backend="foo",server="BACKEND"} 0 | |
69 | haproxy_server_max_sessions{backend="foo",server="FRONTEND"} 0 | |
70 | haproxy_server_max_sessions{backend="foo",server="foo-instance-0"} 0 | |
71 | # HELP haproxy_server_redispatch_warnings_total Total of redispatch warnings. | |
72 | # TYPE haproxy_server_redispatch_warnings_total counter | |
73 | haproxy_server_redispatch_warnings_total{backend="foo",server="BACKEND"} 0 | |
74 | haproxy_server_redispatch_warnings_total{backend="foo",server="FRONTEND"} 0 | |
75 | haproxy_server_redispatch_warnings_total{backend="foo",server="foo-instance-0"} 0 | |
76 | # HELP haproxy_server_response_errors_total Total of response errors. | |
77 | # TYPE haproxy_server_response_errors_total counter | |
78 | haproxy_server_response_errors_total{backend="foo",server="BACKEND"} 0 | |
79 | haproxy_server_response_errors_total{backend="foo",server="FRONTEND"} 0 | |
80 | haproxy_server_response_errors_total{backend="foo",server="foo-instance-0"} 0 | |
81 | # HELP haproxy_server_retry_warnings_total Total of retry warnings. | |
82 | # TYPE haproxy_server_retry_warnings_total counter | |
83 | haproxy_server_retry_warnings_total{backend="foo",server="BACKEND"} 0 | |
84 | haproxy_server_retry_warnings_total{backend="foo",server="FRONTEND"} 0 | |
85 | haproxy_server_retry_warnings_total{backend="foo",server="foo-instance-0"} 0 | |
86 | # HELP haproxy_server_server_aborts_total Total number of data transfers aborted by the server. | |
87 | # TYPE haproxy_server_server_aborts_total counter | |
88 | haproxy_server_server_aborts_total{backend="foo",server="BACKEND"} 0 | |
89 | haproxy_server_server_aborts_total{backend="foo",server="FRONTEND"} 0 | |
90 | haproxy_server_server_aborts_total{backend="foo",server="foo-instance-0"} 0 | |
91 | # HELP haproxy_server_server_selected_total Total number of times a server was selected, either for new sessions, or when re-dispatching. | |
92 | # TYPE haproxy_server_server_selected_total counter | |
93 | haproxy_server_server_selected_total{backend="foo",server="BACKEND"} 0 | |
94 | haproxy_server_server_selected_total{backend="foo",server="FRONTEND"} 0 | |
95 | haproxy_server_server_selected_total{backend="foo",server="foo-instance-0"} 0 | |
96 | # HELP haproxy_server_sessions_total Total number of sessions. | |
97 | # TYPE haproxy_server_sessions_total counter | |
98 | haproxy_server_sessions_total{backend="foo",server="BACKEND"} 0 | |
99 | haproxy_server_sessions_total{backend="foo",server="FRONTEND"} 0 | |
100 | haproxy_server_sessions_total{backend="foo",server="foo-instance-0"} 0 | |
101 | # HELP haproxy_server_up Current health status of the server (1 = UP, 0 = DOWN). | |
102 | # TYPE haproxy_server_up gauge | |
103 | haproxy_server_up{backend="foo",server="BACKEND"} 1 | |
104 | haproxy_server_up{backend="foo",server="FRONTEND"} 1 | |
105 | haproxy_server_up{backend="foo",server="foo-instance-0"} 1 | |
106 | # HELP haproxy_server_weight Current weight of the server. | |
107 | # TYPE haproxy_server_weight gauge | |
108 | haproxy_server_weight{backend="foo",server="BACKEND"} 1 | |
109 | haproxy_server_weight{backend="foo",server="FRONTEND"} 1 | |
110 | haproxy_server_weight{backend="foo",server="foo-instance-0"} 1 | |
111 | # HELP haproxy_up Was the last scrape of HAProxy successful. | |
112 | # TYPE haproxy_up gauge | |
113 | haproxy_up 1 |
0 | # HELP haproxy_exporter_csv_parse_failures_total Number of errors while parsing CSV. | |
1 | # TYPE haproxy_exporter_csv_parse_failures_total counter | |
2 | haproxy_exporter_csv_parse_failures_total 0 | |
3 | # HELP haproxy_exporter_scrapes_total Current total HAProxy scrapes. | |
4 | # TYPE haproxy_exporter_scrapes_total counter | |
5 | haproxy_exporter_scrapes_total 1 | |
6 | # HELP haproxy_server_bytes_in_total Current total of incoming bytes. | |
7 | # TYPE haproxy_server_bytes_in_total counter | |
8 | haproxy_server_bytes_in_total{backend="test",server="127.0.0.1:8080"} 0 | |
9 | # HELP haproxy_server_bytes_out_total Current total of outgoing bytes. | |
10 | # TYPE haproxy_server_bytes_out_total counter | |
11 | haproxy_server_bytes_out_total{backend="test",server="127.0.0.1:8080"} 0 | |
12 | # HELP haproxy_server_check_failures_total Total number of failed health checks. | |
13 | # TYPE haproxy_server_check_failures_total counter | |
14 | haproxy_server_check_failures_total{backend="test",server="127.0.0.1:8080"} 0 | |
15 | # HELP haproxy_server_client_aborts_total Total number of data transfers aborted by the client. | |
16 | # TYPE haproxy_server_client_aborts_total counter | |
17 | haproxy_server_client_aborts_total{backend="test",server="127.0.0.1:8080"} 0 | |
18 | # HELP haproxy_server_connection_errors_total Total of connection errors. | |
19 | # TYPE haproxy_server_connection_errors_total counter | |
20 | haproxy_server_connection_errors_total{backend="test",server="127.0.0.1:8080"} 0 | |
21 | # HELP haproxy_server_current_queue Current number of queued requests assigned to this server. | |
22 | # TYPE haproxy_server_current_queue gauge | |
23 | haproxy_server_current_queue{backend="test",server="127.0.0.1:8080"} 0 | |
24 | # HELP haproxy_server_current_session_rate Current number of sessions per second over last elapsed second. | |
25 | # TYPE haproxy_server_current_session_rate gauge | |
26 | haproxy_server_current_session_rate{backend="test",server="127.0.0.1:8080"} 0 | |
27 | # HELP haproxy_server_current_sessions Current number of active sessions. | |
28 | # TYPE haproxy_server_current_sessions gauge | |
29 | haproxy_server_current_sessions{backend="test",server="127.0.0.1:8080"} 0 | |
30 | # HELP haproxy_server_downtime_seconds_total Total downtime in seconds. | |
31 | # TYPE haproxy_server_downtime_seconds_total counter | |
32 | haproxy_server_downtime_seconds_total{backend="test",server="127.0.0.1:8080"} 0 | |
33 | # HELP haproxy_server_http_responses_total Total of HTTP responses. | |
34 | # TYPE haproxy_server_http_responses_total counter | |
35 | haproxy_server_http_responses_total{backend="test",code="1xx",server="127.0.0.1:8080"} 0 | |
36 | haproxy_server_http_responses_total{backend="test",code="2xx",server="127.0.0.1:8080"} 0 | |
37 | haproxy_server_http_responses_total{backend="test",code="3xx",server="127.0.0.1:8080"} 0 | |
38 | haproxy_server_http_responses_total{backend="test",code="4xx",server="127.0.0.1:8080"} 0 | |
39 | haproxy_server_http_responses_total{backend="test",code="5xx",server="127.0.0.1:8080"} 0 | |
40 | haproxy_server_http_responses_total{backend="test",code="other",server="127.0.0.1:8080"} 0 | |
41 | # HELP haproxy_server_limit_sessions Configured session limit. | |
42 | # TYPE haproxy_server_limit_sessions gauge | |
43 | haproxy_server_limit_sessions{backend="test",server="127.0.0.1:8080"} 0 | |
44 | # HELP haproxy_server_max_queue Maximum observed number of queued requests assigned to this server. | |
45 | # TYPE haproxy_server_max_queue gauge | |
46 | haproxy_server_max_queue{backend="test",server="127.0.0.1:8080"} 0 | |
47 | # HELP haproxy_server_max_session_rate Maximum observed number of sessions per second. | |
48 | # TYPE haproxy_server_max_session_rate gauge | |
49 | haproxy_server_max_session_rate{backend="test",server="127.0.0.1:8080"} 0 | |
50 | # HELP haproxy_server_max_sessions Maximum observed number of active sessions. | |
51 | # TYPE haproxy_server_max_sessions gauge | |
52 | haproxy_server_max_sessions{backend="test",server="127.0.0.1:8080"} 0 | |
53 | # HELP haproxy_server_redispatch_warnings_total Total of redispatch warnings. | |
54 | # TYPE haproxy_server_redispatch_warnings_total counter | |
55 | haproxy_server_redispatch_warnings_total{backend="test",server="127.0.0.1:8080"} 0 | |
56 | # HELP haproxy_server_response_errors_total Total of response errors. | |
57 | # TYPE haproxy_server_response_errors_total counter | |
58 | haproxy_server_response_errors_total{backend="test",server="127.0.0.1:8080"} 0 | |
59 | # HELP haproxy_server_retry_warnings_total Total of retry warnings. | |
60 | # TYPE haproxy_server_retry_warnings_total counter | |
61 | haproxy_server_retry_warnings_total{backend="test",server="127.0.0.1:8080"} 0 | |
62 | # HELP haproxy_server_server_aborts_total Total number of data transfers aborted by the server. | |
63 | # TYPE haproxy_server_server_aborts_total counter | |
64 | haproxy_server_server_aborts_total{backend="test",server="127.0.0.1:8080"} 0 | |
65 | # HELP haproxy_server_server_selected_total Total number of times a server was selected, either for new sessions, or when re-dispatching. | |
66 | # TYPE haproxy_server_server_selected_total counter | |
67 | haproxy_server_server_selected_total{backend="test",server="127.0.0.1:8080"} 0 | |
68 | # HELP haproxy_server_sessions_total Total number of sessions. | |
69 | # TYPE haproxy_server_sessions_total counter | |
70 | haproxy_server_sessions_total{backend="test",server="127.0.0.1:8080"} 0 | |
71 | # HELP haproxy_server_up Current health status of the server (1 = UP, 0 = DOWN). | |
72 | # TYPE haproxy_server_up gauge | |
73 | haproxy_server_up{backend="test",server="127.0.0.1:8080"} 1 | |
74 | # HELP haproxy_server_weight Current weight of the server. | |
75 | # TYPE haproxy_server_weight gauge | |
76 | haproxy_server_weight{backend="test",server="127.0.0.1:8080"} 1 | |
77 | # HELP haproxy_up Was the last scrape of HAProxy successful. | |
78 | # TYPE haproxy_up gauge | |
79 | haproxy_up 1 |
0 | # HELP haproxy_exporter_csv_parse_failures_total Number of errors while parsing CSV. | |
1 | # TYPE haproxy_exporter_csv_parse_failures_total counter | |
2 | haproxy_exporter_csv_parse_failures_total 0 | |
3 | # HELP haproxy_exporter_scrapes_total Current total HAProxy scrapes. | |
4 | # TYPE haproxy_exporter_scrapes_total counter | |
5 | haproxy_exporter_scrapes_total 1 | |
6 | # HELP haproxy_server_bytes_in_total Current total of incoming bytes. | |
7 | # TYPE haproxy_server_bytes_in_total counter | |
8 | haproxy_server_bytes_in_total{backend="test",server="127.0.0.1:8080"} 0 | |
9 | # HELP haproxy_server_bytes_out_total Current total of outgoing bytes. | |
10 | # TYPE haproxy_server_bytes_out_total counter | |
11 | haproxy_server_bytes_out_total{backend="test",server="127.0.0.1:8080"} 0 | |
12 | # HELP haproxy_server_check_failures_total Total number of failed health checks. | |
13 | # TYPE haproxy_server_check_failures_total counter | |
14 | haproxy_server_check_failures_total{backend="test",server="127.0.0.1:8080"} 0 | |
15 | # HELP haproxy_server_client_aborts_total Total number of data transfers aborted by the client. | |
16 | # TYPE haproxy_server_client_aborts_total counter | |
17 | haproxy_server_client_aborts_total{backend="test",server="127.0.0.1:8080"} 0 | |
18 | # HELP haproxy_server_connection_errors_total Total of connection errors. | |
19 | # TYPE haproxy_server_connection_errors_total counter | |
20 | haproxy_server_connection_errors_total{backend="test",server="127.0.0.1:8080"} 0 | |
21 | # HELP haproxy_server_current_queue Current number of queued requests assigned to this server. | |
22 | # TYPE haproxy_server_current_queue gauge | |
23 | haproxy_server_current_queue{backend="test",server="127.0.0.1:8080"} 0 | |
24 | # HELP haproxy_server_current_session_rate Current number of sessions per second over last elapsed second. | |
25 | # TYPE haproxy_server_current_session_rate gauge | |
26 | haproxy_server_current_session_rate{backend="test",server="127.0.0.1:8080"} 0 | |
27 | # HELP haproxy_server_current_sessions Current number of active sessions. | |
28 | # TYPE haproxy_server_current_sessions gauge | |
29 | haproxy_server_current_sessions{backend="test",server="127.0.0.1:8080"} 0 | |
30 | # HELP haproxy_server_downtime_seconds_total Total downtime in seconds. | |
31 | # TYPE haproxy_server_downtime_seconds_total counter | |
32 | haproxy_server_downtime_seconds_total{backend="test",server="127.0.0.1:8080"} 0 | |
33 | # HELP haproxy_server_http_responses_total Total of HTTP responses. | |
34 | # TYPE haproxy_server_http_responses_total counter | |
35 | haproxy_server_http_responses_total{backend="test",code="1xx",server="127.0.0.1:8080"} 0 | |
36 | haproxy_server_http_responses_total{backend="test",code="2xx",server="127.0.0.1:8080"} 0 | |
37 | haproxy_server_http_responses_total{backend="test",code="3xx",server="127.0.0.1:8080"} 0 | |
38 | haproxy_server_http_responses_total{backend="test",code="4xx",server="127.0.0.1:8080"} 0 | |
39 | haproxy_server_http_responses_total{backend="test",code="5xx",server="127.0.0.1:8080"} 0 | |
40 | haproxy_server_http_responses_total{backend="test",code="other",server="127.0.0.1:8080"} 0 | |
41 | # HELP haproxy_server_limit_sessions Configured session limit. | |
42 | # TYPE haproxy_server_limit_sessions gauge | |
43 | haproxy_server_limit_sessions{backend="test",server="127.0.0.1:8080"} 0 | |
44 | # HELP haproxy_server_max_queue Maximum observed number of queued requests assigned to this server. | |
45 | # TYPE haproxy_server_max_queue gauge | |
46 | haproxy_server_max_queue{backend="test",server="127.0.0.1:8080"} 0 | |
47 | # HELP haproxy_server_max_session_rate Maximum observed number of sessions per second. | |
48 | # TYPE haproxy_server_max_session_rate gauge | |
49 | haproxy_server_max_session_rate{backend="test",server="127.0.0.1:8080"} 0 | |
50 | # HELP haproxy_server_max_sessions Maximum observed number of active sessions. | |
51 | # TYPE haproxy_server_max_sessions gauge | |
52 | haproxy_server_max_sessions{backend="test",server="127.0.0.1:8080"} 0 | |
53 | # HELP haproxy_server_redispatch_warnings_total Total of redispatch warnings. | |
54 | # TYPE haproxy_server_redispatch_warnings_total counter | |
55 | haproxy_server_redispatch_warnings_total{backend="test",server="127.0.0.1:8080"} 0 | |
56 | # HELP haproxy_server_response_errors_total Total of response errors. | |
57 | # TYPE haproxy_server_response_errors_total counter | |
58 | haproxy_server_response_errors_total{backend="test",server="127.0.0.1:8080"} 0 | |
59 | # HELP haproxy_server_retry_warnings_total Total of retry warnings. | |
60 | # TYPE haproxy_server_retry_warnings_total counter | |
61 | haproxy_server_retry_warnings_total{backend="test",server="127.0.0.1:8080"} 0 | |
62 | # HELP haproxy_server_server_aborts_total Total number of data transfers aborted by the server. | |
63 | # TYPE haproxy_server_server_aborts_total counter | |
64 | haproxy_server_server_aborts_total{backend="test",server="127.0.0.1:8080"} 0 | |
65 | # HELP haproxy_server_server_selected_total Total number of times a server was selected, either for new sessions, or when re-dispatching. | |
66 | # TYPE haproxy_server_server_selected_total counter | |
67 | haproxy_server_server_selected_total{backend="test",server="127.0.0.1:8080"} 0 | |
68 | # HELP haproxy_server_sessions_total Total number of sessions. | |
69 | # TYPE haproxy_server_sessions_total counter | |
70 | haproxy_server_sessions_total{backend="test",server="127.0.0.1:8080"} 0 | |
71 | # HELP haproxy_server_up Current health status of the server (1 = UP, 0 = DOWN). | |
72 | # TYPE haproxy_server_up gauge | |
73 | haproxy_server_up{backend="test",server="127.0.0.1:8080"} 1 | |
74 | # HELP haproxy_server_weight Current weight of the server. | |
75 | # TYPE haproxy_server_weight gauge | |
76 | haproxy_server_weight{backend="test",server="127.0.0.1:8080"} 1 | |
77 | # HELP haproxy_up Was the last scrape of HAProxy successful. | |
78 | # TYPE haproxy_up gauge | |
79 | haproxy_up 1 | |
80 | # HELP haproxy_version_info HAProxy version info. | |
81 | # TYPE haproxy_version_info gauge | |
82 | haproxy_version_info{release_date="test date",version="test version"} 1 |
0 | # HELP haproxy_exporter_csv_parse_failures_total Number of errors while parsing CSV. | |
1 | # TYPE haproxy_exporter_csv_parse_failures_total counter | |
2 | haproxy_exporter_csv_parse_failures_total 0 | |
3 | # HELP haproxy_exporter_scrapes_total Current total HAProxy scrapes. | |
4 | # TYPE haproxy_exporter_scrapes_total counter | |
5 | haproxy_exporter_scrapes_total 1 | |
6 | # HELP haproxy_up Was the last scrape of HAProxy successful. | |
7 | # TYPE haproxy_up gauge | |
8 | haproxy_up 0 |
0 | # HELP haproxy_exporter_csv_parse_failures_total Number of errors while parsing CSV. | |
1 | # TYPE haproxy_exporter_csv_parse_failures_total counter | |
2 | haproxy_exporter_csv_parse_failures_total 0 | |
3 | # HELP haproxy_exporter_scrapes_total Current total HAProxy scrapes. | |
4 | # TYPE haproxy_exporter_scrapes_total counter | |
5 | haproxy_exporter_scrapes_total 1 | |
6 | # HELP haproxy_up Was the last scrape of HAProxy successful. | |
7 | # TYPE haproxy_up gauge | |
8 | haproxy_up 0 |
0 | { | |
1 | "comment": "", | |
2 | "ignore": "test", | |
3 | "package": [ | |
4 | { | |
5 | "checksumSHA1": "KmjnydoAbofMieIWm+it5OWERaM=", | |
6 | "path": "github.com/alecthomas/template", | |
7 | "revision": "a0175ee3bccc567396460bf5acd36800cb10c49c", | |
8 | "revisionTime": "2016-04-05T07:15:01Z" | |
9 | }, | |
10 | { | |
11 | "checksumSHA1": "3wt0pTXXeS+S93unwhGoLIyGX/Q=", | |
12 | "path": "github.com/alecthomas/template/parse", | |
13 | "revision": "a0175ee3bccc567396460bf5acd36800cb10c49c", | |
14 | "revisionTime": "2016-04-05T07:15:01Z" | |
15 | }, | |
16 | { | |
17 | "checksumSHA1": "fCc3grA7vIxfBru7R3SqjcW+oLI=", | |
18 | "path": "github.com/alecthomas/units", | |
19 | "revision": "2efee857e7cfd4f3d0138cc3cbb1b4966962b93a", | |
20 | "revisionTime": "2015-10-22T06:55:26Z" | |
21 | }, | |
22 | { | |
23 | "checksumSHA1": "4QnLdmB1kG3N+KlDd1N+G9TWAGQ=", | |
24 | "path": "github.com/beorn7/perks/quantile", | |
25 | "revision": "3ac7bf7a47d159a033b107610db8a1b6575507a4", | |
26 | "revisionTime": "2016-02-29T21:34:45Z" | |
27 | }, | |
28 | { | |
29 | "checksumSHA1": "GaJLoEuMGnP5ofXvuweAI4wx06U=", | |
30 | "path": "github.com/golang/protobuf/proto", | |
31 | "revision": "a47340a8e42c4ceb44c00c2a05199e24b24fcaef", | |
32 | "revisionTime": "2018-09-14T20:37:51Z" | |
33 | }, | |
34 | { | |
35 | "checksumSHA1": "bKMZjd2wPw13VwoE7mBeSv5djFA=", | |
36 | "path": "github.com/matttproud/golang_protobuf_extensions/pbutil", | |
37 | "revision": "c12348ce28de40eed0136aa2b644d0ee0650e56c", | |
38 | "revisionTime": "2016-04-24T11:30:07Z" | |
39 | }, | |
40 | { | |
41 | "checksumSHA1": "lLvg5TpUtFbkyAoh+aI5T/nnpWw=", | |
42 | "path": "github.com/prometheus/client_golang/prometheus", | |
43 | "revision": "e637cec7d9c8990247098639ebc6d43dd34ddd49", | |
44 | "revisionTime": "2018-09-17T10:21:22Z" | |
45 | }, | |
46 | { | |
47 | "checksumSHA1": "UBqhkyjCz47+S19MVTigxJ2VjVQ=", | |
48 | "path": "github.com/prometheus/client_golang/prometheus/internal", | |
49 | "revision": "e637cec7d9c8990247098639ebc6d43dd34ddd49", | |
50 | "revisionTime": "2018-09-17T10:21:22Z" | |
51 | }, | |
52 | { | |
53 | "checksumSHA1": "d5BiEvD8MrgpWQ6PQJUvawJsMak=", | |
54 | "path": "github.com/prometheus/client_golang/prometheus/promhttp", | |
55 | "revision": "e637cec7d9c8990247098639ebc6d43dd34ddd49", | |
56 | "revisionTime": "2018-09-17T10:21:22Z" | |
57 | }, | |
58 | { | |
59 | "checksumSHA1": "V8xkqgmP66sq2ZW4QO5wi9a4oZE=", | |
60 | "path": "github.com/prometheus/client_model/go", | |
61 | "revision": "5c3871d89910bfb32f5fcab2aa4b9ec68e65a99f", | |
62 | "revisionTime": "2018-07-12T10:51:10Z" | |
63 | }, | |
64 | { | |
65 | "checksumSHA1": "xfnn0THnqNwjwimeTClsxahYrIo=", | |
66 | "path": "github.com/prometheus/common/expfmt", | |
67 | "revision": "8ba51016a21456f1649877d7079f416d69eb3948", | |
68 | "revisionTime": "2017-07-31T09:30:31Z" | |
69 | }, | |
70 | { | |
71 | "checksumSHA1": "GWlM3d2vPYyNATtTFgftS10/A9w=", | |
72 | "path": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg", | |
73 | "revision": "8ba51016a21456f1649877d7079f416d69eb3948", | |
74 | "revisionTime": "2017-07-31T09:30:31Z" | |
75 | }, | |
76 | { | |
77 | "checksumSHA1": "jYpLEs+wZ5LZubvOJEDSQ8I14MI=", | |
78 | "path": "github.com/prometheus/common/log", | |
79 | "revision": "8ba51016a21456f1649877d7079f416d69eb3948", | |
80 | "revisionTime": "2017-07-31T09:30:31Z" | |
81 | }, | |
82 | { | |
83 | "checksumSHA1": "3VoqH7TFfzA6Ds0zFzIbKCUvBmw=", | |
84 | "path": "github.com/prometheus/common/model", | |
85 | "revision": "8ba51016a21456f1649877d7079f416d69eb3948", | |
86 | "revisionTime": "2017-07-31T09:30:31Z" | |
87 | }, | |
88 | { | |
89 | "checksumSHA1": "91KYK0SpvkaMJJA2+BcxbVnyRO0=", | |
90 | "path": "github.com/prometheus/common/version", | |
91 | "revision": "8ba51016a21456f1649877d7079f416d69eb3948", | |
92 | "revisionTime": "2017-07-31T09:30:31Z" | |
93 | }, | |
94 | { | |
95 | "checksumSHA1": "W218eJZPXJG783fUr/z6IaAZyes=", | |
96 | "path": "github.com/prometheus/procfs", | |
97 | "revision": "abf152e5f3e97f2fafac028d2cc06c1feb87ffa5", | |
98 | "revisionTime": "2016-04-11T19:08:41Z" | |
99 | }, | |
100 | { | |
101 | "checksumSHA1": "htjvdG/znrHmFYRQBqA2vHrJsF4=", | |
102 | "path": "github.com/sirupsen/logrus", | |
103 | "revision": "cd7d1bbe41066b6c1f19780f895901052150a575", | |
104 | "revisionTime": "2016-04-25T09:32:37Z" | |
105 | }, | |
106 | { | |
107 | "checksumSHA1": "HaylhE+ZhMoB6+4yAsvogKvXUrM=", | |
108 | "path": "golang.org/x/sys/unix", | |
109 | "revision": "19ced1583f732e8ff9d7d84de773dc621557df99", | |
110 | "revisionTime": "2015-11-17T03:15:20Z" | |
111 | }, | |
112 | { | |
113 | "checksumSHA1": "3SZTatHIy9OTKc95YlVfXKnoySg=", | |
114 | "path": "gopkg.in/alecthomas/kingpin.v2", | |
115 | "revision": "1087e65c9441605df944fb12c33f0fe7072d18ca", | |
116 | "revisionTime": "2017-07-27T04:22:29Z" | |
117 | } | |
118 | ], | |
119 | "rootPath": "github.com/prometheus/haproxy_exporter" | |
120 | } |