forked from mirrors/statsd_exporter
Compare commits
No commits in common. "master" and "feature/replace-level-pkg" have entirely different histories.
master
...
feature/re
29 changed files with 220 additions and 842 deletions
|
@ -1,11 +1,11 @@
|
|||
version: 2.1
|
||||
orbs:
|
||||
prometheus: prometheus/prometheus@0.16.0
|
||||
prometheus: prometheus/prometheus@0.11.0
|
||||
executors:
|
||||
# Whenever the Go version is updated here, .promu.yml should also be updated.
|
||||
golang:
|
||||
docker:
|
||||
- image: cimg/go:1.19
|
||||
- image: circleci/golang:1.16
|
||||
jobs:
|
||||
test:
|
||||
executor: golang
|
||||
|
|
6
.github/dependabot.yml
vendored
6
.github/dependabot.yml
vendored
|
@ -1,6 +0,0 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "gomod"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
30
.github/workflows/golangci-lint.yml
vendored
30
.github/workflows/golangci-lint.yml
vendored
|
@ -1,30 +0,0 @@
|
|||
name: golangci-lint
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- "go.sum"
|
||||
- "go.mod"
|
||||
- "**.go"
|
||||
- "scripts/errcheck_excludes.txt"
|
||||
- ".github/workflows/golangci-lint.yml"
|
||||
- ".golangci.yml"
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
golangci:
|
||||
name: lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
- name: install Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.18.x
|
||||
- name: Install snmp_exporter/generator dependencies
|
||||
run: sudo apt-get update && sudo apt-get -y install libsnmp-dev
|
||||
if: github.repository == 'prometheus/snmp_exporter'
|
||||
- name: Lint
|
||||
uses: golangci/golangci-lint-action@v3.2.0
|
||||
with:
|
||||
version: v1.45.2
|
|
@ -1,27 +1,5 @@
|
|||
run:
|
||||
issues-exit-code: 1
|
||||
tests: true
|
||||
# Run only staticcheck for now. Additional linters will be enabled one-by-one.
|
||||
linters:
|
||||
disable:
|
||||
- errcheck
|
||||
enable:
|
||||
- deadcode
|
||||
- goimports
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- nakedret
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- unused
|
||||
- varcheck
|
||||
- whitespace
|
||||
linters-settings:
|
||||
govet:
|
||||
check-shadowing: true
|
||||
issues:
|
||||
exclude-use-default: false
|
||||
exclude:
|
||||
- 'shadow: declaration of "err" shadows declaration at line (\d+)'
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
disable-all: true
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
go:
|
||||
# Whenever the Go version is updated here, .circle/config.yml should also
|
||||
# be updated.
|
||||
version: 1.19
|
||||
version: 1.16
|
||||
repository:
|
||||
path: github.com/prometheus/statsd_exporter
|
||||
build:
|
||||
|
|
28
.yamllint
28
.yamllint
|
@ -1,28 +0,0 @@
|
|||
---
|
||||
extends: default
|
||||
|
||||
rules:
|
||||
braces:
|
||||
max-spaces-inside: 1
|
||||
level: error
|
||||
brackets:
|
||||
max-spaces-inside: 1
|
||||
level: error
|
||||
commas: disable
|
||||
comments: disable
|
||||
comments-indentation: disable
|
||||
document-start: disable
|
||||
indentation:
|
||||
spaces: consistent
|
||||
indent-sequences: consistent
|
||||
key-duplicates:
|
||||
ignore: |
|
||||
config/testdata/section_key_dup.bad.yml
|
||||
line-length: disable
|
||||
truthy:
|
||||
ignore: |
|
||||
.github/workflows/codeql-analysis.yml
|
||||
.github/workflows/funcbench.yml
|
||||
.github/workflows/fuzzing.yml
|
||||
.github/workflows/prombench.yml
|
||||
.github/workflows/golangci-lint.yml
|
46
CHANGELOG.md
46
CHANGELOG.md
|
@ -1,48 +1,7 @@
|
|||
## 0.23.0 / 2022-12-07
|
||||
## 0.22.1 / Unreleased
|
||||
|
||||
* [CHANGE] Print help and version to standard out ([#469](https://github.com/prometheus/statsd_exporter/pull/469))
|
||||
* [FEATURE] Support experimental native histograms ([#474](https://github.com/prometheus/statsd_exporter/pull/474))
|
||||
|
||||
## 0.22.8 / 2022-09-13
|
||||
|
||||
* [BUGFIX] Prevent poisoning with gauge/distribution naming collision ([#461](https://github.com/prometheus/statsd_exporter/pull/461))
|
||||
* [CHANGE] Update `client_golang` dependency ([#463](https://github.com/prometheus/statsd_exporter/pull/463))
|
||||
|
||||
## 0.22.7 / 2022-07-08
|
||||
|
||||
* [CHANGE] Build with Go 1.18 ([#450](https://github.com/prometheus/statsd_exporter/pull/450))
|
||||
|
||||
## 0.22.6 / 2022-07-08
|
||||
|
||||
* [CHANGE] Update dependencies ([#449](https://github.com/prometheus/statsd_exporter/pull/449))
|
||||
|
||||
This is another housekeeping release.
|
||||
|
||||
## 0.22.5 / 2022-05-06
|
||||
|
||||
* [ENHANCEMENT] Add metric for total lines relayed ([#434](https://github.com/prometheus/statsd_exporter/pull/434))
|
||||
|
||||
This release is built with Go 1.17.9, to address security issues in Go.
|
||||
|
||||
## 0.22.4 / 2021-11-26
|
||||
|
||||
* [BUGFIX] Make Docker image compatible with the runAsNonRoot setting in Kubernetes pods ([#409](https://github.com/prometheus/statsd_exporter/pull/409))
|
||||
* [BUGFIX] Library: fix support for custom Registerers with histograms and summaries ([#410](https://github.com/prometheus/statsd_exporter/pull/410))
|
||||
|
||||
## 0.22.3 / 2021-10-26
|
||||
|
||||
* [BUGFIX] Accept metrics with multiple dashes even if not mapped ([#402](https://github.com/prometheus/statsd_exporter/pull/402))
|
||||
|
||||
## 0.22.2 / 2021-09-10
|
||||
|
||||
* [ENHANCEMENT] Add metrics to relay ([#393](https://github.com/prometheus/statsd_exporter/pull/393))
|
||||
|
||||
## 0.22.1 / 2021-09-01
|
||||
|
||||
* [ENHANCEMENT] Accept incoming metrics with multiple dashes (with mapping) ([#381](https://github.com/prometheus/statsd_exporter//pull/381))
|
||||
* [ENHANCEMENT] Allow forwarding messages to statsd for easier transition ([#388](https://github.com/prometheus/statsd_exporter/pull/388))
|
||||
* [BUGFIX] Actually expose pprof endpoints ([#386](https://github.com/prometheus/statsd_exporter/pull/386))
|
||||
* [BUGFIX] Fix performance regression on metric ingestion ([#390](https://github.com/prometheus/statsd_exporter/pull/390))
|
||||
* [ENHANCEMENT] Accept incoming metrics with multiple dashes (with mapping) ([#381](https://github.com/prometheus/statsd_exporter//pull/381))
|
||||
|
||||
## 0.21.0 / 2021-06-10
|
||||
|
||||
|
@ -415,6 +374,7 @@ NOTE: This release renames `statsd_bridge` to `statsd_exporter`
|
|||
* [ENHANCEMENT] add root endpoint with redirect ([#25](https://github.com/prometheus/statsd_exporter/pulls/25))
|
||||
* [CHANGE] rename bridge to exporter ([#26](https://github.com/prometheus/statsd_exporter/pulls/26))
|
||||
|
||||
|
||||
## 0.1.0 / 2015-04-17
|
||||
|
||||
* Initial release
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
# Prometheus Community Code of Conduct
|
||||
## Prometheus Community Code of Conduct
|
||||
|
||||
Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md).
|
||||
Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
|
||||
|
|
|
@ -7,7 +7,7 @@ ARG ARCH="amd64"
|
|||
ARG OS="linux"
|
||||
COPY .build/${OS}-${ARCH}/statsd_exporter /bin/statsd_exporter
|
||||
|
||||
USER 65534
|
||||
USER nobody
|
||||
EXPOSE 9102 9125 9125/udp
|
||||
HEALTHCHECK CMD wget --spider -S "http://localhost:9102/metrics" -T 60 2>&1 || exit 1
|
||||
ENTRYPOINT [ "/bin/statsd_exporter" ]
|
||||
|
|
|
@ -36,6 +36,29 @@ GO_VERSION ?= $(shell $(GO) version)
|
|||
GO_VERSION_NUMBER ?= $(word 3, $(GO_VERSION))
|
||||
PRE_GO_111 ?= $(shell echo $(GO_VERSION_NUMBER) | grep -E 'go1\.(10|[0-9])\.')
|
||||
|
||||
GOVENDOR :=
|
||||
GO111MODULE :=
|
||||
ifeq (, $(PRE_GO_111))
|
||||
ifneq (,$(wildcard go.mod))
|
||||
# Enforce Go modules support just in case the directory is inside GOPATH (and for Travis CI).
|
||||
GO111MODULE := on
|
||||
|
||||
ifneq (,$(wildcard vendor))
|
||||
# Always use the local vendor/ directory to satisfy the dependencies.
|
||||
GOOPTS := $(GOOPTS) -mod=vendor
|
||||
endif
|
||||
endif
|
||||
else
|
||||
ifneq (,$(wildcard go.mod))
|
||||
ifneq (,$(wildcard vendor))
|
||||
$(warning This repository requires Go >= 1.11 because of Go modules)
|
||||
$(warning Some recipes may not work as expected as the current Go runtime is '$(GO_VERSION_NUMBER)')
|
||||
endif
|
||||
else
|
||||
# This repository isn't using Go modules (yet).
|
||||
GOVENDOR := $(FIRST_GOPATH)/bin/govendor
|
||||
endif
|
||||
endif
|
||||
PROMU := $(FIRST_GOPATH)/bin/promu
|
||||
pkgs = ./...
|
||||
|
||||
|
@ -55,26 +78,17 @@ ifneq ($(shell which gotestsum),)
|
|||
endif
|
||||
endif
|
||||
|
||||
PROMU_VERSION ?= 0.14.0
|
||||
PROMU_VERSION ?= 0.12.0
|
||||
PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz
|
||||
|
||||
SKIP_GOLANGCI_LINT :=
|
||||
GOLANGCI_LINT :=
|
||||
GOLANGCI_LINT_OPTS ?=
|
||||
GOLANGCI_LINT_VERSION ?= v1.49.0
|
||||
GOLANGCI_LINT_VERSION ?= v1.39.0
|
||||
# golangci-lint only supports linux, darwin and windows platforms on i386/amd64.
|
||||
# windows isn't included here because of the path separator being different.
|
||||
ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin))
|
||||
ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386))
|
||||
# If we're in CI and there is an Actions file, that means the linter
|
||||
# is being run in Actions, so we don't need to run it here.
|
||||
ifneq (,$(SKIP_GOLANGCI_LINT))
|
||||
GOLANGCI_LINT :=
|
||||
else ifeq (,$(CIRCLE_JOB))
|
||||
GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint
|
||||
else ifeq (,$(wildcard .github/workflows/golangci-lint.yml))
|
||||
GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -130,25 +144,32 @@ common-check_license:
|
|||
.PHONY: common-deps
|
||||
common-deps:
|
||||
@echo ">> getting dependencies"
|
||||
$(GO) mod download
|
||||
ifdef GO111MODULE
|
||||
GO111MODULE=$(GO111MODULE) $(GO) mod download
|
||||
else
|
||||
$(GO) get $(GOOPTS) -t ./...
|
||||
endif
|
||||
|
||||
.PHONY: update-go-deps
|
||||
update-go-deps:
|
||||
@echo ">> updating Go dependencies"
|
||||
@for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \
|
||||
$(GO) get -d $$m; \
|
||||
$(GO) get $$m; \
|
||||
done
|
||||
$(GO) mod tidy
|
||||
GO111MODULE=$(GO111MODULE) $(GO) mod tidy
|
||||
ifneq (,$(wildcard vendor))
|
||||
GO111MODULE=$(GO111MODULE) $(GO) mod vendor
|
||||
endif
|
||||
|
||||
.PHONY: common-test-short
|
||||
common-test-short: $(GOTEST_DIR)
|
||||
@echo ">> running short tests"
|
||||
$(GOTEST) -short $(GOOPTS) $(pkgs)
|
||||
GO111MODULE=$(GO111MODULE) $(GOTEST) -short $(GOOPTS) $(pkgs)
|
||||
|
||||
.PHONY: common-test
|
||||
common-test: $(GOTEST_DIR)
|
||||
@echo ">> running all tests"
|
||||
$(GOTEST) $(test-flags) $(GOOPTS) $(pkgs)
|
||||
GO111MODULE=$(GO111MODULE) $(GOTEST) $(test-flags) $(GOOPTS) $(pkgs)
|
||||
|
||||
$(GOTEST_DIR):
|
||||
@mkdir -p $@
|
||||
|
@ -156,21 +177,25 @@ $(GOTEST_DIR):
|
|||
.PHONY: common-format
|
||||
common-format:
|
||||
@echo ">> formatting code"
|
||||
$(GO) fmt $(pkgs)
|
||||
GO111MODULE=$(GO111MODULE) $(GO) fmt $(pkgs)
|
||||
|
||||
.PHONY: common-vet
|
||||
common-vet:
|
||||
@echo ">> vetting code"
|
||||
$(GO) vet $(GOOPTS) $(pkgs)
|
||||
GO111MODULE=$(GO111MODULE) $(GO) vet $(GOOPTS) $(pkgs)
|
||||
|
||||
.PHONY: common-lint
|
||||
common-lint: $(GOLANGCI_LINT)
|
||||
ifdef GOLANGCI_LINT
|
||||
@echo ">> running golangci-lint"
|
||||
ifdef GO111MODULE
|
||||
# 'go list' needs to be executed before staticcheck to prepopulate the modules cache.
|
||||
# Otherwise staticcheck might fail randomly for some reason not yet explained.
|
||||
$(GO) list -e -compiled -test=true -export=false -deps=true -find=false -tags= -- ./... > /dev/null
|
||||
$(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs)
|
||||
GO111MODULE=$(GO111MODULE) $(GO) list -e -compiled -test=true -export=false -deps=true -find=false -tags= -- ./... > /dev/null
|
||||
GO111MODULE=$(GO111MODULE) $(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs)
|
||||
else
|
||||
$(GOLANGCI_LINT) run $(pkgs)
|
||||
endif
|
||||
endif
|
||||
|
||||
.PHONY: common-yamllint
|
||||
|
@ -187,15 +212,28 @@ endif
|
|||
common-staticcheck: lint
|
||||
|
||||
.PHONY: common-unused
|
||||
common-unused:
|
||||
common-unused: $(GOVENDOR)
|
||||
ifdef GOVENDOR
|
||||
@echo ">> running check for unused packages"
|
||||
@$(GOVENDOR) list +unused | grep . && exit 1 || echo 'No unused packages'
|
||||
else
|
||||
ifdef GO111MODULE
|
||||
@echo ">> running check for unused/missing packages in go.mod"
|
||||
$(GO) mod tidy
|
||||
GO111MODULE=$(GO111MODULE) $(GO) mod tidy
|
||||
ifeq (,$(wildcard vendor))
|
||||
@git diff --exit-code -- go.sum go.mod
|
||||
else
|
||||
@echo ">> running check for unused packages in vendor/"
|
||||
GO111MODULE=$(GO111MODULE) $(GO) mod vendor
|
||||
@git diff --exit-code -- go.sum go.mod vendor/
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
.PHONY: common-build
|
||||
common-build: promu
|
||||
@echo ">> building binaries"
|
||||
$(PROMU) build --prefix $(PREFIX) $(PROMU_BINARIES)
|
||||
GO111MODULE=$(GO111MODULE) $(PROMU) build --prefix $(PREFIX) $(PROMU_BINARIES)
|
||||
|
||||
.PHONY: common-tarball
|
||||
common-tarball: promu
|
||||
|
@ -251,6 +289,12 @@ $(GOLANGCI_LINT):
|
|||
| sh -s -- -b $(FIRST_GOPATH)/bin $(GOLANGCI_LINT_VERSION)
|
||||
endif
|
||||
|
||||
ifdef GOVENDOR
|
||||
.PHONY: $(GOVENDOR)
|
||||
$(GOVENDOR):
|
||||
GOOS= GOARCH= $(GO) get -u github.com/kardianos/govendor
|
||||
endif
|
||||
|
||||
.PHONY: precheck
|
||||
precheck::
|
||||
|
||||
|
|
81
README.md
81
README.md
|
@ -8,38 +8,26 @@
|
|||
|
||||
## Overview
|
||||
|
||||
The StatsD exporter is a drop-in replacement for StatsD.
|
||||
This exporter translates StatsD metrics to Prometheus metrics via configured mapping rules.
|
||||
### With StatsD
|
||||
|
||||
We recommend using the exporter only as an intermediate solution, and switching to [native Prometheus instrumentation](http://prometheus.io/docs/instrumenting/clientlibs/) in the long term.
|
||||
While it is common to run centralized StatsD servers, the exporter works best as a [sidecar](https://docs.microsoft.com/en-us/azure/architecture/patterns/sidecar).
|
||||
|
||||
### Transitioning from an existing StatsD setup
|
||||
|
||||
The relay feature allows for a gradual transition.
|
||||
|
||||
Introduce the exporter by adding it as a sidecar alongside the application instances.
|
||||
In Kubernetes, this means adding it to the [pod](https://kubernetes.io/docs/concepts/workloads/pods/).
|
||||
Use the `--statsd.relay.address` to forward metrics to your existing StatsD UDP endpoint.
|
||||
Relaying forwards statsd events unmodified, preserving the original metric name and tags in any format.
|
||||
|
||||
+-------------+ +----------+ +------------+
|
||||
| Application +--->| Exporter +----------------->| StatsD |
|
||||
+-------------+ +----------+ +------------+
|
||||
^
|
||||
| +------------+
|
||||
+----------------------+ Prometheus |
|
||||
+------------+
|
||||
|
||||
### Relaying from StatsD
|
||||
|
||||
To pipe metrics from an existing StatsD environment into Prometheus, configure StatsD's repeater backend to repeat all received metrics to a `statsd_exporter` process.
|
||||
To pipe metrics from an existing StatsD environment into Prometheus, configure
|
||||
StatsD's repeater backend to repeat all received metrics to a `statsd_exporter`
|
||||
process. This exporter translates StatsD metrics to Prometheus metrics via
|
||||
configured mapping rules.
|
||||
|
||||
+----------+ +-------------------+ +--------------+
|
||||
| StatsD |---(UDP/TCP repeater)--->| statsd_exporter |<---(scrape /metrics)---| Prometheus |
|
||||
+----------+ +-------------------+ +--------------+
|
||||
|
||||
This allows trying out the exporter with minimal effort, but does not provide the per-instance metrics of the sidecar pattern.
|
||||
### Without StatsD
|
||||
|
||||
Since the StatsD exporter uses the same line protocol as StatsD itself, you can
|
||||
also configure your applications to send StatsD metrics directly to the exporter.
|
||||
In that case, you don't need to run a StatsD server anymore.
|
||||
|
||||
We recommend this only as an intermediate solution and recommend switching to
|
||||
[native Prometheus instrumentation](http://prometheus.io/docs/instrumenting/clientlibs/)
|
||||
in the long term.
|
||||
|
||||
### Tagging Extensions
|
||||
|
||||
|
@ -160,10 +148,6 @@ NOTE: Version 0.7.0 switched to the [kingpin](https://github.com/alecthomas/king
|
|||
Parse Librato style tags. Enabled by default.
|
||||
--statsd.parse-signalfx-tags
|
||||
Parse SignalFX style tags. Enabled by default.
|
||||
--statsd.relay.address=STATSD.RELAY.ADDRESS
|
||||
The UDP relay target address (host:port)
|
||||
--statsd.relay.packet-length=1400
|
||||
Maximum relay output packet length to avoid fragmentation
|
||||
--log.level=info Only log messages with the given severity or
|
||||
above. One of: [debug, info, warn, error]
|
||||
--log.format=logfmt Output format of log messages. One of: [logfmt,
|
||||
|
@ -176,10 +160,6 @@ NOTE: Version 0.7.0 switched to the [kingpin](https://github.com/alecthomas/king
|
|||
The `statsd_exporter` has an optional lifecycle API (disabled by default) that can be used to reload or quit the exporter
|
||||
by sending a `PUT` or `POST` request to the `/-/reload` or `/-/quit` endpoints.
|
||||
|
||||
## Relay
|
||||
|
||||
The `statsd_exporter` has an optional mode that will buffer and relay incoming statsd lines to a remote server. This is useful to "tee" the data when migrating to using the exporter. The relay will flush the buffer at least once per second to avoid delaying delivery of metrics.
|
||||
|
||||
## Tests
|
||||
|
||||
$ go test
|
||||
|
@ -296,6 +276,7 @@ mappings:
|
|||
name: "${2}_total"
|
||||
labels:
|
||||
provider: "$1"
|
||||
mappings:
|
||||
- match: "(.*)\\.(.*)--(.*)\\.status\.(.*)\\.count"
|
||||
match_type: regex
|
||||
name: "request_total"
|
||||
|
@ -316,27 +297,6 @@ mappings:
|
|||
provider: "$1"
|
||||
```
|
||||
|
||||
#### Special match groups
|
||||
|
||||
When using regex, the match group `0` is the full match and can be used to attach labels to the metric.
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
mappings:
|
||||
- match: ".+"
|
||||
match_type: regex
|
||||
name: "$0"
|
||||
labels:
|
||||
statsd_metric_name: "$0"
|
||||
```
|
||||
|
||||
If a metric `my.statsd_counter` is received, the metric name will **still** be mapped to `my_statsd_counter` (Prometheus compatible name).
|
||||
But the metric will also have the label `statsd_metric_name` with the value `my.statsd_counter` (unchanged value).
|
||||
|
||||
Note: If you use the `match` like the example (i.e. `.+`), be aware that it will be a "catch-all" block. So it should come at the very end of the mapping list.
|
||||
|
||||
The same is not achievable with glob matching, for more details check [this issue](https://github.com/prometheus/statsd_exporter/issues/444).
|
||||
|
||||
### Naming, labels, and help
|
||||
|
||||
Please note that metrics with the same name must also have the same set of
|
||||
|
@ -402,8 +362,6 @@ mappings:
|
|||
observer_type: histogram
|
||||
histogram_options:
|
||||
buckets: [ 0.01, 0.025, 0.05, 0.1 ]
|
||||
native_histogram_bucket_factor: 1.1
|
||||
native_histogram_max_buckets: 256
|
||||
name: "my_timer"
|
||||
labels:
|
||||
provider: "$2"
|
||||
|
@ -417,11 +375,6 @@ values](https://godoc.org/github.com/prometheus/client_golang/prometheus#pkg-var
|
|||
are used for the histogram buckets:
|
||||
`[.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10]`.
|
||||
`+Inf` is added automatically.
|
||||
If your Prometheus server is enabled to scrape native histograms (v2.40.0+),
|
||||
then you can set the `native_histogram_bucket_factor` to configure precision of the
|
||||
buckets in the sparse histogram. More about this in the original [client_golang docs](https://github.com/prometheus/client_golang/blob/449b46435075e6e069e05af920fe028b941033cf/prometheus/histogram.go#L399-L430).
|
||||
Also, a configuration of the maximum number of buckets can be set with `native_histogram_max_buckets`, this
|
||||
avoids the histograms to grow too large in memory. More about this in the original [client_golang docs](https://github.com/prometheus/client_golang/blob/449b46435075e6e069e05af920fe028b941033cf/prometheus/histogram.go#L443-L467).
|
||||
|
||||
`observer_type` is only used when the statsd metric type is a timer, histogram, or distribution.
|
||||
`buckets` is only used when the statsd metric type is one of these, and the `observer_type` is set to `histogram`.
|
||||
|
@ -476,8 +429,6 @@ defaults:
|
|||
observer_type: histogram
|
||||
histogram_options:
|
||||
buckets: [.005, .01, .025, .05, .1, .25, .5, 1, 2.5 ]
|
||||
native_histogram_bucket_factor: 1.1
|
||||
native_histogram_max_buckets: 256
|
||||
summary_options:
|
||||
quantiles:
|
||||
- quantile: 0.99
|
||||
|
@ -557,7 +508,7 @@ Possible values for `match_metric_type` are `gauge`, `counter` and `observer`.
|
|||
|
||||
There is a cache used to improve the performance of the metric mapping, that can greatly improvement performance.
|
||||
The cache has a default maximum of 1000 unique statsd metric names -> prometheus metrics mappings that it can store.
|
||||
This maximum can be adjusted using the `statsd.cache-size` flag.
|
||||
This maximum can be adjust using the `statsd.cache-size` flag.
|
||||
|
||||
If the maximum is reached, entries are by default rotated using the [least recently used replacement policy](https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)). This strategy is optimal when memory is constrained as only the most recent entries are retained.
|
||||
|
||||
|
|
|
@ -3,4 +3,4 @@
|
|||
The Prometheus security policy, including how to report vulnerabilities, can be
|
||||
found here:
|
||||
|
||||
<https://prometheus.io/docs/operating/security/>
|
||||
https://prometheus.io/docs/operating/security/
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
0.23.0
|
||||
0.22.1
|
||||
|
|
24
go.mod
24
go.mod
|
@ -1,27 +1,13 @@
|
|||
module github.com/prometheus/statsd_exporter
|
||||
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/go-kit/log v0.2.1
|
||||
github.com/go-kit/log v0.1.0
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
|
||||
github.com/prometheus/client_golang v1.14.0
|
||||
github.com/prometheus/client_model v0.3.0
|
||||
github.com/prometheus/common v0.37.0
|
||||
github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807
|
||||
github.com/prometheus/client_golang v1.11.0
|
||||
github.com/prometheus/client_model v0.2.0
|
||||
github.com/prometheus/common v0.28.0
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/go-logfmt/logfmt v0.5.1 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/prometheus/procfs v0.8.0 // indirect
|
||||
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
)
|
||||
go 1.13
|
||||
|
|
57
go.sum
57
go.sum
|
@ -38,17 +38,15 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafo
|
|||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc=
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
|
@ -66,15 +64,13 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2
|
|||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/log v0.1.0 h1:DGJh0Sm43HbOeYDNnVZFl8BvcYVvjD5bqYJvp0REbwQ=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
||||
github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
|
||||
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
|
||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
|
@ -103,10 +99,8 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
|||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
|
@ -117,8 +111,8 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
|
@ -139,7 +133,6 @@ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX
|
|||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
|
@ -159,40 +152,34 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
|
|||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
|
||||
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
||||
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
|
||||
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
|
||||
github.com/prometheus/common v0.28.0 h1:vGVfV9KrDTvWt5boZO0I19g2E3CsWfpPPKZM9dt3mEw=
|
||||
github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
|
||||
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
|
@ -203,8 +190,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
|||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807 h1:LUsDduamlucuNnWcaTbXQ6aLILFcLXADpOzeEH3U+OI=
|
||||
github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
|
@ -278,15 +263,12 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
|
|||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -330,21 +312,15 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d h1:/m5NbqQelATgoSPVC2Z23sR4kVNokFwDDyWh/3rGY+I=
|
||||
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
@ -391,6 +367,7 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc
|
|||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
|
@ -465,10 +442,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
|||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1 h1:7QnIQpGRHE5RnLKnESfDoxm2dTapTZua5a0kS0A+VXQ=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
98
main.go
98
main.go
|
@ -26,7 +26,6 @@ import (
|
|||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"github.com/prometheus/common/promlog"
|
||||
"github.com/prometheus/common/promlog/flag"
|
||||
|
@ -42,122 +41,126 @@ import (
|
|||
"github.com/prometheus/statsd_exporter/pkg/mapper"
|
||||
"github.com/prometheus/statsd_exporter/pkg/mappercache/lru"
|
||||
"github.com/prometheus/statsd_exporter/pkg/mappercache/randomreplacement"
|
||||
"github.com/prometheus/statsd_exporter/pkg/relay"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultHelp = "Metric autogenerated by statsd_exporter."
|
||||
regErrF = "Failed to update metric"
|
||||
)
|
||||
|
||||
var (
|
||||
eventStats = promauto.NewCounterVec(
|
||||
eventStats = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_events_total",
|
||||
Help: "The total number of StatsD events seen.",
|
||||
},
|
||||
[]string{"type"},
|
||||
)
|
||||
eventsFlushed = promauto.NewCounter(
|
||||
eventsFlushed = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_event_queue_flushed_total",
|
||||
Help: "Number of times events were flushed to exporter",
|
||||
},
|
||||
)
|
||||
eventsUnmapped = promauto.NewCounter(
|
||||
eventsUnmapped = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_events_unmapped_total",
|
||||
Help: "The total number of StatsD events no mapping was found for.",
|
||||
})
|
||||
udpPackets = promauto.NewCounter(
|
||||
udpPackets = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_udp_packets_total",
|
||||
Help: "The total number of StatsD packets received over UDP.",
|
||||
},
|
||||
)
|
||||
tcpConnections = promauto.NewCounter(
|
||||
tcpConnections = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_tcp_connections_total",
|
||||
Help: "The total number of TCP connections handled.",
|
||||
},
|
||||
)
|
||||
tcpErrors = promauto.NewCounter(
|
||||
tcpErrors = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_tcp_connection_errors_total",
|
||||
Help: "The number of errors encountered reading from TCP.",
|
||||
},
|
||||
)
|
||||
tcpLineTooLong = promauto.NewCounter(
|
||||
tcpLineTooLong = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_tcp_too_long_lines_total",
|
||||
Help: "The number of lines discarded due to being too long.",
|
||||
},
|
||||
)
|
||||
unixgramPackets = promauto.NewCounter(
|
||||
unixgramPackets = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_unixgram_packets_total",
|
||||
Help: "The total number of StatsD packets received over Unixgram.",
|
||||
},
|
||||
)
|
||||
linesReceived = promauto.NewCounter(
|
||||
linesReceived = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_lines_total",
|
||||
Help: "The total number of StatsD lines received.",
|
||||
},
|
||||
)
|
||||
samplesReceived = promauto.NewCounter(
|
||||
samplesReceived = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_samples_total",
|
||||
Help: "The total number of StatsD samples received.",
|
||||
},
|
||||
)
|
||||
sampleErrors = promauto.NewCounterVec(
|
||||
sampleErrors = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_sample_errors_total",
|
||||
Help: "The total number of errors parsing StatsD samples.",
|
||||
},
|
||||
[]string{"reason"},
|
||||
)
|
||||
tagsReceived = promauto.NewCounter(
|
||||
tagsReceived = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_tags_total",
|
||||
Help: "The total number of DogStatsD tags processed.",
|
||||
},
|
||||
)
|
||||
tagErrors = promauto.NewCounter(
|
||||
tagErrors = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_tag_errors_total",
|
||||
Help: "The number of errors parsing DogStatsD tags.",
|
||||
},
|
||||
)
|
||||
configLoads = promauto.NewCounterVec(
|
||||
configLoads = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_config_reloads_total",
|
||||
Help: "The number of configuration reloads.",
|
||||
},
|
||||
[]string{"outcome"},
|
||||
)
|
||||
mappingsCount = promauto.NewGauge(prometheus.GaugeOpts{
|
||||
mappingsCount = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "statsd_exporter_loaded_mappings",
|
||||
Help: "The current number of configured metric mappings.",
|
||||
})
|
||||
conflictingEventStats = promauto.NewCounterVec(
|
||||
conflictingEventStats = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_events_conflict_total",
|
||||
Help: "The total number of StatsD events with conflicting names.",
|
||||
},
|
||||
[]string{"type"},
|
||||
)
|
||||
errorEventStats = promauto.NewCounterVec(
|
||||
errorEventStats = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_events_error_total",
|
||||
Help: "The total number of StatsD events discarded due to errors.",
|
||||
},
|
||||
[]string{"reason"},
|
||||
)
|
||||
eventsActions = promauto.NewCounterVec(
|
||||
eventsActions = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_events_actions_total",
|
||||
Help: "The total number of StatsD events by action.",
|
||||
},
|
||||
[]string{"action"},
|
||||
)
|
||||
metricsCount = promauto.NewGaugeVec(
|
||||
metricsCount = prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "statsd_exporter_metrics_total",
|
||||
Help: "The total number of metrics.",
|
||||
|
@ -166,6 +169,40 @@ var (
|
|||
)
|
||||
)
|
||||
|
||||
func init() {
|
||||
prometheus.MustRegister(version.NewCollector("statsd_exporter"))
|
||||
prometheus.MustRegister(eventStats)
|
||||
prometheus.MustRegister(eventsFlushed)
|
||||
prometheus.MustRegister(eventsUnmapped)
|
||||
prometheus.MustRegister(udpPackets)
|
||||
prometheus.MustRegister(tcpConnections)
|
||||
prometheus.MustRegister(tcpErrors)
|
||||
prometheus.MustRegister(tcpLineTooLong)
|
||||
prometheus.MustRegister(unixgramPackets)
|
||||
prometheus.MustRegister(linesReceived)
|
||||
prometheus.MustRegister(samplesReceived)
|
||||
prometheus.MustRegister(sampleErrors)
|
||||
prometheus.MustRegister(tagsReceived)
|
||||
prometheus.MustRegister(tagErrors)
|
||||
prometheus.MustRegister(configLoads)
|
||||
prometheus.MustRegister(mappingsCount)
|
||||
prometheus.MustRegister(conflictingEventStats)
|
||||
prometheus.MustRegister(errorEventStats)
|
||||
prometheus.MustRegister(eventsActions)
|
||||
prometheus.MustRegister(metricsCount)
|
||||
}
|
||||
|
||||
// uncheckedCollector wraps a Collector but its Describe method yields no Desc.
|
||||
// This allows incoming metrics to have inconsistent label sets
|
||||
type uncheckedCollector struct {
|
||||
c prometheus.Collector
|
||||
}
|
||||
|
||||
func (u uncheckedCollector) Describe(_ chan<- *prometheus.Desc) {}
|
||||
func (u uncheckedCollector) Collect(c chan<- prometheus.Metric) {
|
||||
u.c.Collect(c)
|
||||
}
|
||||
|
||||
func serveHTTP(mux http.Handler, listenAddress string, logger log.Logger) {
|
||||
level.Error(logger).Log("msg", http.ListenAndServe(listenAddress, mux))
|
||||
os.Exit(1)
|
||||
|
@ -249,7 +286,7 @@ func main() {
|
|||
readBuffer = kingpin.Flag("statsd.read-buffer", "Size (in bytes) of the operating system's transmit read buffer associated with the UDP or Unixgram connection. Please make sure the kernel parameters net.core.rmem_max is set to a value greater than the value specified.").Int()
|
||||
cacheSize = kingpin.Flag("statsd.cache-size", "Maximum size of your metric mapping cache. Relies on least recently used replacement policy if max size is reached.").Default("1000").Int()
|
||||
cacheType = kingpin.Flag("statsd.cache-type", "Metric mapping cache type. Valid options are \"lru\" and \"random\"").Default("lru").Enum("lru", "random")
|
||||
eventQueueSize = kingpin.Flag("statsd.event-queue-size", "Size of internal queue for processing events.").Default("10000").Uint()
|
||||
eventQueueSize = kingpin.Flag("statsd.event-queue-size", "Size of internal queue for processing events.").Default("10000").Int()
|
||||
eventFlushThreshold = kingpin.Flag("statsd.event-flush-threshold", "Number of events to hold in queue before flushing.").Default("1000").Int()
|
||||
eventFlushInterval = kingpin.Flag("statsd.event-flush-interval", "Maximum time between event queue flushes.").Default("200ms").Duration()
|
||||
dumpFSMPath = kingpin.Flag("debug.dump-fsm", "The path to dump internal FSM generated for glob matching as Dot file.").Default("").String()
|
||||
|
@ -258,14 +295,11 @@ func main() {
|
|||
influxdbTagsEnabled = kingpin.Flag("statsd.parse-influxdb-tags", "Parse InfluxDB style tags. Enabled by default.").Default("true").Bool()
|
||||
libratoTagsEnabled = kingpin.Flag("statsd.parse-librato-tags", "Parse Librato style tags. Enabled by default.").Default("true").Bool()
|
||||
signalFXTagsEnabled = kingpin.Flag("statsd.parse-signalfx-tags", "Parse SignalFX style tags. Enabled by default.").Default("true").Bool()
|
||||
relayAddr = kingpin.Flag("statsd.relay.address", "The UDP relay target address (host:port)").String()
|
||||
relayPacketLen = kingpin.Flag("statsd.relay.packet-length", "Maximum relay output packet length to avoid fragmentation").Default("1400").Uint()
|
||||
)
|
||||
|
||||
promlogConfig := &promlog.Config{}
|
||||
flag.AddFlags(kingpin.CommandLine, promlogConfig)
|
||||
kingpin.Version(version.Print("statsd_exporter"))
|
||||
kingpin.CommandLine.UsageWriter(os.Stdout)
|
||||
kingpin.HelpFlag.Short('h')
|
||||
kingpin.Parse()
|
||||
logger := promlog.New(promlogConfig)
|
||||
|
@ -273,7 +307,6 @@ func main() {
|
|||
level.Error(logger).Log("msg", "failed to set log level", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
prometheus.MustRegister(version.NewCollector("statsd_exporter"))
|
||||
|
||||
parser := line.NewParser()
|
||||
if *dogstatsdTagsEnabled {
|
||||
|
@ -329,16 +362,6 @@ func main() {
|
|||
return
|
||||
}
|
||||
|
||||
var relayTarget *relay.Relay
|
||||
if *relayAddr != "" {
|
||||
var err error
|
||||
relayTarget, err = relay.NewRelay(logger, *relayAddr, *relayPacketLen)
|
||||
if err != nil {
|
||||
level.Error(logger).Log("msg", "Unable to create relay", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
level.Info(logger).Log("msg", "Accepting StatsD Traffic", "udp", *statsdListenUDP, "tcp", *statsdListenTCP, "unixgram", *statsdListenUnixgram)
|
||||
level.Info(logger).Log("msg", "Accepting Prometheus Requests", "addr", *listenAddress)
|
||||
|
||||
|
@ -375,7 +398,6 @@ func main() {
|
|||
UDPPackets: udpPackets,
|
||||
LinesReceived: linesReceived,
|
||||
EventsFlushed: eventsFlushed,
|
||||
Relay: relayTarget,
|
||||
SampleErrors: *sampleErrors,
|
||||
SamplesReceived: samplesReceived,
|
||||
TagErrors: tagErrors,
|
||||
|
@ -405,7 +427,6 @@ func main() {
|
|||
LineParser: parser,
|
||||
LinesReceived: linesReceived,
|
||||
EventsFlushed: eventsFlushed,
|
||||
Relay: relayTarget,
|
||||
SampleErrors: *sampleErrors,
|
||||
SamplesReceived: samplesReceived,
|
||||
TagErrors: tagErrors,
|
||||
|
@ -451,7 +472,6 @@ func main() {
|
|||
UnixgramPackets: unixgramPackets,
|
||||
LinesReceived: linesReceived,
|
||||
EventsFlushed: eventsFlushed,
|
||||
Relay: relayTarget,
|
||||
SampleErrors: *sampleErrors,
|
||||
SamplesReceived: samplesReceived,
|
||||
TagErrors: tagErrors,
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
The `pkg` directory is deprecated.
|
||||
Please do not add new packages to this directory.
|
||||
Existing packages will be moved elsewhere eventually.
|
|
@ -74,6 +74,12 @@ var (
|
|||
Help: "The number of lines discarded due to being too long.",
|
||||
},
|
||||
)
|
||||
unixgramPackets = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_unixgram_packets_total",
|
||||
Help: "The total number of StatsD packets received over Unixgram.",
|
||||
},
|
||||
)
|
||||
linesReceived = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_lines_total",
|
||||
|
@ -105,6 +111,17 @@ var (
|
|||
Help: "The number of errors parsing DogStatsD tags.",
|
||||
},
|
||||
)
|
||||
configLoads = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_config_reloads_total",
|
||||
Help: "The number of configuration reloads.",
|
||||
},
|
||||
[]string{"outcome"},
|
||||
)
|
||||
mappingsCount = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "statsd_exporter_loaded_mappings",
|
||||
Help: "The current number of configured metric mappings.",
|
||||
})
|
||||
conflictingEventStats = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_events_conflict_total",
|
||||
|
@ -401,76 +418,6 @@ func TestConflictingMetrics(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "histogram vs counter with count suffix",
|
||||
expected: []float64{2},
|
||||
in: event.Events{
|
||||
&event.ObserverEvent{
|
||||
OMetricName: "histogram_test1",
|
||||
OValue: 2,
|
||||
},
|
||||
&event.CounterEvent{
|
||||
CMetricName: "histogram_test1_count",
|
||||
CValue: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "histogram vs counter with sum suffix",
|
||||
expected: []float64{2},
|
||||
in: event.Events{
|
||||
&event.ObserverEvent{
|
||||
OMetricName: "histogram_test1",
|
||||
OValue: 2,
|
||||
},
|
||||
&event.CounterEvent{
|
||||
CMetricName: "histogram_test1_sum",
|
||||
CValue: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "histogram vs counter with bucket suffix",
|
||||
expected: []float64{2},
|
||||
in: event.Events{
|
||||
&event.ObserverEvent{
|
||||
OMetricName: "histogram_test1",
|
||||
OValue: 2,
|
||||
},
|
||||
&event.CounterEvent{
|
||||
CMetricName: "histogram_test1_bucket",
|
||||
CValue: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "histogram vs gauge with sum suffix",
|
||||
expected: []float64{2},
|
||||
in: event.Events{
|
||||
&event.ObserverEvent{
|
||||
OMetricName: "histogram_test1",
|
||||
OValue: 2,
|
||||
},
|
||||
&event.GaugeEvent{
|
||||
GMetricName: "histogram_test1_sum",
|
||||
GValue: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "histogram vs gauge with count suffix",
|
||||
expected: []float64{2},
|
||||
in: event.Events{
|
||||
&event.ObserverEvent{
|
||||
OMetricName: "histogram_test1",
|
||||
OValue: 2,
|
||||
},
|
||||
&event.GaugeEvent{
|
||||
GMetricName: "histogram_test1_count",
|
||||
GValue: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "counter vs histogram",
|
||||
expected: []float64{1},
|
||||
|
@ -590,11 +537,10 @@ mappings:
|
|||
events <- s.in
|
||||
close(events)
|
||||
}()
|
||||
reg := prometheus.NewRegistry()
|
||||
ex := NewExporter(reg, testMapper, log.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, testMapper, log.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex.Listen(events)
|
||||
|
||||
metrics, err := reg.Gather()
|
||||
metrics, err := prometheus.DefaultGatherer.Gather()
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot gather from DefaultGatherer: %v", err)
|
||||
}
|
||||
|
|
|
@ -239,6 +239,7 @@ samples:
|
|||
for _, sample := range samples {
|
||||
samplesReceived.Inc()
|
||||
components := strings.Split(sample, "|")
|
||||
samplingFactor := 1.0
|
||||
if len(components) < 2 || len(components) > 4 {
|
||||
sampleErrors.WithLabelValues("malformed_component").Inc()
|
||||
level.Debug(logger).Log("msg", "Bad component", "line", line)
|
||||
|
@ -272,7 +273,7 @@ samples:
|
|||
switch component[0] {
|
||||
case '@':
|
||||
|
||||
samplingFactor, err := strconv.ParseFloat(component[1:], 64)
|
||||
samplingFactor, err = strconv.ParseFloat(component[1:], 64)
|
||||
if err != nil {
|
||||
level.Debug(logger).Log("msg", "Invalid sampling factor", "component", component[1:], "line", line)
|
||||
sampleErrors.WithLabelValues("invalid_sample_factor").Inc()
|
||||
|
|
|
@ -25,7 +25,6 @@ import (
|
|||
|
||||
"github.com/prometheus/statsd_exporter/pkg/event"
|
||||
"github.com/prometheus/statsd_exporter/pkg/level"
|
||||
"github.com/prometheus/statsd_exporter/pkg/relay"
|
||||
)
|
||||
|
||||
type Parser interface {
|
||||
|
@ -40,7 +39,6 @@ type StatsDUDPListener struct {
|
|||
UDPPackets prometheus.Counter
|
||||
LinesReceived prometheus.Counter
|
||||
EventsFlushed prometheus.Counter
|
||||
Relay *relay.Relay
|
||||
SampleErrors prometheus.CounterVec
|
||||
SamplesReceived prometheus.Counter
|
||||
TagErrors prometheus.Counter
|
||||
|
@ -74,9 +72,6 @@ func (l *StatsDUDPListener) HandlePacket(packet []byte) {
|
|||
for _, line := range lines {
|
||||
level.Debug(l.Logger).Log("msg", "Incoming line", "proto", "udp", "line", line)
|
||||
l.LinesReceived.Inc()
|
||||
if l.Relay != nil && len(line) > 0 {
|
||||
l.Relay.RelayLine(line)
|
||||
}
|
||||
l.EventHandler.Queue(l.LineParser.LineToEvents(line, l.SampleErrors, l.SamplesReceived, l.TagErrors, l.TagsReceived, l.Logger))
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +83,6 @@ type StatsDTCPListener struct {
|
|||
LineParser Parser
|
||||
LinesReceived prometheus.Counter
|
||||
EventsFlushed prometheus.Counter
|
||||
Relay *relay.Relay
|
||||
SampleErrors prometheus.CounterVec
|
||||
SamplesReceived prometheus.Counter
|
||||
TagErrors prometheus.Counter
|
||||
|
@ -140,9 +134,6 @@ func (l *StatsDTCPListener) HandleConn(c *net.TCPConn) {
|
|||
break
|
||||
}
|
||||
l.LinesReceived.Inc()
|
||||
if l.Relay != nil && len(line) > 0 {
|
||||
l.Relay.RelayLine(string(line))
|
||||
}
|
||||
l.EventHandler.Queue(l.LineParser.LineToEvents(string(line), l.SampleErrors, l.SamplesReceived, l.TagErrors, l.TagsReceived, l.Logger))
|
||||
}
|
||||
}
|
||||
|
@ -155,7 +146,6 @@ type StatsDUnixgramListener struct {
|
|||
UnixgramPackets prometheus.Counter
|
||||
LinesReceived prometheus.Counter
|
||||
EventsFlushed prometheus.Counter
|
||||
Relay *relay.Relay
|
||||
SampleErrors prometheus.CounterVec
|
||||
SamplesReceived prometheus.Counter
|
||||
TagErrors prometheus.Counter
|
||||
|
@ -189,9 +179,6 @@ func (l *StatsDUnixgramListener) HandlePacket(packet []byte) {
|
|||
for _, line := range lines {
|
||||
level.Debug(l.Logger).Log("msg", "Incoming line", "proto", "unixgram", "line", line)
|
||||
l.LinesReceived.Inc()
|
||||
if l.Relay != nil && len(line) > 0 {
|
||||
l.Relay.RelayLine(line)
|
||||
}
|
||||
l.EventHandler.Queue(l.LineParser.LineToEvents(line, l.SampleErrors, l.SamplesReceived, l.TagErrors, l.TagsReceived, l.Logger))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,9 +39,6 @@ func EscapeMetricName(metricName string) string {
|
|||
// This is an character replacement method optimized for this limited
|
||||
// use case. It is much faster than using a regex.
|
||||
offset := 0
|
||||
|
||||
var prevChar rune
|
||||
|
||||
for i, c := range metricName {
|
||||
// Seek forward, skipping valid characters until we find one that needs
|
||||
// to be replaced, then add all the characters we've seen so far to the
|
||||
|
@ -50,13 +47,6 @@ func EscapeMetricName(metricName string) string {
|
|||
(c >= '0' && c <= '9') || (c == '_') {
|
||||
// Character is valid, so skip over it without doing anything.
|
||||
} else {
|
||||
// Double-dashes are allowed if there is a corresponding mapping.
|
||||
// For consistency, double-dashes should also be allowed in the default case.
|
||||
if c == '-' && prevChar == '-' {
|
||||
offset = i + utf8.RuneLen(c)
|
||||
continue
|
||||
}
|
||||
|
||||
if !escaped {
|
||||
// Up until now we've been lazy and avoided actually allocating
|
||||
// memory. Unfortunately we've now determined this string needs
|
||||
|
@ -68,8 +58,6 @@ func EscapeMetricName(metricName string) string {
|
|||
offset = i + utf8.RuneLen(c)
|
||||
sb.WriteByte('_')
|
||||
}
|
||||
|
||||
prevChar = c
|
||||
}
|
||||
|
||||
if !escaped {
|
||||
|
|
|
@ -20,8 +20,6 @@ func TestEscapeMetricName(t *testing.T) {
|
|||
"clean": "clean",
|
||||
"0starts_with_digit": "_0starts_with_digit",
|
||||
"with_underscore": "with_underscore",
|
||||
"with--doubledash": "with_doubledash",
|
||||
"with---multiple-dashes": "with_multiple_dashes",
|
||||
"with.dot": "with_dot",
|
||||
"with😱emoji": "with_emoji",
|
||||
"with.*.multiple": "with___multiple",
|
||||
|
@ -41,8 +39,6 @@ func BenchmarkEscapeMetricName(b *testing.B) {
|
|||
"clean",
|
||||
"0starts_with_digit",
|
||||
"with_underscore",
|
||||
"with--doubledash",
|
||||
"with---multiple-dashes",
|
||||
"with.dot",
|
||||
"with😱emoji",
|
||||
"with.*.multiple",
|
||||
|
|
|
@ -43,6 +43,6 @@ func (f *FSM) DumpFSM(w io.Writer) {
|
|||
idx++
|
||||
}
|
||||
// color for start state
|
||||
w.Write([]byte(fmt.Sprintln("0 [color=\"#a94442\",fillcolor=\"#f2dede\"];")))
|
||||
w.Write([]byte(fmt.Sprintf("0 [color=\"#a94442\",fillcolor=\"#f2dede\"];\n")))
|
||||
w.Write([]byte("}"))
|
||||
}
|
||||
|
|
|
@ -15,14 +15,14 @@ package mapper
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"io/ioutil"
|
||||
"regexp"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"gopkg.in/yaml.v2"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/prometheus/statsd_exporter/pkg/level"
|
||||
"github.com/prometheus/statsd_exporter/pkg/mapper/fsm"
|
||||
|
@ -65,8 +65,6 @@ type SummaryOptions struct {
|
|||
|
||||
type HistogramOptions struct {
|
||||
Buckets []float64 `yaml:"buckets"`
|
||||
NativeHistogramBucketFactor float64 `yaml:"native_histogram_bucket_factor"`
|
||||
NativeHistogramMaxBuckets uint32 `yaml:"native_histogram_max_buckets"`
|
||||
}
|
||||
|
||||
type metricObjective struct {
|
||||
|
@ -90,12 +88,6 @@ func (m *MetricMapper) InitFromYAMLString(fileContents string) error {
|
|||
if len(n.Defaults.HistogramOptions.Buckets) == 0 {
|
||||
n.Defaults.HistogramOptions.Buckets = prometheus.DefBuckets
|
||||
}
|
||||
if n.Defaults.HistogramOptions.NativeHistogramBucketFactor == 0 {
|
||||
n.Defaults.HistogramOptions.NativeHistogramBucketFactor = 1.1
|
||||
}
|
||||
if n.Defaults.HistogramOptions.NativeHistogramMaxBuckets <= 0 {
|
||||
n.Defaults.HistogramOptions.NativeHistogramMaxBuckets = 256
|
||||
}
|
||||
|
||||
if len(n.Defaults.SummaryOptions.Quantiles) == 0 {
|
||||
n.Defaults.SummaryOptions.Quantiles = defaultQuantiles
|
||||
|
@ -241,10 +233,6 @@ func (m *MetricMapper) InitFromYAMLString(fileContents string) error {
|
|||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
|
||||
if m.Logger == nil {
|
||||
m.Logger = log.NewNopLogger()
|
||||
}
|
||||
|
||||
m.Defaults = n.Defaults
|
||||
m.Mappings = n.Mappings
|
||||
|
||||
|
@ -271,11 +259,15 @@ func (m *MetricMapper) InitFromYAMLString(fileContents string) error {
|
|||
m.MappingsCount.Set(float64(len(n.Mappings)))
|
||||
}
|
||||
|
||||
if m.Logger == nil {
|
||||
m.Logger = log.NewNopLogger()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MetricMapper) InitFromFile(fileName string) error {
|
||||
mappingStr, err := os.ReadFile(fileName)
|
||||
mappingStr, err := ioutil.ReadFile(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -389,6 +381,7 @@ func (m *MetricMapper) GetMapping(statsdMetric string, statsdMetricType MetricTy
|
|||
// make a shallow copy so that we do not overwrite name
|
||||
// as multiple names can be matched by same mapping
|
||||
func copyMetricMapping(in *MetricMapping) *MetricMapping {
|
||||
out := *in
|
||||
var out MetricMapping
|
||||
out = *in
|
||||
return &out
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@ import (
|
|||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
|
||||
"github.com/prometheus/statsd_exporter/pkg/mappercache/lru"
|
||||
"github.com/prometheus/statsd_exporter/pkg/mappercache/randomreplacement"
|
||||
)
|
||||
|
@ -244,9 +242,7 @@ mappings:
|
|||
"foo.bar.baz",
|
||||
}
|
||||
|
||||
mapper := MetricMapper{
|
||||
Logger: log.NewNopLogger(),
|
||||
}
|
||||
mapper := MetricMapper{}
|
||||
err := mapper.InitFromYAMLString(config)
|
||||
if err != nil {
|
||||
b.Fatalf("Config load error: %s %s", config, err)
|
||||
|
|
|
@ -19,7 +19,6 @@ import (
|
|||
"hash"
|
||||
"hash/fnv"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
@ -166,11 +165,6 @@ func (r *Registry) GetCounter(metricName string, labels prometheus.Labels, help
|
|||
return nil, fmt.Errorf("metric with name %s is already registered", metricName)
|
||||
}
|
||||
|
||||
err := r.checkHistogramNameCollision(metricName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var counterVec *prometheus.CounterVec
|
||||
if vh == nil {
|
||||
metricsCount.WithLabelValues("counter").Inc()
|
||||
|
@ -187,6 +181,7 @@ func (r *Registry) GetCounter(metricName string, labels prometheus.Labels, help
|
|||
}
|
||||
|
||||
var counter prometheus.Counter
|
||||
var err error
|
||||
if counter, err = counterVec.GetMetricWith(labels); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -195,18 +190,6 @@ func (r *Registry) GetCounter(metricName string, labels prometheus.Labels, help
|
|||
return counter, nil
|
||||
}
|
||||
|
||||
func (r *Registry) checkHistogramNameCollision(metricName string) error {
|
||||
histogramSuffixes := []string{"_bucket", "_count", "_sum"}
|
||||
for _, suffix := range histogramSuffixes {
|
||||
if strings.HasSuffix(metricName, suffix) {
|
||||
if r.MetricConflicts(strings.TrimSuffix(metricName, suffix), metrics.CounterMetricType) {
|
||||
return fmt.Errorf("metric with name %s is already registered", metricName)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Registry) GetGauge(metricName string, labels prometheus.Labels, help string, mapping *mapper.MetricMapping, metricsCount *prometheus.GaugeVec) (prometheus.Gauge, error) {
|
||||
hash, labelNames := r.HashLabels(labels)
|
||||
vh, mh := r.Get(metricName, hash, metrics.GaugeMetricType)
|
||||
|
@ -218,11 +201,6 @@ func (r *Registry) GetGauge(metricName string, labels prometheus.Labels, help st
|
|||
return nil, fmt.Errorf("metrics.Metric with name %s is already registered", metricName)
|
||||
}
|
||||
|
||||
err := r.checkHistogramNameCollision(metricName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("metrics.Metric with name %s is already registered", metricName)
|
||||
}
|
||||
|
||||
var gaugeVec *prometheus.GaugeVec
|
||||
if vh == nil {
|
||||
metricsCount.WithLabelValues("gauge").Inc()
|
||||
|
@ -239,6 +217,7 @@ func (r *Registry) GetGauge(metricName string, labels prometheus.Labels, help st
|
|||
}
|
||||
|
||||
var gauge prometheus.Gauge
|
||||
var err error
|
||||
if gauge, err = gaugeVec.GetMetricWith(labels); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -274,25 +253,13 @@ func (r *Registry) GetHistogram(metricName string, labels prometheus.Labels, hel
|
|||
if mapping.HistogramOptions != nil && len(mapping.HistogramOptions.Buckets) > 0 {
|
||||
buckets = mapping.HistogramOptions.Buckets
|
||||
}
|
||||
|
||||
bucketFactor := r.Mapper.Defaults.HistogramOptions.NativeHistogramBucketFactor
|
||||
if mapping.HistogramOptions != nil && mapping.HistogramOptions.NativeHistogramBucketFactor > 0 {
|
||||
bucketFactor = mapping.HistogramOptions.NativeHistogramBucketFactor
|
||||
}
|
||||
|
||||
maxBuckets := r.Mapper.Defaults.HistogramOptions.NativeHistogramMaxBuckets
|
||||
if mapping.HistogramOptions != nil && mapping.HistogramOptions.NativeHistogramMaxBuckets > 0 {
|
||||
maxBuckets = mapping.HistogramOptions.NativeHistogramMaxBuckets
|
||||
}
|
||||
histogramVec = prometheus.NewHistogramVec(prometheus.HistogramOpts{
|
||||
Name: metricName,
|
||||
Help: help,
|
||||
Buckets: buckets,
|
||||
NativeHistogramBucketFactor: bucketFactor,
|
||||
NativeHistogramMaxBucketNumber: maxBuckets,
|
||||
}, labelNames)
|
||||
|
||||
if err := r.Registerer.Register(uncheckedCollector{histogramVec}); err != nil {
|
||||
if err := prometheus.Register(uncheckedCollector{histogramVec}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
|
@ -361,7 +328,7 @@ func (r *Registry) GetSummary(metricName string, labels prometheus.Labels, help
|
|||
BufCap: summaryOptions.BufCap,
|
||||
}, labelNames)
|
||||
|
||||
if err := r.Registerer.Register(uncheckedCollector{summaryVec}); err != nil {
|
||||
if err := prometheus.Register(uncheckedCollector{summaryVec}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -1,167 +0,0 @@
|
|||
// Copyright 2021 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package relay
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/statsd_exporter/pkg/clock"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
"github.com/prometheus/statsd_exporter/pkg/level"
|
||||
)
|
||||
|
||||
type Relay struct {
|
||||
addr *net.UDPAddr
|
||||
bufferChannel chan []byte
|
||||
conn *net.UDPConn
|
||||
logger log.Logger
|
||||
packetLength uint
|
||||
|
||||
packetsTotal prometheus.Counter
|
||||
longLinesTotal prometheus.Counter
|
||||
relayedLinesTotal prometheus.Counter
|
||||
}
|
||||
|
||||
var (
|
||||
relayPacketsTotal = promauto.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_relay_packets_total",
|
||||
Help: "The number of StatsD packets relayed.",
|
||||
},
|
||||
[]string{"target"},
|
||||
)
|
||||
relayLongLinesTotal = promauto.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_relay_long_lines_total",
|
||||
Help: "The number lines that were too long to relay.",
|
||||
},
|
||||
[]string{"target"},
|
||||
)
|
||||
relayLinesRelayedTotal = promauto.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_relay_lines_relayed_total",
|
||||
Help: "The number of lines that were buffered to be relayed.",
|
||||
},
|
||||
[]string{"target"},
|
||||
)
|
||||
)
|
||||
|
||||
// NewRelay creates a statsd UDP relay. It can be used to send copies of statsd raw
|
||||
// lines to a separate service.
|
||||
func NewRelay(l log.Logger, target string, packetLength uint) (*Relay, error) {
|
||||
addr, err := net.ResolveUDPAddr("udp", target)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to resolve target %s, err: %w", target, err)
|
||||
}
|
||||
conn, err := net.ListenUDP("udp", nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to listen on UDP, err: %w", err)
|
||||
}
|
||||
|
||||
c := make(chan []byte, 100)
|
||||
|
||||
r := Relay{
|
||||
addr: addr,
|
||||
bufferChannel: c,
|
||||
conn: conn,
|
||||
logger: l,
|
||||
packetLength: packetLength,
|
||||
|
||||
packetsTotal: relayPacketsTotal.WithLabelValues(target),
|
||||
longLinesTotal: relayLongLinesTotal.WithLabelValues(target),
|
||||
relayedLinesTotal: relayLinesRelayedTotal.WithLabelValues(target),
|
||||
}
|
||||
|
||||
// Startup the UDP sender.
|
||||
go r.relayOutput()
|
||||
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
// relayOutput buffers statsd lines and sends them to the relay target.
|
||||
func (r *Relay) relayOutput() {
|
||||
var buffer bytes.Buffer
|
||||
var err error
|
||||
|
||||
relayInterval := clock.NewTicker(1 * time.Second)
|
||||
defer relayInterval.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-relayInterval.C:
|
||||
err = r.sendPacket(buffer.Bytes())
|
||||
if err != nil {
|
||||
level.Error(r.logger).Log("msg", "Error sending UDP packet", "error", err)
|
||||
return
|
||||
}
|
||||
// Clear out the buffer.
|
||||
buffer.Reset()
|
||||
case b := <-r.bufferChannel:
|
||||
if uint(len(b)+buffer.Len()) > r.packetLength {
|
||||
level.Debug(r.logger).Log("msg", "Buffer full, sending packet", "length", buffer.Len())
|
||||
err = r.sendPacket(buffer.Bytes())
|
||||
if err != nil {
|
||||
level.Error(r.logger).Log("msg", "Error sending UDP packet", "error", err)
|
||||
return
|
||||
}
|
||||
// Seed the new buffer with the new line.
|
||||
buffer.Reset()
|
||||
buffer.Write(b)
|
||||
} else {
|
||||
level.Debug(r.logger).Log("msg", "Adding line to buffer", "line", b)
|
||||
buffer.Write(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sendPacket sends a single relay line to the destination target.
|
||||
func (r *Relay) sendPacket(buf []byte) error {
|
||||
if len(buf) == 0 {
|
||||
level.Debug(r.logger).Log("msg", "Empty buffer, nothing to send")
|
||||
return nil
|
||||
}
|
||||
level.Debug(r.logger).Log("msg", "Sending packet", "length", len(buf), "data", buf)
|
||||
_, err := r.conn.WriteToUDP(buf, r.addr)
|
||||
r.packetsTotal.Inc()
|
||||
return err
|
||||
}
|
||||
|
||||
// RelayLine processes a single statsd line and forwards it to the relay target.
|
||||
func (r *Relay) RelayLine(l string) {
|
||||
lineLength := uint(len(l))
|
||||
if lineLength == 0 {
|
||||
level.Debug(r.logger).Log("msg", "Empty line, not relaying")
|
||||
return
|
||||
}
|
||||
if lineLength > r.packetLength-1 {
|
||||
level.Warn(r.logger).Log("msg", "line too long, not relaying", "length", lineLength, "max", r.packetLength)
|
||||
r.longLinesTotal.Inc()
|
||||
return
|
||||
}
|
||||
level.Debug(r.logger).Log("msg", "Relaying line", "line", l)
|
||||
if !strings.HasSuffix(l, "\n") {
|
||||
l = l + "\n"
|
||||
}
|
||||
r.relayedLinesTotal.Inc()
|
||||
r.bufferChannel <- []byte(l)
|
||||
}
|
|
@ -1,176 +0,0 @@
|
|||
// Copyright 2022 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package relay
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
"github.com/prometheus/statsd_exporter/pkg/clock"
|
||||
"github.com/stvp/go-udp-testing"
|
||||
)
|
||||
|
||||
func TestRelay_RelayLine(t *testing.T) {
|
||||
type args struct {
|
||||
lines []string
|
||||
expected string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
}{
|
||||
{
|
||||
name: "multiple lines",
|
||||
args: args{
|
||||
lines: []string{"foo5:100|c|#tag1:bar,#tag2:baz", "foo2:200|c|#tag1:bar,#tag2:baz"},
|
||||
expected: "foo5:100|c|#tag1:bar,#tag2:baz\n",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
udp.SetAddr(":1160")
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tickerCh := make(chan time.Time)
|
||||
clock.ClockInstance = &clock.Clock{
|
||||
TickerCh: tickerCh,
|
||||
}
|
||||
clock.ClockInstance.Instant = time.Unix(0, 0)
|
||||
|
||||
logger := log.NewNopLogger()
|
||||
r, err := NewRelay(
|
||||
logger,
|
||||
"localhost:1160",
|
||||
200,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Did not expect error while creating relay.")
|
||||
}
|
||||
|
||||
udp.ShouldReceive(t, tt.args.expected, func() {
|
||||
for _, line := range tt.args.lines {
|
||||
r.RelayLine(line)
|
||||
}
|
||||
|
||||
for goSchedTimes := 0; goSchedTimes < 1000; goSchedTimes++ {
|
||||
if len(r.bufferChannel) == 0 {
|
||||
break
|
||||
}
|
||||
runtime.Gosched()
|
||||
}
|
||||
|
||||
// Tick time forward to trigger a packet send.
|
||||
clock.ClockInstance.Instant = time.Unix(1, 10)
|
||||
clock.ClockInstance.TickerCh <- time.Unix(0, 0)
|
||||
})
|
||||
|
||||
metrics, err := prometheus.DefaultGatherer.Gather()
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot gather from DefaultGatherer: %v", err)
|
||||
}
|
||||
|
||||
metricNames := map[string]float64{
|
||||
"statsd_exporter_relay_long_lines_total": 0,
|
||||
"statsd_exporter_relay_lines_relayed_total": float64(len(tt.args.lines)),
|
||||
}
|
||||
for metricName, expectedValue := range metricNames {
|
||||
metric := getFloat64(metrics, metricName, prometheus.Labels{"target": "localhost:1160"})
|
||||
|
||||
if metric == nil {
|
||||
t.Fatalf("Could not find time series with first label set for metric: %s", metricName)
|
||||
}
|
||||
if *metric != expectedValue {
|
||||
t.Errorf("Expected metric %s to be %f, got %f", metricName, expectedValue, *metric)
|
||||
}
|
||||
}
|
||||
|
||||
prometheus.Unregister(relayLongLinesTotal)
|
||||
prometheus.Unregister(relayLinesRelayedTotal)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// getFloat64 search for metric by name in array of MetricFamily and then search a value by labels.
|
||||
// Method returns a value or nil if metric is not found.
|
||||
func getFloat64(metrics []*dto.MetricFamily, name string, labels prometheus.Labels) *float64 {
|
||||
var metricFamily *dto.MetricFamily
|
||||
for _, m := range metrics {
|
||||
if *m.Name == name {
|
||||
metricFamily = m
|
||||
break
|
||||
}
|
||||
}
|
||||
if metricFamily == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var metric *dto.Metric
|
||||
labelStr := fmt.Sprintf("%v", labels)
|
||||
for _, m := range metricFamily.Metric {
|
||||
l := labelPairsAsLabels(m.GetLabel())
|
||||
ls := fmt.Sprintf("%v", l)
|
||||
if labelStr == ls {
|
||||
metric = m
|
||||
break
|
||||
}
|
||||
}
|
||||
if metric == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var value float64
|
||||
if metric.Gauge != nil {
|
||||
value = metric.Gauge.GetValue()
|
||||
return &value
|
||||
}
|
||||
if metric.Counter != nil {
|
||||
value = metric.Counter.GetValue()
|
||||
return &value
|
||||
}
|
||||
if metric.Histogram != nil {
|
||||
value = metric.Histogram.GetSampleSum()
|
||||
return &value
|
||||
}
|
||||
if metric.Summary != nil {
|
||||
value = metric.Summary.GetSampleSum()
|
||||
return &value
|
||||
}
|
||||
if metric.Untyped != nil {
|
||||
value = metric.Untyped.GetValue()
|
||||
return &value
|
||||
}
|
||||
panic(fmt.Errorf("collected a non-gauge/counter/histogram/summary/untyped metric: %s", metric))
|
||||
}
|
||||
|
||||
func labelPairsAsLabels(pairs []*dto.LabelPair) (labels prometheus.Labels) {
|
||||
labels = prometheus.Labels{}
|
||||
for _, pair := range pairs {
|
||||
if pair.Name == nil {
|
||||
continue
|
||||
}
|
||||
value := ""
|
||||
if pair.Value != nil {
|
||||
value = *pair.Value
|
||||
}
|
||||
labels[*pair.Name] = value
|
||||
}
|
||||
return
|
||||
}
|
Loading…
Reference in a new issue