Codebase list prometheus-haproxy-exporter / upstream/0.12.0+ds
Merge tag 'upstream/0.12.0' into unvendored Guillem Jover 3 years ago
25 changed file(s) with 1655 addition(s) and 753 deletion(s). Raw diff Collapse all Expand all
00 ---
1 version: 2
1 version: 2.1
2
3 orbs:
4 prometheus: prometheus/prometheus@0.4.0
25
36 jobs:
47 test:
8 # Whenever the Go version is updated here, .promu.yml
9 # should also be updated.
510 docker:
6 - image: circleci/golang:1.10
7 working_directory: /go/src/github.com/prometheus/haproxy_exporter
11 - image: circleci/golang:1.15
812
913 steps:
10 - checkout
14 - prometheus/setup_environment
1115 - setup_remote_docker
12 - run: make promu
1316 - 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
8819
8920 workflows:
9021 version: 2
9425 filters:
9526 tags:
9627 only: /.*/
97 - build:
28 - prometheus/build:
29 name: build
9830 filters:
9931 tags:
10032 only: /.*/
101 - docker_hub_master:
33 - prometheus/publish_master:
34 context: org-context
10235 requires:
10336 - test
10437 - build
10538 filters:
10639 branches:
10740 only: master
108 - docker_hub_release_tags:
41 - prometheus/publish_release:
42 context: org-context
10943 requires:
11044 - test
11145 - 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
04 repository:
15 path: github.com/prometheus/haproxy_exporter
26 build:
3 flags: -a -tags netgo
7 flags: -mod=vendor -a -tags netgo
48 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"}}
1014 tarball:
1115 files:
1216 - LICENSE
+0
-5
.travis.yml less more
0 language: go
1 go: 1.9
2
3 script:
4 - make check_license style unused test staticcheck
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"
02 FROM quay.io/prometheus/busybox:latest
13 LABEL maintainer="The Prometheus Authors <prometheus-developers@googlegroups.com>"
24
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
48
9 USER nobody
510 ENTRYPOINT ["/bin/haproxy_exporter"]
611 EXPOSE 9101
1010 # See the License for the specific language governing permissions and
1111 # limitations under the License.
1212
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
1319 include Makefile.common
1420
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
1515 # !!! Open PRs only against the prometheus/prometheus/Makefile.common repository!
1616
1717 # Example usage :
18 # Create the main Makefile in the root project directory.
18 # Create the main Makefile in the root project directory.
1919 # include Makefile.common
2020 # customTarget:
2121 # @echo ">> Running customTarget"
2727 GO ?= go
2828 GOFMT ?= $(GO)fmt
2929 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
3061 PROMU := $(FIRST_GOPATH)/bin/promu
31 STATICCHECK := $(FIRST_GOPATH)/bin/staticcheck
32 GOVENDOR := $(FIRST_GOPATH)/bin/govendor
3362 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
3493
3594 PREFIX ?= $(shell pwd)
3695 BIN_DIR ?= $(shell pwd)
3796 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:
44124 @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:
49134 @echo ">> checking license header"
50135 @licRes=$$(for file in $$(find . -type f -iname '*.go' ! -path './vendor/*') ; do \
51136 awk 'NR<=3' $$file | grep -Eq "(Copyright|generated|GENERATED)" || echo $$file; \
55140 exit 1; \
56141 fi
57142
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)
60165 @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)
65170 @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:
70178 @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:
75183 @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
85207 @echo ">> running check for unused packages"
86208 @$(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
90225 @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
95230 @echo ">> building release tarball"
96231 $(PROMU) tarball --prefix $(PREFIX) $(BIN_DIR)
97232
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)"
101258
102259 .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
110283 .PHONY: $(GOVENDOR)
111284 $(GOVENDOR):
112285 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
11
22 This is a simple server that scrapes HAProxy stats and exports them via HTTP for
33 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).*
46
57 ## Getting Started
68
4951 ```
5052
5153 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:
5355
5456 ```bash
5557 haproxy_exporter --no-haproxy.ssl-verify --haproxy.scrape-uri="https://haproxy.example.com/haproxy?stats;csv"
8082 To run the haproxy exporter as a Docker container, run:
8183
8284 ```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"
8486 ```
8587
8688 [hub]: https://hub.docker.com/r/prom/haproxy-exporter/
115117 ## License
116118
117119 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 0.9.0
0 0.12.0
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=
1313 package main
1414
1515 import (
16 "bufio"
1617 "crypto/tls"
1718 "encoding/csv"
1819 "errors"
2324 "net/http"
2425 _ "net/http/pprof"
2526 "net/url"
27 "os"
2628 "sort"
2729 "strconv"
2830 "strings"
2931 "sync"
3032 "time"
3133
34 "github.com/go-kit/kit/log"
35 "github.com/go-kit/kit/log/level"
3236 "github.com/prometheus/client_golang/prometheus"
3337 "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"
3540 "github.com/prometheus/common/version"
3641 "gopkg.in/alecthomas/kingpin.v2"
3742 )
4853 // HAProxy 1.7
4954 // 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
5055 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"
5670 )
5771
5872 var (
6175 serverLabelNames = []string{"backend", "server"}
6276 )
6377
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
101120
102121 func (m metrics) String() string {
103122 keys := make([]int, 0, len(m))
114133
115134 var (
116135 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)
143230 )
144231
145232 // Exporter collects HAProxy stats from the given URI and exports them using
146233 // the prometheus metrics package.
147234 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
155245 }
156246
157247 // 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) {
159249 u, err := url.Parse(uri)
160250 if err != nil {
161251 return nil, err
162252 }
163253
164 var fetch func() (io.ReadCloser, error)
254 var fetchInfo func() (io.ReadCloser, error)
255 var fetchStat func() (io.ReadCloser, error)
165256 switch u.Scheme {
166257 case "http", "https", "file":
167 fetch = fetchHTTP(uri, sslVerify, timeout)
258 fetchStat = fetchHTTP(uri, sslVerify, timeout)
168259 case "unix":
169 fetch = fetchUnix(u, timeout)
260 fetchInfo = fetchUnix(u, showInfoCmd, timeout)
261 fetchStat = fetchUnix(u, showStatCmd, timeout)
170262 default:
171263 return nil, fmt.Errorf("unsupported scheme: %q", u.Scheme)
172264 }
173265
266 excludedServerStatesMap := map[string]struct{}{}
267 for _, f := range strings.Split(excludedServerStates, ",") {
268 excludedServerStatesMap[f] = struct{}{}
269 }
270
174271 return &Exporter{
175 URI: uri,
176 fetch: fetch,
272 URI: uri,
273 fetchInfo: fetchInfo,
274 fetchStat: fetchStat,
177275 up: prometheus.NewGauge(prometheus.GaugeOpts{
178276 Namespace: namespace,
179277 Name: "up",
181279 }),
182280 totalScrapes: prometheus.NewCounter(prometheus.CounterOpts{
183281 Namespace: namespace,
184 Name: "exporter_total_scrapes",
282 Name: "exporter_scrapes_total",
185283 Help: "Current total HAProxy scrapes.",
186284 }),
187285 csvParseFailures: prometheus.NewCounter(prometheus.CounterOpts{
188286 Namespace: namespace,
189 Name: "exporter_csv_parse_failures",
287 Name: "exporter_csv_parse_failures_total",
190288 Help: "Number of errors while parsing CSV.",
191289 }),
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,
243293 }, nil
244294 }
245295
246296 // Describe describes all the metrics ever exported by the HAProxy exporter. It
247297 // implements prometheus.Collector.
248298 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
254304 }
255305 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
259310 ch <- e.totalScrapes.Desc()
260311 ch <- e.csvParseFailures.Desc()
261312 }
266317 e.mutex.Lock() // To protect metrics from concurrent collects.
267318 defer e.mutex.Unlock()
268319
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)
273323 ch <- e.totalScrapes
274324 ch <- e.csvParseFailures
275 e.collectMetrics(ch)
276325 }
277326
278327 func fetchHTTP(uri string, sslVerify bool, timeout time.Duration) func() (io.ReadCloser, error) {
295344 }
296345 }
297346
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) {
299348 return func() (io.ReadCloser, error) {
300349 f, err := net.DialTimeout("unix", u.Path, timeout)
301350 if err != nil {
305354 f.Close()
306355 return nil, err
307356 }
308 cmd := "show stat\n"
309357 n, err := io.WriteString(f, cmd)
310358 if err != nil {
311359 f.Close()
319367 }
320368 }
321369
322 func (e *Exporter) scrape() {
370 func (e *Exporter) scrape(ch chan<- prometheus.Metric) (up float64) {
323371 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()
326391 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
330394 }
331395 defer body.Close()
332 e.up.Set(1)
333396
334397 reader := csv.NewReader(body)
335398 reader.TrailingComma = true
344407 break loop
345408 default:
346409 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)
348411 e.csvParseFailures.Inc()
349412 continue loop
350413 }
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) {
384448 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))
386450 e.csvParseFailures.Inc()
387451 return
388452 }
389453
390 pxname, svname, typ := csvRow[0], csvRow[1], csvRow[32]
454 pxname, svname, status, typ := csvRow[pxnameField], csvRow[svnameField], csvRow[statusField], csvRow[typeField]
391455
392456 const (
393457 frontend = "0"
394458 backend = "1"
395459 server = "2"
396 listener = "3"
397460 )
398461
399462 switch typ {
400463 case frontend:
401 e.exportCsvFields(e.frontendMetrics, csvRow, pxname)
464 e.exportCsvFields(frontendMetrics, csvRow, ch, pxname)
402465 case backend:
403 e.exportCsvFields(e.backendMetrics, csvRow, pxname)
466 e.exportCsvFields(backendMetrics, csvRow, ch, pxname)
404467 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 }
406472 }
407473 }
408474
409475 func parseStatusField(value string) int64 {
410476 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":
412478 return 1
413 case "DOWN", "DOWN 1/2", "NOLB", "MAINT":
479 case "DOWN", "DOWN 1/2", "NOLB", "MAINT", "MAINT(via)", "MAINT(resolution)":
414480 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) {
420487 for fieldIdx, metric := range metrics {
421488 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
423491 }
424492 valueStr := csvRow[fieldIdx]
425493 if valueStr == "" {
434502 case statusField:
435503 valueInt = parseStatusField(valueStr)
436504 value = float64(valueInt)
437 case qtimeMsField, ctimeMsField, rtimeMsField, ttimeMsField:
505 case checkDurationField, qtimeMsField, ctimeMsField, rtimeMsField, ttimeMsField:
438506 value, err = strconv.ParseFloat(valueStr, 64)
439507 value /= 1000
440508 default:
442510 value = float64(valueInt)
443511 }
444512 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)
446514 e.csvParseFailures.Inc()
447515 continue
448516 }
449 metric.WithLabelValues(labels...).Set(value)
517 ch <- prometheus.MustNewConstMetric(metric.Desc, metric.Type, value, labels...)
450518 }
451519 }
452520
453521 // filterServerMetrics returns the set of server metrics specified by the comma
454522 // 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{}
457525 if len(filter) == 0 {
458526 return metrics, nil
459527 }
460528
461 selected := map[int]struct{}{}
462529 for _, f := range strings.Split(filter, ",") {
463530 field, err := strconv.Atoi(f)
464531 if err != nil {
465532 return nil, fmt.Errorf("invalid server metric field number: %v", f)
466533 }
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 {
472535 metrics[field] = metric
473536 }
474537 }
538
475539 return metrics, nil
476540 }
477541
486550 https://prometheus.io/docs/instrumenting/writing_clientlibs/#process-metrics.`
487551
488552 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()
496561 )
497562
498 log.AddFlags(kingpin.CommandLine)
563 promlogConfig := &promlog.Config{}
564 flag.AddFlags(kingpin.CommandLine, promlogConfig)
499565 kingpin.Version(version.Print("haproxy_exporter"))
500566 kingpin.HelpFlag.Short('h')
501567 kingpin.Parse()
568 logger := promlog.New(promlogConfig)
502569
503570 selectedServerMetrics, err := filterServerMetrics(*haProxyServerMetricFields)
504571 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)
512580 if err != nil {
513 log.Fatal(err)
581 level.Error(logger).Log("msg", "Error creating an exporter", "err", err)
582 os.Exit(1)
514583 }
515584 prometheus.MustRegister(exporter)
516585 prometheus.MustRegister(version.NewCollector("haproxy_exporter"))
520589 PidFn: func() (int, error) {
521590 content, err := ioutil.ReadFile(*haProxyPidFile)
522591 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)
524593 }
525594 value, err := strconv.Atoi(strings.TrimSpace(string(content)))
526595 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)
528597 }
529598 return value, nil
530599 },
533602 prometheus.MustRegister(procExporter)
534603 }
535604
536 log.Infoln("Listening on", *listenAddress)
605 level.Info(logger).Log("msg", "Listening on address", "address", *listenAddress)
537606 http.Handle(*metricsPath, promhttp.Handler())
538607 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
539608 w.Write([]byte(`<html>
544613 </body>
545614 </html>`))
546615 })
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 }
2020 "net/http"
2121 "net/http/httptest"
2222 "os"
23 "path"
2324 "reflect"
2425 "runtime"
2526 "testing"
2627 "time"
2728
28 dto "github.com/prometheus/client_model/go"
29
29 "github.com/go-kit/kit/log"
3030 "github.com/prometheus/client_golang/prometheus"
31 "github.com/prometheus/client_golang/prometheus/testutil"
3132 )
3233
33 const testSocket = "/tmp/haproxyexportertest.sock"
34 const (
35 testSocket = "/tmp/haproxyexportertest.sock"
36 testInfo = "Release_date: test date\nVersion: test version\n"
37 )
3438
3539 type haproxy struct {
3640 *httptest.Server
5559 }
5660 }
5761
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 }
7070 }
7171
7272 func TestInvalidConfig(t *testing.T) {
7373 h := newHaproxy([]byte("not,enough,fields"))
7474 defer h.Close()
7575
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")
9979 }
10080
10181 func TestServerWithoutChecks(t *testing.T) {
10282 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,,,,,,,,,,,"))
10383 defer h.Close()
10484
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")
13388 }
13489
13590 // TestServerBrokenCSV ensures bugs in CSV format are handled gracefully. List of known bugs:
145100 h := newHaproxy([]byte(data))
146101 defer h.Close()
147102
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")
176106 }
177107
178108 func TestOlderHaproxyVersions(t *testing.T) {
183113 h := newHaproxy([]byte(data))
184114 defer h.Close()
185115
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")
210119 }
211120
212121 func TestConfigChangeDetection(t *testing.T) {
213122 h := newHaproxy([]byte(""))
214123 defer h.Close()
215124
216 e, _ := NewExporter(h.URL, true, serverMetrics, 5*time.Second)
125 e, _ := NewExporter(h.URL, true, serverMetrics, excludedServerStates, 5*time.Second, log.NewNopLogger())
217126 ch := make(chan prometheus.Metric)
218127
219128 go func() {
240149 s.Close()
241150 }()
242151
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")
269158 }
270159
271160 func TestNotFound(t *testing.T) {
272161 s := httptest.NewServer(http.NotFoundHandler())
273162 defer s.Close()
274163
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) {
293173 if err := os.Remove(file); err != nil && !os.IsNotExist(err) {
294174 return nil, err
295175 }
312192 return
313193 }
314194 switch l {
195 case "show info\n":
196 c.Write([]byte(infoPayload))
197 return
315198 case "show stat\n":
316199 c.Write([]byte(statsPayload))
317200 return
331214 t.Skip("not on windows")
332215 return
333216 }
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)
335218 if err != nil {
336219 t.Fatalf("can't start test server: %v", err)
337220 }
338221 defer srv.Close()
339222
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")
371229 }
372230
373231 func TestUnixDomainNotFound(t *testing.T) {
379237 if err := os.Remove(testSocket); err != nil && !os.IsNotExist(err) {
380238 t.Fatal(err)
381239 }
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")
404242 }
405243
406244 func TestUnixDomainDeadline(t *testing.T) {
432270 }
433271 }()
434272
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")
457276 }
458277
459278 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())
461280 if expect, got := (*Exporter)(nil), e; expect != got {
462281 t.Errorf("expected %v, got %v", expect, got)
463282 }
500319 func TestFilterServerMetrics(t *testing.T) {
501320 tests := []struct {
502321 input string
503 want map[int]*prometheus.GaugeVec
322 want map[int]metricInfo
504323 }{
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}}},
507326 {input: serverMetrics.String(), want: serverMetrics},
508327 }
509328
532351 h := newHaproxy(config)
533352 defer h.Close()
534353
535 e, _ := NewExporter(h.URL, true, serverMetrics, 5*time.Second)
354 e, _ := NewExporter(h.URL, true, serverMetrics, excludedServerStates, 5*time.Second, log.NewNopLogger())
536355
537356 var before, after runtime.MemStats
538357 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
-121
vendor/vendor.json less more
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 }