mirror of
https://github.com/prometheus/statsd_exporter.git
synced 2024-11-10 17:31:07 +00:00
Compare commits
85 commits
Author | SHA1 | Date | |
---|---|---|---|
|
285293f587 | ||
|
7b20c1c6b0 | ||
|
8cf95221d1 | ||
|
3a4875414b | ||
|
e103da1d09 | ||
|
3082cf590c | ||
|
5d59712795 | ||
|
9803afaa8d | ||
|
009fcca35f | ||
|
3e8c235b06 | ||
|
c0a390a2c4 | ||
|
9cf8734c97 | ||
|
211680b98c | ||
|
bcd2cd8862 | ||
|
3cd0545478 | ||
|
64cc00e019 | ||
|
8aac1cabf3 | ||
|
e3378f8027 | ||
|
c18857b71b | ||
|
a20db6eec6 | ||
|
a7b501d3f2 | ||
|
2a6c1a326b | ||
|
1a5428f4ef | ||
|
0c2c1d96f9 | ||
|
eccf511051 | ||
|
658dadba2f | ||
|
77d911b7fe | ||
|
c7a3f16195 | ||
|
c818915ae3 | ||
|
32f8087bcc | ||
|
2d0de3fba8 | ||
|
cfb74254cb | ||
|
b967f755be | ||
|
1221aed101 | ||
|
4cef1c0d49 | ||
|
58c8a24608 | ||
|
da51813af4 | ||
|
4fcebbde52 | ||
|
90547ea496 | ||
|
3d4d6a9d5c | ||
|
c5aee286ee | ||
|
2b2623218f | ||
|
060a3a8870 | ||
|
8aec6fdf63 | ||
|
96609f9679 | ||
|
468af47dfb | ||
|
da94065b43 | ||
|
ba68944bec | ||
|
7b4f7310ae | ||
|
921ad0771f | ||
|
dcb9cc9446 | ||
|
905f00863b | ||
|
58769c7b4d | ||
|
9c4dfce4e0 | ||
|
29c77f407c | ||
|
233d74d0f7 | ||
|
3f985fa9ac | ||
|
479379a908 | ||
|
6e02dfcaae | ||
|
2c4ffa9620 | ||
|
ac0ef06e65 | ||
|
337849188c | ||
|
4b21c8e662 | ||
|
91ccdb962a | ||
|
d93cb36b75 | ||
|
6483ce0ffe | ||
|
d5473a0f96 | ||
|
b9ee6639ce | ||
|
80810d614e | ||
|
cae614397a | ||
|
e729f64ef3 | ||
|
adeacdd760 | ||
|
a19a729111 | ||
|
4c268bcdf7 | ||
|
8ec3225483 | ||
|
7d28d2145f | ||
|
48b0038897 | ||
|
abc3a1f95c | ||
|
4a0e88e27b | ||
|
7188ed4292 | ||
|
c48fa1bfa7 | ||
|
5d3e63295a | ||
|
8fdc626bfc | ||
|
8adea73c00 | ||
|
a853c2b0b2 |
30 changed files with 2318 additions and 555 deletions
|
@ -5,7 +5,7 @@ executors:
|
|||
# Whenever the Go version is updated here, .promu.yml should also be updated.
|
||||
golang:
|
||||
docker:
|
||||
- image: cimg/go:1.19
|
||||
- image: cimg/go:1.23
|
||||
jobs:
|
||||
test:
|
||||
executor: golang
|
||||
|
|
57
.github/workflows/container_description.yml
vendored
Normal file
57
.github/workflows/container_description.yml
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
---
|
||||
name: Push README to Docker Hub
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- "README.md"
|
||||
- "README-containers.md"
|
||||
- ".github/workflows/container_description.yml"
|
||||
branches: [ main, master ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
PushDockerHubReadme:
|
||||
runs-on: ubuntu-latest
|
||||
name: Push README to Docker Hub
|
||||
if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks.
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Set docker hub repo name
|
||||
run: echo "DOCKER_REPO_NAME=$(make docker-repo-name)" >> $GITHUB_ENV
|
||||
- name: Push README to Dockerhub
|
||||
uses: christian-korneck/update-container-description-action@d36005551adeaba9698d8d67a296bd16fa91f8e8 # v1
|
||||
env:
|
||||
DOCKER_USER: ${{ secrets.DOCKER_HUB_LOGIN }}
|
||||
DOCKER_PASS: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
||||
with:
|
||||
destination_container_repo: ${{ env.DOCKER_REPO_NAME }}
|
||||
provider: dockerhub
|
||||
short_description: ${{ env.DOCKER_REPO_NAME }}
|
||||
# Empty string results in README-containers.md being pushed if it
|
||||
# exists. Otherwise, README.md is pushed.
|
||||
readme_file: ''
|
||||
|
||||
PushQuayIoReadme:
|
||||
runs-on: ubuntu-latest
|
||||
name: Push README to quay.io
|
||||
if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks.
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Set quay.io org name
|
||||
run: echo "DOCKER_REPO=$(echo quay.io/${GITHUB_REPOSITORY_OWNER} | tr -d '-')" >> $GITHUB_ENV
|
||||
- name: Set quay.io repo name
|
||||
run: echo "DOCKER_REPO_NAME=$(make docker-repo-name)" >> $GITHUB_ENV
|
||||
- name: Push README to quay.io
|
||||
uses: christian-korneck/update-container-description-action@d36005551adeaba9698d8d67a296bd16fa91f8e8 # v1
|
||||
env:
|
||||
DOCKER_APIKEY: ${{ secrets.QUAY_IO_API_TOKEN }}
|
||||
with:
|
||||
destination_container_repo: ${{ env.DOCKER_REPO_NAME }}
|
||||
provider: quay
|
||||
# Empty string results in README-containers.md being pushed if it
|
||||
# exists. Otherwise, README.md is pushed.
|
||||
readme_file: ''
|
19
.github/workflows/golangci-lint.yml
vendored
19
.github/workflows/golangci-lint.yml
vendored
|
@ -12,21 +12,28 @@ on:
|
|||
- ".golangci.yml"
|
||||
pull_request:
|
||||
|
||||
permissions: # added using https://github.com/step-security/secure-repo
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
golangci:
|
||||
permissions:
|
||||
contents: read # for actions/checkout to fetch code
|
||||
pull-requests: read # for golangci/golangci-lint-action to fetch pull requests
|
||||
name: lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- name: install Go
|
||||
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
|
||||
with:
|
||||
go-version: 1.21.x
|
||||
go-version: 1.23.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@3a919529898de77ec3da873e3063ca4b10e7f5cc # v3.7.0
|
||||
uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1
|
||||
with:
|
||||
version: v1.54.2
|
||||
args: --verbose
|
||||
version: v1.61.0
|
||||
|
|
|
@ -5,20 +5,19 @@ linters:
|
|||
disable:
|
||||
- errcheck
|
||||
enable:
|
||||
- deadcode
|
||||
- goimports
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- nakedret
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- unused
|
||||
- varcheck
|
||||
- whitespace
|
||||
linters-settings:
|
||||
govet:
|
||||
check-shadowing: true
|
||||
enable-all: true
|
||||
disable:
|
||||
- fieldalignment
|
||||
issues:
|
||||
exclude-use-default: false
|
||||
exclude:
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
go:
|
||||
# Whenever the Go version is updated here, .circle/config.yml should also
|
||||
# be updated.
|
||||
version: 1.19
|
||||
version: 1.23
|
||||
repository:
|
||||
path: github.com/prometheus/statsd_exporter
|
||||
build:
|
||||
flags: -a -tags 'netgo static_build'
|
||||
ldflags: |
|
||||
-X github.com/prometheus/common/version.Version={{.Version}}
|
||||
-X github.com/prometheus/common/version.Revision={{.Revision}}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
---
|
||||
extends: default
|
||||
ignore: |
|
||||
ui/react-app/node_modules
|
||||
|
||||
rules:
|
||||
braces:
|
||||
|
|
24
CHANGELOG.md
24
CHANGELOG.md
|
@ -1,3 +1,27 @@
|
|||
## 0.28.0 / 2024-10-25
|
||||
|
||||
* [CHANGE] Update exporter-toolkit & switch to slog ([#586](https://github.com/prometheus/statsd_exporter/pull/586))
|
||||
* [CHANGE] Update client_golang and prometheus-common
|
||||
|
||||
This is a breaking change for library users.
|
||||
|
||||
## 0.27.2 / 2024-10-07
|
||||
|
||||
* [BUGFIX] Fix panic on certain invalid lines ([#579](https://github.com/prometheus/statsd_exporter/pull/579))
|
||||
|
||||
## 0.27.1 / 2024-08-18
|
||||
|
||||
* [FEATURE] Support [dogstatsd extended aggregation](https://github.com/DataDog/datadog-go/blob/master/README.md#extended-aggregation) ([#558](https://github.com/prometheus/statsd_exporter/pull/558))
|
||||
* [SECURITY] Update dependencies
|
||||
|
||||
Thank you [@GrgDev](https://github.com/GrgDev) for the contribution!
|
||||
|
||||
## 0.26.1 / 2024-03-22
|
||||
|
||||
* [SECURITY] Update dependencies, including `google.golang.org/protobuf` for CVE-2024-24786
|
||||
|
||||
This is a maintenance release.
|
||||
|
||||
## 0.26.0 / 2023-12-06
|
||||
|
||||
* [CHANGE] Update dependencies: prometheus/common, client model, and Go 1.21
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
* Matthias Rampke <matthias@prometheus.io>
|
||||
* Pedro Tanaka [@pedro-stanaka](https://github.com/pedro-stanaka)
|
||||
|
|
|
@ -49,23 +49,23 @@ endif
|
|||
GOTEST := $(GO) test
|
||||
GOTEST_DIR :=
|
||||
ifneq ($(CIRCLE_JOB),)
|
||||
ifneq ($(shell command -v gotestsum > /dev/null),)
|
||||
ifneq ($(shell command -v gotestsum 2> /dev/null),)
|
||||
GOTEST_DIR := test-results
|
||||
GOTEST := gotestsum --junitfile $(GOTEST_DIR)/unit-tests.xml --
|
||||
endif
|
||||
endif
|
||||
|
||||
PROMU_VERSION ?= 0.15.0
|
||||
PROMU_VERSION ?= 0.17.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.54.2
|
||||
# golangci-lint only supports linux, darwin and windows platforms on i386/amd64.
|
||||
GOLANGCI_LINT_VERSION ?= v1.60.2
|
||||
# golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64.
|
||||
# windows isn't included here because of the path separator being different.
|
||||
ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin))
|
||||
ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386))
|
||||
ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386 arm64))
|
||||
# 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))
|
||||
|
@ -169,16 +169,20 @@ common-vet:
|
|||
common-lint: $(GOLANGCI_LINT)
|
||||
ifdef GOLANGCI_LINT
|
||||
@echo ">> running golangci-lint"
|
||||
# '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)
|
||||
endif
|
||||
|
||||
.PHONY: common-lint-fix
|
||||
common-lint-fix: $(GOLANGCI_LINT)
|
||||
ifdef GOLANGCI_LINT
|
||||
@echo ">> running golangci-lint fix"
|
||||
$(GOLANGCI_LINT) run --fix $(GOLANGCI_LINT_OPTS) $(pkgs)
|
||||
endif
|
||||
|
||||
.PHONY: common-yamllint
|
||||
common-yamllint:
|
||||
@echo ">> running yamllint on all YAML files in the repository"
|
||||
ifeq (, $(shell command -v yamllint > /dev/null))
|
||||
ifeq (, $(shell command -v yamllint 2> /dev/null))
|
||||
@echo "yamllint not installed so skipping"
|
||||
else
|
||||
yamllint .
|
||||
|
@ -204,6 +208,10 @@ common-tarball: promu
|
|||
@echo ">> building release tarball"
|
||||
$(PROMU) tarball --prefix $(PREFIX) $(BIN_DIR)
|
||||
|
||||
.PHONY: common-docker-repo-name
|
||||
common-docker-repo-name:
|
||||
@echo "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)"
|
||||
|
||||
.PHONY: common-docker $(BUILD_DOCKER_ARCHS)
|
||||
common-docker: $(BUILD_DOCKER_ARCHS)
|
||||
$(BUILD_DOCKER_ARCHS): common-docker-%:
|
||||
|
@ -267,3 +275,9 @@ $(1)_precheck:
|
|||
exit 1; \
|
||||
fi
|
||||
endef
|
||||
|
||||
govulncheck: install-govulncheck
|
||||
govulncheck ./...
|
||||
|
||||
install-govulncheck:
|
||||
command -v govulncheck > /dev/null || go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
|
|
70
README.md
70
README.md
|
@ -79,6 +79,7 @@ in the DogStatsD documentation for the concept description and
|
|||
[Datagram Format](https://docs.datadoghq.com/developers/dogstatsd/datagram_shell/).
|
||||
If you encounter problems, note that this tagging style is incompatible with
|
||||
the original `statsd` implementation.
|
||||
The exporter also supports [DogStatD extended aggregations](https://github.com/prometheus/statsd_exporter/pull/558) in combination with DogStatsD tags, but not other tagging styles.
|
||||
|
||||
For [SignalFX dimension](https://github.com/signalfx/signalfx-agent/blob/main/docs/monitors/collectd-statsd.md#adding-dimensions-to-statsd-metrics), add the tags to the metric name in square brackets, as so:
|
||||
|
||||
|
@ -108,71 +109,7 @@ NOTE: Version 0.7.0 switched to the [kingpin](https://github.com/alecthomas/king
|
|||
* boolean long flags are disabled by prefixing with no (`--flag-name` is true, `--no-flag-name` is false)
|
||||
* multiple short flags can be combined (but there currently is only one)
|
||||
* flag processing stops at the first `--`
|
||||
|
||||
```
|
||||
usage: statsd_exporter [<flags>]
|
||||
|
||||
Flags:
|
||||
-h, --help Show context-sensitive help (also try
|
||||
--help-long and --help-man).
|
||||
--web.listen-address=":9102"
|
||||
The address on which to expose the web interface
|
||||
and generated Prometheus metrics.
|
||||
--web.enable-lifecycle Enable shutdown and reload via HTTP request.
|
||||
--web.telemetry-path="/metrics"
|
||||
Path under which to expose metrics.
|
||||
--statsd.listen-udp=":9125"
|
||||
The UDP address on which to receive statsd
|
||||
metric lines. "" disables it.
|
||||
--statsd.listen-tcp=":9125"
|
||||
The TCP address on which to receive statsd
|
||||
metric lines. "" disables it.
|
||||
--statsd.listen-unixgram=""
|
||||
The Unixgram socket path to receive statsd
|
||||
metric lines in datagram. "" disables it.
|
||||
--statsd.unixsocket-mode="755"
|
||||
The permission mode of the unix socket.
|
||||
--statsd.mapping-config=STATSD.MAPPING-CONFIG
|
||||
Metric mapping configuration file name.
|
||||
--statsd.read-buffer=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.
|
||||
--statsd.cache-size=1000 Maximum size of your metric mapping cache.
|
||||
Relies on least recently used replacement policy
|
||||
if max size is reached.
|
||||
--statsd.cache-type=lru Metric mapping cache type. Valid options are
|
||||
"lru" and "random"
|
||||
--statsd.event-queue-size=10000
|
||||
Size of internal queue for processing events
|
||||
--statsd.event-flush-threshold=1000
|
||||
Number of events to hold in queue before
|
||||
flushing
|
||||
--statsd.event-flush-interval=200ms
|
||||
Maximum time between event queue flushes.
|
||||
--debug.dump-fsm="" The path to dump internal FSM generated for
|
||||
glob matching as Dot file.
|
||||
--check-config Check configuration and exit.
|
||||
--statsd.parse-dogstatsd-tags
|
||||
Parse DogStatsd style tags. Enabled by default.
|
||||
--statsd.parse-influxdb-tags
|
||||
Parse InfluxDB style tags. Enabled by default.
|
||||
--statsd.parse-librato-tags
|
||||
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,
|
||||
json]
|
||||
--version Show application version.
|
||||
```
|
||||
* see `--help` for a full list of flags
|
||||
|
||||
## Lifecycle API
|
||||
|
||||
|
@ -604,7 +541,7 @@ mappings:
|
|||
scale: 1e-6
|
||||
```
|
||||
|
||||
### Event flushing configuration
|
||||
### Event flushing configuration
|
||||
|
||||
Internally `statsd_exporter` runs a goroutine for each network listener (UDP, TCP & Unix Socket). These each receive and parse metrics received into an event. For performance purposes, these events are queued internally and flushed to the main exporter goroutine periodically in batches. The size of this queue and the flush criteria can be tuned with the `--statsd.event-queue-size`, `--statsd.event-flush-threshold` and `--statsd.event-flush-interval`. However, the defaults should perform well even for very high traffic environments.
|
||||
|
||||
|
@ -633,7 +570,6 @@ Semantic versioning of the exporter is based on the impact on users of the expor
|
|||
|
||||
We encourage re-use of these packages and welcome [issues](https://github.com/prometheus/statsd_exporter/issues?q=is%3Aopen+is%3Aissue+label%3Alibrary) related to their usability as a library.
|
||||
|
||||
[travis]: https://travis-ci.org/prometheus/statsd_exporter
|
||||
[circleci]: https://circleci.com/gh/prometheus/statsd_exporter
|
||||
[quay]: https://quay.io/repository/prometheus/statsd-exporter
|
||||
[hub]: https://hub.docker.com/r/prom/statsd-exporter/
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
0.26.0
|
||||
0.28.0
|
||||
|
|
|
@ -15,14 +15,15 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
"github.com/prometheus/common/promslog"
|
||||
|
||||
"github.com/prometheus/statsd_exporter/pkg/clock"
|
||||
"github.com/prometheus/statsd_exporter/pkg/event"
|
||||
|
@ -81,6 +82,58 @@ func TestHandlePacket(t *testing.T) {
|
|||
GLabels: map[string]string{},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "gauge increment",
|
||||
in: "foo:+10|g",
|
||||
out: event.Events{
|
||||
&event.GaugeEvent{
|
||||
GMetricName: "foo",
|
||||
GValue: 10,
|
||||
GRelative: true,
|
||||
GLabels: map[string]string{},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "gauge set negative",
|
||||
in: "foo:0|g\nfoo:-1|g",
|
||||
out: event.Events{
|
||||
&event.GaugeEvent{
|
||||
GMetricName: "foo",
|
||||
GValue: 0,
|
||||
GRelative: false,
|
||||
GLabels: map[string]string{},
|
||||
},
|
||||
&event.GaugeEvent{
|
||||
GMetricName: "foo",
|
||||
GValue: -1,
|
||||
GRelative: true,
|
||||
GLabels: map[string]string{},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
// Test the sequence given here https://github.com/statsd/statsd/blob/master/docs/metric_types.md#gauges
|
||||
name: "gauge up and down",
|
||||
in: "gaugor:333|g\ngaugor:-10|g\ngaugor:+4|g",
|
||||
out: event.Events{
|
||||
&event.GaugeEvent{
|
||||
GMetricName: "gaugor",
|
||||
GValue: 333,
|
||||
GRelative: false,
|
||||
GLabels: map[string]string{},
|
||||
},
|
||||
&event.GaugeEvent{
|
||||
GMetricName: "gaugor",
|
||||
GValue: -10,
|
||||
GRelative: true,
|
||||
GLabels: map[string]string{},
|
||||
},
|
||||
&event.GaugeEvent{
|
||||
GMetricName: "gaugor",
|
||||
GValue: 4,
|
||||
GRelative: true,
|
||||
GLabels: map[string]string{},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "simple timer",
|
||||
in: "foo:200|ms",
|
||||
|
@ -540,7 +593,7 @@ func TestHandlePacket(t *testing.T) {
|
|||
for k, l := range []statsDPacketHandler{&listener.StatsDUDPListener{
|
||||
Conn: nil,
|
||||
EventHandler: nil,
|
||||
Logger: log.NewNopLogger(),
|
||||
Logger: promslog.NewNopLogger(),
|
||||
LineParser: parser,
|
||||
UDPPackets: udpPackets,
|
||||
UDPPacketDrops: udpPacketDrops,
|
||||
|
@ -553,7 +606,7 @@ func TestHandlePacket(t *testing.T) {
|
|||
}, &mockStatsDTCPListener{listener.StatsDTCPListener{
|
||||
Conn: nil,
|
||||
EventHandler: nil,
|
||||
Logger: log.NewNopLogger(),
|
||||
Logger: promslog.NewNopLogger(),
|
||||
LineParser: parser,
|
||||
LinesReceived: linesReceived,
|
||||
EventsFlushed: eventsFlushed,
|
||||
|
@ -564,7 +617,7 @@ func TestHandlePacket(t *testing.T) {
|
|||
TCPConnections: tcpConnections,
|
||||
TCPErrors: tcpErrors,
|
||||
TCPLineTooLong: tcpLineTooLong,
|
||||
}, log.NewNopLogger()}} {
|
||||
}, promslog.NewNopLogger()}} {
|
||||
events := make(chan event.Events, 32)
|
||||
l.SetEventHandler(&event.UnbufferedEventHandler{C: events})
|
||||
for i, scenario := range scenarios {
|
||||
|
@ -597,7 +650,7 @@ type statsDPacketHandler interface {
|
|||
|
||||
type mockStatsDTCPListener struct {
|
||||
listener.StatsDTCPListener
|
||||
log.Logger
|
||||
*slog.Logger
|
||||
}
|
||||
|
||||
func (ml *mockStatsDTCPListener) HandlePacket(packet []byte) {
|
||||
|
@ -658,7 +711,7 @@ mappings:
|
|||
events := make(chan event.Events)
|
||||
defer close(events)
|
||||
go func() {
|
||||
ex := exporter.NewExporter(prometheus.DefaultRegisterer, testMapper, log.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex := exporter.NewExporter(prometheus.DefaultRegisterer, testMapper, promslog.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex.Listen(events)
|
||||
}()
|
||||
|
||||
|
|
|
@ -17,9 +17,8 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/common/promslog"
|
||||
|
||||
"github.com/prometheus/statsd_exporter/pkg/event"
|
||||
"github.com/prometheus/statsd_exporter/pkg/exporter"
|
||||
|
@ -43,7 +42,7 @@ func benchmarkUDPListener(times int, b *testing.B) {
|
|||
"some_very_useful_metrics_with_quite_a_log_name:13|c",
|
||||
}
|
||||
bytesInput := make([]string, len(input)*times)
|
||||
logger := log.NewNopLogger()
|
||||
logger := promslog.NewNopLogger()
|
||||
for run := 0; run < times; run++ {
|
||||
for i := 0; i < len(input); i++ {
|
||||
bytesInput[run*len(input)+i] = fmt.Sprintf("run%d%s", run, input[i])
|
||||
|
@ -175,7 +174,7 @@ mappings:
|
|||
b.Fatalf("Config load error: %s %s", config, err)
|
||||
}
|
||||
|
||||
ex := exporter.NewExporter(prometheus.DefaultRegisterer, testMapper, log.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex := exporter.NewExporter(prometheus.DefaultRegisterer, testMapper, promslog.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
|
||||
// reset benchmark timer to not measure startup costs
|
||||
b.ResetTimer()
|
||||
|
|
40
go.mod
40
go.mod
|
@ -1,38 +1,36 @@
|
|||
module github.com/prometheus/statsd_exporter
|
||||
|
||||
go 1.18
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/alecthomas/kingpin/v2 v2.4.0
|
||||
github.com/go-kit/log v0.2.1
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
|
||||
github.com/prometheus/client_golang v1.17.0
|
||||
github.com/prometheus/client_model v0.5.0
|
||||
github.com/prometheus/common v0.45.0
|
||||
github.com/prometheus/exporter-toolkit v0.10.0
|
||||
github.com/prometheus/client_golang v1.20.5
|
||||
github.com/prometheus/client_model v0.6.1
|
||||
github.com/prometheus/common v0.60.1
|
||||
github.com/prometheus/exporter-toolkit v0.13.1
|
||||
github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/jpillora/backoff v1.0.0 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/mdlayher/socket v0.4.1 // indirect
|
||||
github.com/mdlayher/vsock v1.2.1 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
||||
github.com/prometheus/procfs v0.11.1 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
|
||||
golang.org/x/crypto v0.14.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/oauth2 v0.12.0 // indirect
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
golang.org/x/sys v0.13.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
golang.org/x/crypto v0.28.0 // indirect
|
||||
golang.org/x/net v0.29.0 // indirect
|
||||
golang.org/x/oauth2 v0.23.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
golang.org/x/text v0.19.0 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
)
|
||||
|
|
109
go.sum
109
go.sum
|
@ -1,86 +1,85 @@
|
|||
github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY=
|
||||
github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE=
|
||||
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/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrIewtiFmMK5RXHej2XnoXNhxVsAYUfg=
|
||||
github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs=
|
||||
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/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/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.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
|
||||
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
|
||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
|
||||
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
|
||||
github.com/mdlayher/vsock v1.2.1 h1:pC1mTJTvjo1r9n9fbm7S1j04rCgCzhCOS5DY0zqHlnQ=
|
||||
github.com/mdlayher/vsock v1.2.1/go.mod h1:NRfCibel++DgeMD8z/hP+PPTjlNJsdPOmxcnENvE+SE=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
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 v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q=
|
||||
github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY=
|
||||
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
|
||||
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
|
||||
github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM=
|
||||
github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY=
|
||||
github.com/prometheus/exporter-toolkit v0.10.0 h1:yOAzZTi4M22ZzVxD+fhy1URTuNRj/36uQJJ5S8IPza8=
|
||||
github.com/prometheus/exporter-toolkit v0.10.0/go.mod h1:+sVFzuvV5JDyw+Ih6p3zFxZNVnKQa3x5qPmDSiPu4ZY=
|
||||
github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI=
|
||||
github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY=
|
||||
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc=
|
||||
github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw=
|
||||
github.com/prometheus/exporter-toolkit v0.13.1 h1:Evsh0gWQo2bdOHlnz9+0Nm7/OFfIwhE2Ws4A2jIlR04=
|
||||
github.com/prometheus/exporter-toolkit v0.13.1/go.mod h1:ujdv2YIOxtdFxxqtloLpbqmxd5J0Le6IITUvIRSWjj0=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
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/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4=
|
||||
golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4=
|
||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.3.0/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.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
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.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
||||
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
||||
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
@ -16,7 +16,7 @@ package main
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/common/promslog"
|
||||
|
||||
"github.com/prometheus/statsd_exporter/pkg/line"
|
||||
)
|
||||
|
@ -36,7 +36,7 @@ var (
|
|||
"foo15:200|ms:300|ms:5|c|@0.1:6|g\nfoo15a:1|c:5|ms",
|
||||
"some_very_useful_metrics_with_quite_a_log_name:13|c",
|
||||
}
|
||||
nopLogger = log.NewNopLogger()
|
||||
nopLogger = promslog.NewNopLogger()
|
||||
)
|
||||
|
||||
func benchmarkLinesToEvents(times int, b *testing.B, input []string) {
|
||||
|
|
96
main.go
96
main.go
|
@ -16,6 +16,7 @@ package main
|
|||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
|
@ -25,19 +26,18 @@ import (
|
|||
"syscall"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
versioncollector "github.com/prometheus/client_golang/prometheus/collectors/version"
|
||||
"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"
|
||||
"github.com/prometheus/common/promslog"
|
||||
"github.com/prometheus/common/promslog/flag"
|
||||
"github.com/prometheus/common/version"
|
||||
"github.com/prometheus/exporter-toolkit/web"
|
||||
|
||||
"github.com/prometheus/statsd_exporter/pkg/address"
|
||||
"github.com/prometheus/statsd_exporter/pkg/event"
|
||||
"github.com/prometheus/statsd_exporter/pkg/exporter"
|
||||
"github.com/prometheus/statsd_exporter/pkg/level"
|
||||
"github.com/prometheus/statsd_exporter/pkg/line"
|
||||
"github.com/prometheus/statsd_exporter/pkg/listener"
|
||||
"github.com/prometheus/statsd_exporter/pkg/mapper"
|
||||
|
@ -173,49 +173,49 @@ var (
|
|||
)
|
||||
)
|
||||
|
||||
func serveHTTP(mux http.Handler, listenAddress string, logger log.Logger) {
|
||||
level.Error(logger).Log("msg", http.ListenAndServe(listenAddress, mux))
|
||||
func serveHTTP(mux http.Handler, listenAddress string, logger *slog.Logger) {
|
||||
logger.Error(http.ListenAndServe(listenAddress, mux).Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func sighupConfigReloader(fileName string, mapper *mapper.MetricMapper, logger log.Logger) {
|
||||
func sighupConfigReloader(fileName string, mapper *mapper.MetricMapper, logger *slog.Logger) {
|
||||
signals := make(chan os.Signal, 1)
|
||||
signal.Notify(signals, syscall.SIGHUP)
|
||||
|
||||
for s := range signals {
|
||||
if fileName == "" {
|
||||
level.Warn(logger).Log("msg", "Received signal but no mapping config to reload", "signal", s)
|
||||
logger.Warn("Received signal but no mapping config to reload", "signal", s)
|
||||
continue
|
||||
}
|
||||
|
||||
level.Info(logger).Log("msg", "Received signal, attempting reload", "signal", s)
|
||||
logger.Info("Received signal, attempting reload", "signal", s)
|
||||
|
||||
reloadConfig(fileName, mapper, logger)
|
||||
}
|
||||
}
|
||||
|
||||
func reloadConfig(fileName string, mapper *mapper.MetricMapper, logger log.Logger) {
|
||||
func reloadConfig(fileName string, mapper *mapper.MetricMapper, logger *slog.Logger) {
|
||||
err := mapper.InitFromFile(fileName)
|
||||
if err != nil {
|
||||
level.Info(logger).Log("msg", "Error reloading config", "error", err)
|
||||
logger.Info("Error reloading config", "error", err)
|
||||
configLoads.WithLabelValues("failure").Inc()
|
||||
} else {
|
||||
level.Info(logger).Log("msg", "Config reloaded successfully")
|
||||
logger.Info("Config reloaded successfully")
|
||||
configLoads.WithLabelValues("success").Inc()
|
||||
}
|
||||
}
|
||||
|
||||
func dumpFSM(mapper *mapper.MetricMapper, dumpFilename string, logger log.Logger) error {
|
||||
func dumpFSM(mapper *mapper.MetricMapper, dumpFilename string, logger *slog.Logger) error {
|
||||
f, err := os.Create(dumpFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
level.Info(logger).Log("msg", "Start dumping FSM", "file_name", dumpFilename)
|
||||
logger.Info("Start dumping FSM", "file_name", dumpFilename)
|
||||
w := bufio.NewWriter(f)
|
||||
mapper.FSM.DumpFSM(w)
|
||||
w.Flush()
|
||||
f.Close()
|
||||
level.Info(logger).Log("msg", "Finish dumping FSM")
|
||||
logger.Info("Finish dumping FSM")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -270,18 +270,14 @@ func main() {
|
|||
udpPacketQueueSize = kingpin.Flag("statsd.udp-packet-queue-size", "Size of internal queue for processing UDP packets.").Default("10000").Int()
|
||||
)
|
||||
|
||||
promlogConfig := &promlog.Config{}
|
||||
flag.AddFlags(kingpin.CommandLine, promlogConfig)
|
||||
promslogConfig := &promslog.Config{}
|
||||
flag.AddFlags(kingpin.CommandLine, promslogConfig)
|
||||
kingpin.Version(version.Print("statsd_exporter"))
|
||||
kingpin.CommandLine.UsageWriter(os.Stdout)
|
||||
kingpin.HelpFlag.Short('h')
|
||||
kingpin.Parse()
|
||||
logger := promlog.New(promlogConfig)
|
||||
if err := level.SetLogLevel(promlogConfig.Level.String()); err != nil {
|
||||
level.Error(logger).Log("msg", "failed to set log level", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
prometheus.MustRegister(version.NewCollector("statsd_exporter"))
|
||||
logger := promslog.New(promslogConfig)
|
||||
prometheus.MustRegister(versioncollector.NewCollector("statsd_exporter"))
|
||||
|
||||
parser := line.NewParser()
|
||||
if *dogstatsdTagsEnabled {
|
||||
|
@ -297,8 +293,8 @@ func main() {
|
|||
parser.EnableSignalFXParsing()
|
||||
}
|
||||
|
||||
level.Info(logger).Log("msg", "Starting StatsD -> Prometheus Exporter", "version", version.Info())
|
||||
level.Info(logger).Log("msg", "Build context", "context", version.BuildContext())
|
||||
logger.Info("Starting StatsD -> Prometheus Exporter", "version", version.Info())
|
||||
logger.Info("Build context", "context", version.BuildContext())
|
||||
|
||||
events := make(chan event.Events, *eventQueueSize)
|
||||
defer close(events)
|
||||
|
@ -308,7 +304,7 @@ func main() {
|
|||
|
||||
cache, err := getCache(*cacheSize, *cacheType, thisMapper.Registerer)
|
||||
if err != nil {
|
||||
level.Error(logger).Log("msg", "Unable to setup metric mapper cache", "error", err)
|
||||
logger.Error("Unable to setup metric mapper cache", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
thisMapper.UseCache(cache)
|
||||
|
@ -316,13 +312,13 @@ func main() {
|
|||
if *mappingConfig != "" {
|
||||
err := thisMapper.InitFromFile(*mappingConfig)
|
||||
if err != nil {
|
||||
level.Error(logger).Log("msg", "error loading config", "error", err)
|
||||
logger.Error("error loading config", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if *dumpFSMPath != "" {
|
||||
err := dumpFSM(thisMapper, *dumpFSMPath, logger)
|
||||
if err != nil {
|
||||
level.Error(logger).Log("msg", "error dumping FSM", "error", err)
|
||||
logger.Error("error dumping FSM", "error", err)
|
||||
// Failure to dump the FSM is an error (the user asked for it and it
|
||||
// didn't happen) but not fatal (the exporter is fully functional
|
||||
// afterwards).
|
||||
|
@ -333,7 +329,7 @@ func main() {
|
|||
exporter := exporter.NewExporter(prometheus.DefaultRegisterer, thisMapper, logger, eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
|
||||
if *checkConfig {
|
||||
level.Info(logger).Log("msg", "Configuration check successful, exiting")
|
||||
logger.Info("Configuration check successful, exiting")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -342,35 +338,35 @@ func main() {
|
|||
var err error
|
||||
relayTarget, err = relay.NewRelay(logger, *relayAddr, *relayPacketLen)
|
||||
if err != nil {
|
||||
level.Error(logger).Log("msg", "Unable to create relay", "err", err)
|
||||
logger.Error("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)
|
||||
logger.Info("Accepting StatsD Traffic", "udp", *statsdListenUDP, "tcp", *statsdListenTCP, "unixgram", *statsdListenUnixgram)
|
||||
logger.Info("Accepting Prometheus Requests", "addr", *listenAddress)
|
||||
|
||||
if *statsdListenUDP == "" && *statsdListenTCP == "" && *statsdListenUnixgram == "" {
|
||||
level.Error(logger).Log("At least one of UDP/TCP/Unixgram listeners must be specified.")
|
||||
logger.Error("At least one of UDP/TCP/Unixgram listeners must be specified.")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if *statsdListenUDP != "" {
|
||||
udpListenAddr, err := address.UDPAddrFromString(*statsdListenUDP)
|
||||
if err != nil {
|
||||
level.Error(logger).Log("msg", "invalid UDP listen address", "address", *statsdListenUDP, "error", err)
|
||||
logger.Error("invalid UDP listen address", "address", *statsdListenUDP, "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
uconn, err := net.ListenUDP("udp", udpListenAddr)
|
||||
if err != nil {
|
||||
level.Error(logger).Log("msg", "failed to start UDP listener", "error", err)
|
||||
logger.Error("failed to start UDP listener", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if *readBuffer != 0 {
|
||||
err = uconn.SetReadBuffer(*readBuffer)
|
||||
if err != nil {
|
||||
level.Error(logger).Log("msg", "error setting UDP read buffer", "error", err)
|
||||
logger.Error("error setting UDP read buffer", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
@ -400,12 +396,12 @@ func main() {
|
|||
if *statsdListenTCP != "" {
|
||||
tcpListenAddr, err := address.TCPAddrFromString(*statsdListenTCP)
|
||||
if err != nil {
|
||||
level.Error(logger).Log("msg", "invalid TCP listen address", "address", *statsdListenUDP, "error", err)
|
||||
logger.Error("invalid TCP listen address", "address", *statsdListenUDP, "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
tconn, err := net.ListenTCP("tcp", tcpListenAddr)
|
||||
if err != nil {
|
||||
level.Error(logger).Log("msg", err)
|
||||
logger.Error("failed to start TCP listener", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer tconn.Close()
|
||||
|
@ -433,7 +429,7 @@ func main() {
|
|||
if *statsdListenUnixgram != "" {
|
||||
var err error
|
||||
if _, err = os.Stat(*statsdListenUnixgram); !os.IsNotExist(err) {
|
||||
level.Error(logger).Log("msg", "Unixgram socket already exists", "socket_name", *statsdListenUnixgram)
|
||||
logger.Error("Unixgram socket already exists", "socket_name", *statsdListenUnixgram)
|
||||
os.Exit(1)
|
||||
}
|
||||
uxgconn, err := net.ListenUnixgram("unixgram", &net.UnixAddr{
|
||||
|
@ -441,7 +437,7 @@ func main() {
|
|||
Name: *statsdListenUnixgram,
|
||||
})
|
||||
if err != nil {
|
||||
level.Error(logger).Log("msg", "failed to listen on Unixgram socket", "error", err)
|
||||
logger.Error("failed to listen on Unixgram socket", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
@ -450,7 +446,7 @@ func main() {
|
|||
if *readBuffer != 0 {
|
||||
err = uxgconn.SetReadBuffer(*readBuffer)
|
||||
if err != nil {
|
||||
level.Error(logger).Log("msg", "error setting Unixgram read buffer", "error", err)
|
||||
logger.Error("error setting Unixgram read buffer", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
@ -480,11 +476,11 @@ func main() {
|
|||
// convert the string to octet
|
||||
perm, err := strconv.ParseInt("0"+string(*statsdUnixSocketMode), 8, 32)
|
||||
if err != nil {
|
||||
level.Warn(logger).Log("Bad permission %s: %v, ignoring\n", *statsdUnixSocketMode, err)
|
||||
logger.Warn("Bad permission %s: %v, ignoring\n", *statsdUnixSocketMode, err)
|
||||
} else {
|
||||
err = os.Chmod(*statsdListenUnixgram, os.FileMode(perm))
|
||||
if err != nil {
|
||||
level.Warn(logger).Log("Failed to change unixgram socket permission: %v", err)
|
||||
logger.Warn("Failed to change unixgram socket permission", "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -506,7 +502,7 @@ func main() {
|
|||
}
|
||||
landingPage, err := web.NewLandingPage(landingConfig)
|
||||
if err != nil {
|
||||
level.Error(logger).Log("err", err)
|
||||
logger.Error("error creating landing page", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
mux.Handle("/", landingPage)
|
||||
|
@ -519,10 +515,10 @@ func main() {
|
|||
if r.Method == http.MethodPut || r.Method == http.MethodPost {
|
||||
fmt.Fprintf(w, "Requesting reload")
|
||||
if *mappingConfig == "" {
|
||||
level.Warn(logger).Log("msg", "Received lifecycle api reload but no mapping config to reload")
|
||||
logger.Warn("Received lifecycle api reload but no mapping config to reload")
|
||||
return
|
||||
}
|
||||
level.Info(logger).Log("msg", "Received lifecycle api reload, attempting reload")
|
||||
logger.Info("Received lifecycle api reload, attempting reload")
|
||||
reloadConfig(*mappingConfig, thisMapper, logger)
|
||||
}
|
||||
})
|
||||
|
@ -536,7 +532,7 @@ func main() {
|
|||
|
||||
mux.HandleFunc("/-/healthy", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == http.MethodGet {
|
||||
level.Debug(logger).Log("msg", "Received health check")
|
||||
logger.Debug("Received health check")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Fprintf(w, "Statsd Exporter is Healthy.\n")
|
||||
}
|
||||
|
@ -544,7 +540,7 @@ func main() {
|
|||
|
||||
mux.HandleFunc("/-/ready", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == http.MethodGet {
|
||||
level.Debug(logger).Log("msg", "Received ready check")
|
||||
logger.Debug("Received ready check")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Fprintf(w, "Statsd Exporter is Ready.\n")
|
||||
}
|
||||
|
@ -561,8 +557,8 @@ func main() {
|
|||
// quit if we get a message on either channel
|
||||
select {
|
||||
case sig := <-signals:
|
||||
level.Info(logger).Log("msg", "Received os signal, exiting", "signal", sig.String())
|
||||
logger.Info("Received os signal, exiting", "signal", sig.String())
|
||||
case <-quitChan:
|
||||
level.Info(logger).Log("msg", "Received lifecycle api quit, exiting")
|
||||
logger.Info("Received lifecycle api quit, exiting")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,15 +14,14 @@
|
|||
package exporter
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/prometheus/statsd_exporter/pkg/clock"
|
||||
"github.com/prometheus/statsd_exporter/pkg/event"
|
||||
"github.com/prometheus/statsd_exporter/pkg/level"
|
||||
"github.com/prometheus/statsd_exporter/pkg/mapper"
|
||||
"github.com/prometheus/statsd_exporter/pkg/registry"
|
||||
)
|
||||
|
@ -43,7 +42,7 @@ type Registry interface {
|
|||
type Exporter struct {
|
||||
Mapper *mapper.MetricMapper
|
||||
Registry Registry
|
||||
Logger log.Logger
|
||||
Logger *slog.Logger
|
||||
EventsActions *prometheus.CounterVec
|
||||
EventsUnmapped prometheus.Counter
|
||||
ErrorEventStats *prometheus.CounterVec
|
||||
|
@ -63,7 +62,7 @@ func (b *Exporter) Listen(e <-chan event.Events) {
|
|||
b.Registry.RemoveStaleMetrics()
|
||||
case events, ok := <-e:
|
||||
if !ok {
|
||||
level.Debug(b.Logger).Log("msg", "Channel is closed. Break out of Exporter.Listener.")
|
||||
b.Logger.Debug("Channel is closed. Break out of Exporter.Listener.")
|
||||
removeStaleMetricsTicker.Stop()
|
||||
return
|
||||
}
|
||||
|
@ -99,7 +98,7 @@ func (b *Exporter) handleEvent(thisEvent event.Event) {
|
|||
prometheusLabels := thisEvent.Labels()
|
||||
if present {
|
||||
if mapping.Name == "" {
|
||||
level.Debug(b.Logger).Log("msg", "The mapping generates an empty metric name", "metric_name", thisEvent.MetricName(), "match", mapping.Match)
|
||||
b.Logger.Debug("The mapping generates an empty metric name", "metric_name", thisEvent.MetricName(), "match", mapping.Match)
|
||||
b.ErrorEventStats.WithLabelValues("empty_metric_name").Inc()
|
||||
return
|
||||
}
|
||||
|
@ -127,7 +126,7 @@ func (b *Exporter) handleEvent(thisEvent event.Event) {
|
|||
// We don't accept negative values for counters. Incrementing the counter with a negative number
|
||||
// will cause the exporter to panic. Instead we will warn and continue to the next event.
|
||||
if eventValue < 0.0 {
|
||||
level.Debug(b.Logger).Log("msg", "counter must be non-negative value", "metric", metricName, "event_value", eventValue)
|
||||
b.Logger.Debug("counter must be non-negative value", "metric", metricName, "event_value", eventValue)
|
||||
b.ErrorEventStats.WithLabelValues("illegal_negative_counter").Inc()
|
||||
return
|
||||
}
|
||||
|
@ -137,7 +136,7 @@ func (b *Exporter) handleEvent(thisEvent event.Event) {
|
|||
counter.Add(eventValue)
|
||||
b.EventStats.WithLabelValues("counter").Inc()
|
||||
} else {
|
||||
level.Debug(b.Logger).Log("msg", regErrF, "metric", metricName, "error", err)
|
||||
b.Logger.Debug(regErrF, "metric", metricName, "error", err)
|
||||
b.ConflictingEventStats.WithLabelValues("counter").Inc()
|
||||
}
|
||||
|
||||
|
@ -152,7 +151,7 @@ func (b *Exporter) handleEvent(thisEvent event.Event) {
|
|||
}
|
||||
b.EventStats.WithLabelValues("gauge").Inc()
|
||||
} else {
|
||||
level.Debug(b.Logger).Log("msg", regErrF, "metric", metricName, "error", err)
|
||||
b.Logger.Debug(regErrF, "metric", metricName, "error", err)
|
||||
b.ConflictingEventStats.WithLabelValues("gauge").Inc()
|
||||
}
|
||||
|
||||
|
@ -172,7 +171,7 @@ func (b *Exporter) handleEvent(thisEvent event.Event) {
|
|||
histogram.Observe(eventValue)
|
||||
b.EventStats.WithLabelValues("observer").Inc()
|
||||
} else {
|
||||
level.Debug(b.Logger).Log("msg", regErrF, "metric", metricName, "error", err)
|
||||
b.Logger.Debug(regErrF, "metric", metricName, "error", err)
|
||||
b.ConflictingEventStats.WithLabelValues("observer").Inc()
|
||||
}
|
||||
|
||||
|
@ -182,22 +181,22 @@ func (b *Exporter) handleEvent(thisEvent event.Event) {
|
|||
summary.Observe(eventValue)
|
||||
b.EventStats.WithLabelValues("observer").Inc()
|
||||
} else {
|
||||
level.Debug(b.Logger).Log("msg", regErrF, "metric", metricName, "error", err)
|
||||
b.Logger.Debug(regErrF, "metric", metricName, "error", err)
|
||||
b.ConflictingEventStats.WithLabelValues("observer").Inc()
|
||||
}
|
||||
|
||||
default:
|
||||
level.Error(b.Logger).Log("msg", "unknown observer type", "type", t)
|
||||
b.Logger.Error("unknown observer type", "type", t)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
default:
|
||||
level.Debug(b.Logger).Log("msg", "Unsupported event type")
|
||||
b.Logger.Debug("Unsupported event type")
|
||||
b.EventStats.WithLabelValues("illegal").Inc()
|
||||
}
|
||||
}
|
||||
|
||||
func NewExporter(reg prometheus.Registerer, mapper *mapper.MetricMapper, logger log.Logger, eventsActions *prometheus.CounterVec, eventsUnmapped prometheus.Counter, errorEventStats *prometheus.CounterVec, eventStats *prometheus.CounterVec, conflictingEventStats *prometheus.CounterVec, metricsCount *prometheus.GaugeVec) *Exporter {
|
||||
func NewExporter(reg prometheus.Registerer, mapper *mapper.MetricMapper, logger *slog.Logger, eventsActions *prometheus.CounterVec, eventsUnmapped prometheus.Counter, errorEventStats *prometheus.CounterVec, eventStats *prometheus.CounterVec, conflictingEventStats *prometheus.CounterVec, metricsCount *prometheus.GaugeVec) *Exporter {
|
||||
return &Exporter{
|
||||
Mapper: mapper,
|
||||
Registry: registry.NewRegistry(reg, mapper),
|
||||
|
|
|
@ -15,13 +15,14 @@ package exporter
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
"github.com/prometheus/common/promslog"
|
||||
|
||||
"github.com/prometheus/statsd_exporter/pkg/clock"
|
||||
"github.com/prometheus/statsd_exporter/pkg/event"
|
||||
|
@ -172,7 +173,7 @@ func TestNegativeCounter(t *testing.T) {
|
|||
|
||||
testMapper := mapper.MetricMapper{}
|
||||
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, &testMapper, log.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, &testMapper, promslog.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex.Listen(events)
|
||||
|
||||
updated := getTelemetryCounterValue(errorCounter)
|
||||
|
@ -253,7 +254,7 @@ mappings:
|
|||
t.Fatalf("Config load error: %s %s", config, err)
|
||||
}
|
||||
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, testMapper, log.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, testMapper, promslog.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex.Listen(events)
|
||||
|
||||
metrics, err := prometheus.DefaultGatherer.Gather()
|
||||
|
@ -316,7 +317,7 @@ mappings:
|
|||
t.Fatalf("Config load error: %s %s", config, err)
|
||||
}
|
||||
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, testMapper, log.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, testMapper, promslog.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex.Listen(events)
|
||||
|
||||
metrics, err := prometheus.DefaultGatherer.Gather()
|
||||
|
@ -359,14 +360,14 @@ mappings:
|
|||
honor_labels: true
|
||||
`
|
||||
testMapper := &mapper.MetricMapper{
|
||||
Logger: log.NewNopLogger(),
|
||||
Logger: promslog.NewNopLogger(),
|
||||
}
|
||||
err := testMapper.InitFromYAMLString(config)
|
||||
if err != nil {
|
||||
t.Fatalf("Config load error: %s %s", config, err)
|
||||
}
|
||||
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, testMapper, log.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, testMapper, promslog.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex.Listen(events)
|
||||
|
||||
metrics, err := prometheus.DefaultGatherer.Gather()
|
||||
|
@ -647,7 +648,7 @@ mappings:
|
|||
close(events)
|
||||
}()
|
||||
reg := prometheus.NewRegistry()
|
||||
ex := NewExporter(reg, testMapper, log.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex := NewExporter(reg, testMapper, promslog.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex.Listen(events)
|
||||
|
||||
metrics, err := reg.Gather()
|
||||
|
@ -702,7 +703,7 @@ mappings:
|
|||
errorCounter := errorEventStats.WithLabelValues("empty_metric_name")
|
||||
prev := getTelemetryCounterValue(errorCounter)
|
||||
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, testMapper, log.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, testMapper, promslog.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex.Listen(events)
|
||||
|
||||
updated := getTelemetryCounterValue(errorCounter)
|
||||
|
@ -736,7 +737,7 @@ func TestInvalidUtf8InDatadogTagValue(t *testing.T) {
|
|||
for _, l := range []statsDPacketHandler{&listener.StatsDUDPListener{
|
||||
Conn: nil,
|
||||
EventHandler: nil,
|
||||
Logger: log.NewNopLogger(),
|
||||
Logger: promslog.NewNopLogger(),
|
||||
LineParser: parser,
|
||||
UDPPackets: udpPackets,
|
||||
UDPPacketDrops: udpPacketDrops,
|
||||
|
@ -749,7 +750,7 @@ func TestInvalidUtf8InDatadogTagValue(t *testing.T) {
|
|||
}, &mockStatsDTCPListener{listener.StatsDTCPListener{
|
||||
Conn: nil,
|
||||
EventHandler: nil,
|
||||
Logger: log.NewNopLogger(),
|
||||
Logger: promslog.NewNopLogger(),
|
||||
LineParser: parser,
|
||||
LinesReceived: linesReceived,
|
||||
EventsFlushed: eventsFlushed,
|
||||
|
@ -760,7 +761,7 @@ func TestInvalidUtf8InDatadogTagValue(t *testing.T) {
|
|||
TCPConnections: tcpConnections,
|
||||
TCPErrors: tcpErrors,
|
||||
TCPLineTooLong: tcpLineTooLong,
|
||||
}, log.NewNopLogger()}} {
|
||||
}, promslog.NewNopLogger()}} {
|
||||
l.SetEventHandler(ueh)
|
||||
l.HandlePacket([]byte("bar:200|c|#tag:value\nbar:200|c|#tag:\xc3\x28invalid"))
|
||||
}
|
||||
|
@ -769,7 +770,7 @@ func TestInvalidUtf8InDatadogTagValue(t *testing.T) {
|
|||
|
||||
testMapper := mapper.MetricMapper{}
|
||||
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, &testMapper, log.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, &testMapper, promslog.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex.Listen(events)
|
||||
}
|
||||
|
||||
|
@ -782,7 +783,7 @@ func TestSummaryWithQuantilesEmptyMapping(t *testing.T) {
|
|||
go func() {
|
||||
testMapper := mapper.MetricMapper{}
|
||||
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, &testMapper, log.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, &testMapper, promslog.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex.Listen(events)
|
||||
}()
|
||||
|
||||
|
@ -825,7 +826,7 @@ func TestHistogramUnits(t *testing.T) {
|
|||
events := make(chan event.Events)
|
||||
go func() {
|
||||
testMapper := mapper.MetricMapper{}
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, &testMapper, log.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, &testMapper, promslog.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex.Mapper.Defaults.ObserverType = mapper.ObserverTypeHistogram
|
||||
ex.Listen(events)
|
||||
}()
|
||||
|
@ -861,7 +862,7 @@ func TestCounterIncrement(t *testing.T) {
|
|||
events := make(chan event.Events)
|
||||
go func() {
|
||||
testMapper := mapper.MetricMapper{}
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, &testMapper, log.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, &testMapper, promslog.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex.Listen(events)
|
||||
}()
|
||||
|
||||
|
@ -902,6 +903,58 @@ func TestCounterIncrement(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Test case from https://github.com/statsd/statsd/blob/master/docs/metric_types.md#gauges
|
||||
func TestGaugeIncrementDecrement(t *testing.T) {
|
||||
// Start exporter with a synchronous channel
|
||||
events := make(chan event.Events)
|
||||
go func() {
|
||||
testMapper := mapper.MetricMapper{}
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, &testMapper, promslog.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex.Listen(events)
|
||||
}()
|
||||
|
||||
// Synchronously send a statsd event to wait for handleEvent execution.
|
||||
// Then close events channel to stop a listener.
|
||||
name := "gaugor"
|
||||
c := event.Events{
|
||||
&event.GaugeEvent{
|
||||
GMetricName: "gaugor",
|
||||
GValue: 333,
|
||||
GRelative: false,
|
||||
GLabels: map[string]string{},
|
||||
},
|
||||
&event.GaugeEvent{
|
||||
GMetricName: "gaugor",
|
||||
GValue: -10,
|
||||
GRelative: true,
|
||||
GLabels: map[string]string{},
|
||||
},
|
||||
&event.GaugeEvent{
|
||||
GMetricName: "gaugor",
|
||||
GValue: 4,
|
||||
GRelative: true,
|
||||
GLabels: map[string]string{},
|
||||
},
|
||||
}
|
||||
events <- c
|
||||
// Push empty event so that we block until the first event is consumed.
|
||||
events <- event.Events{}
|
||||
close(events)
|
||||
|
||||
// Check histogram value
|
||||
metrics, err := prometheus.DefaultGatherer.Gather()
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot gather from DefaultGatherer: %v", err)
|
||||
}
|
||||
value := getFloat64(metrics, name, nil)
|
||||
if value == nil {
|
||||
t.Fatal("gauge value should not be nil")
|
||||
}
|
||||
if *value != 327 {
|
||||
t.Fatalf("gauge wasn't incremented and decremented properly")
|
||||
}
|
||||
}
|
||||
|
||||
func TestScaledMapping(t *testing.T) {
|
||||
events := make(chan event.Events)
|
||||
testMapper := mapper.MetricMapper{}
|
||||
|
@ -918,7 +971,7 @@ func TestScaledMapping(t *testing.T) {
|
|||
|
||||
// Start exporter with a synchronous channel
|
||||
go func() {
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, &testMapper, log.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, &testMapper, promslog.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex.Listen(events)
|
||||
}()
|
||||
|
||||
|
@ -966,7 +1019,7 @@ type statsDPacketHandler interface {
|
|||
|
||||
type mockStatsDTCPListener struct {
|
||||
listener.StatsDTCPListener
|
||||
log.Logger
|
||||
*slog.Logger
|
||||
}
|
||||
|
||||
func (ml *mockStatsDTCPListener) HandlePacket(packet []byte) {
|
||||
|
@ -1027,7 +1080,7 @@ mappings:
|
|||
events := make(chan event.Events)
|
||||
defer close(events)
|
||||
go func() {
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, testMapper, log.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex := NewExporter(prometheus.DefaultRegisterer, testMapper, promslog.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||
ex.Listen(events)
|
||||
}()
|
||||
|
||||
|
@ -1239,7 +1292,7 @@ func BenchmarkParseDogStatsDTags(b *testing.B) {
|
|||
b.Run(name, func(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
labels := map[string]string{}
|
||||
parser.ParseDogStatsDTags(tags, labels, tagErrors, log.NewNopLogger())
|
||||
parser.ParseDogStatsDTags(tags, labels, tagErrors, promslog.NewNopLogger())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,97 +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 level
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
)
|
||||
|
||||
var logLevel = LevelInfo
|
||||
|
||||
// A Level is a logging priority. Higher levels are more important.
|
||||
type Level int
|
||||
|
||||
const (
|
||||
// LevelDebug logs are typically voluminous, and are usually disabled in
|
||||
// production.
|
||||
LevelDebug Level = iota
|
||||
// LevelInfo is the default logging priority.
|
||||
LevelInfo
|
||||
// LevelWarn logs are more important than Info, but don't need individual
|
||||
// human review.
|
||||
LevelWarn
|
||||
// LevelError logs are high-priority. If an application is running smoothly,
|
||||
// it shouldn't generate any error-level logs.
|
||||
LevelError
|
||||
)
|
||||
|
||||
var emptyLogger = &EmptyLogger{}
|
||||
|
||||
type EmptyLogger struct{}
|
||||
|
||||
func (l *EmptyLogger) Log(keyvals ...interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetLogLevel sets the log level.
|
||||
func SetLogLevel(level string) error {
|
||||
switch level {
|
||||
case "debug":
|
||||
logLevel = LevelDebug
|
||||
case "info":
|
||||
logLevel = LevelInfo
|
||||
case "warn":
|
||||
logLevel = LevelWarn
|
||||
case "error":
|
||||
logLevel = LevelError
|
||||
default:
|
||||
return fmt.Errorf("unrecognized log level %s", level)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Error returns a logger that includes a Key/ErrorValue pair.
|
||||
func Error(logger log.Logger) log.Logger {
|
||||
if logLevel <= LevelError {
|
||||
return level.Error(logger)
|
||||
}
|
||||
return emptyLogger
|
||||
}
|
||||
|
||||
// Warn returns a logger that includes a Key/WarnValue pair.
|
||||
func Warn(logger log.Logger) log.Logger {
|
||||
if logLevel <= LevelWarn {
|
||||
return level.Warn(logger)
|
||||
}
|
||||
return emptyLogger
|
||||
}
|
||||
|
||||
// Info returns a logger that includes a Key/InfoValue pair.
|
||||
func Info(logger log.Logger) log.Logger {
|
||||
if logLevel <= LevelInfo {
|
||||
return level.Info(logger)
|
||||
}
|
||||
return emptyLogger
|
||||
}
|
||||
|
||||
// Debug returns a logger that includes a Key/DebugValue pair.
|
||||
func Debug(logger log.Logger) log.Logger {
|
||||
if logLevel <= LevelDebug {
|
||||
return level.Debug(logger)
|
||||
}
|
||||
return emptyLogger
|
||||
}
|
|
@ -1,110 +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 level
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
)
|
||||
|
||||
func TestSetLogLevel(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
level string
|
||||
logLevel Level
|
||||
wantErr bool
|
||||
}{
|
||||
{"wrong level", "foo", LevelInfo, true},
|
||||
{"level debug", "debug", LevelDebug, false},
|
||||
{"level info", "info", LevelInfo, false},
|
||||
{"level warn", "warn", LevelWarn, false},
|
||||
{"level error", "error", LevelError, false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if err := SetLogLevel(tt.level); (err != nil) != tt.wantErr {
|
||||
t.Fatalf("Expected log level to be set successfully, but got %v", err)
|
||||
}
|
||||
if tt.logLevel != logLevel {
|
||||
t.Fatalf("Expected log level %v, but got %v", tt.logLevel, logLevel)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestVariousLevels(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
level string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
"level debug",
|
||||
"debug",
|
||||
strings.Join([]string{
|
||||
"level=debug log=debug",
|
||||
"level=info log=info",
|
||||
"level=warn log=warn",
|
||||
"level=error log=error",
|
||||
}, "\n"),
|
||||
},
|
||||
{
|
||||
"level info",
|
||||
"info",
|
||||
strings.Join([]string{
|
||||
"level=info log=info",
|
||||
"level=warn log=warn",
|
||||
"level=error log=error",
|
||||
}, "\n"),
|
||||
},
|
||||
{
|
||||
"level warn",
|
||||
"warn",
|
||||
strings.Join([]string{
|
||||
"level=warn log=warn",
|
||||
"level=error log=error",
|
||||
}, "\n"),
|
||||
},
|
||||
{
|
||||
"level error",
|
||||
"error",
|
||||
strings.Join([]string{
|
||||
"level=error log=error",
|
||||
}, "\n"),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
logger := log.NewLogfmtLogger(&buf)
|
||||
|
||||
if err := SetLogLevel(tt.level); err != nil {
|
||||
t.Fatalf("Expected log level to be set successfully, but got %v", err)
|
||||
}
|
||||
|
||||
Debug(logger).Log("log", "debug")
|
||||
Info(logger).Log("log", "info")
|
||||
Warn(logger).Log("log", "warn")
|
||||
Error(logger).Log("log", "error")
|
||||
|
||||
got := strings.TrimSpace(buf.String())
|
||||
if tt.want != got {
|
||||
t.Fatalf("Expected log output %v, but got %v", tt.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -15,15 +15,14 @@ package line
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/prometheus/statsd_exporter/pkg/event"
|
||||
"github.com/prometheus/statsd_exporter/pkg/level"
|
||||
"github.com/prometheus/statsd_exporter/pkg/mapper"
|
||||
)
|
||||
|
||||
|
@ -95,11 +94,11 @@ func buildEvent(statType, metric string, value float64, relative bool, labels ma
|
|||
}
|
||||
}
|
||||
|
||||
func parseTag(component, tag string, separator rune, labels map[string]string, tagErrors prometheus.Counter, logger log.Logger) {
|
||||
func parseTag(component, tag string, separator rune, labels map[string]string, tagErrors prometheus.Counter, logger *slog.Logger) {
|
||||
// Entirely empty tag is an error
|
||||
if len(tag) == 0 {
|
||||
tagErrors.Inc()
|
||||
level.Debug(logger).Log("msg", "Empty name tag", "component", component)
|
||||
logger.Debug("Empty name tag", "component", component)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -111,7 +110,7 @@ func parseTag(component, tag string, separator rune, labels map[string]string, t
|
|||
if len(k) == 0 || len(v) == 0 {
|
||||
// Empty key or value is an error
|
||||
tagErrors.Inc()
|
||||
level.Debug(logger).Log("msg", "Malformed name tag", "k", k, "v", v, "component", component)
|
||||
logger.Debug("Malformed name tag", "k", k, "v", v, "component", component)
|
||||
} else {
|
||||
labels[mapper.EscapeMetricName(k)] = v
|
||||
}
|
||||
|
@ -121,10 +120,10 @@ func parseTag(component, tag string, separator rune, labels map[string]string, t
|
|||
|
||||
// Missing separator (no value) is an error
|
||||
tagErrors.Inc()
|
||||
level.Debug(logger).Log("msg", "Malformed name tag", "tag", tag, "component", component)
|
||||
logger.Debug("Malformed name tag", "tag", tag, "component", component)
|
||||
}
|
||||
|
||||
func parseNameTags(component string, labels map[string]string, tagErrors prometheus.Counter, logger log.Logger) {
|
||||
func parseNameTags(component string, labels map[string]string, tagErrors prometheus.Counter, logger *slog.Logger) {
|
||||
lastTagEndIndex := 0
|
||||
for i, c := range component {
|
||||
if c == ',' {
|
||||
|
@ -148,7 +147,7 @@ func trimLeftHash(s string) string {
|
|||
return s
|
||||
}
|
||||
|
||||
func (p *Parser) ParseDogStatsDTags(component string, labels map[string]string, tagErrors prometheus.Counter, logger log.Logger) {
|
||||
func (p *Parser) ParseDogStatsDTags(component string, labels map[string]string, tagErrors prometheus.Counter, logger *slog.Logger) {
|
||||
if p.DogstatsdTagsEnabled {
|
||||
lastTagEndIndex := 0
|
||||
for i, c := range component {
|
||||
|
@ -167,7 +166,7 @@ func (p *Parser) ParseDogStatsDTags(component string, labels map[string]string,
|
|||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseNameAndTags(name string, labels map[string]string, tagErrors prometheus.Counter, logger log.Logger) string {
|
||||
func (p *Parser) parseNameAndTags(name string, labels map[string]string, tagErrors prometheus.Counter, logger *slog.Logger) string {
|
||||
if p.SignalFXTagsEnabled {
|
||||
// check for SignalFx tags first
|
||||
// `[` delimits start of tags by SignalFx
|
||||
|
@ -183,7 +182,7 @@ func (p *Parser) parseNameAndTags(name string, labels map[string]string, tagErro
|
|||
return name[:startIdx] + name[endIdx+1:]
|
||||
case (startIdx != -1) != (endIdx != -1):
|
||||
// only one bracket, return unparsed
|
||||
level.Debug(logger).Log("msg", "invalid SignalFx tags, not parsing", "metric", name)
|
||||
logger.Debug("invalid SignalFx tags, not parsing", "metric", name)
|
||||
tagErrors.Inc()
|
||||
return name
|
||||
}
|
||||
|
@ -202,7 +201,7 @@ func (p *Parser) parseNameAndTags(name string, labels map[string]string, tagErro
|
|||
return name
|
||||
}
|
||||
|
||||
func (p *Parser) LineToEvents(line string, sampleErrors prometheus.CounterVec, samplesReceived prometheus.Counter, tagErrors prometheus.Counter, tagsReceived prometheus.Counter, logger log.Logger) event.Events {
|
||||
func (p *Parser) LineToEvents(line string, sampleErrors prometheus.CounterVec, samplesReceived prometheus.Counter, tagErrors prometheus.Counter, tagsReceived prometheus.Counter, logger *slog.Logger) event.Events {
|
||||
events := event.Events{}
|
||||
if line == "" {
|
||||
return events
|
||||
|
@ -211,24 +210,55 @@ func (p *Parser) LineToEvents(line string, sampleErrors prometheus.CounterVec, s
|
|||
elements := strings.SplitN(line, ":", 2)
|
||||
if len(elements) < 2 || len(elements[0]) == 0 || !utf8.ValidString(line) {
|
||||
sampleErrors.WithLabelValues("malformed_line").Inc()
|
||||
level.Debug(logger).Log("msg", "Bad line from StatsD", "line", line)
|
||||
logger.Debug("bad line", "line", line)
|
||||
return events
|
||||
}
|
||||
|
||||
labels := map[string]string{}
|
||||
metric := p.parseNameAndTags(elements[0], labels, tagErrors, logger)
|
||||
|
||||
var samples []string
|
||||
if strings.Contains(elements[1], "|#") {
|
||||
usingDogStatsDTags := strings.Contains(elements[1], "|#")
|
||||
if usingDogStatsDTags && len(labels) > 0 {
|
||||
// using DogStatsD tags
|
||||
|
||||
// don't allow mixed tagging styles
|
||||
if len(labels) > 0 {
|
||||
sampleErrors.WithLabelValues("mixed_tagging_styles").Inc()
|
||||
level.Debug(logger).Log("msg", "Bad line (multiple tagging styles) from StatsD", "line", line)
|
||||
logger.Debug("bad line: multiple tagging styles", "line", line)
|
||||
return events
|
||||
}
|
||||
|
||||
var samples []string
|
||||
lineParts := strings.SplitN(elements[1], "|", 3)
|
||||
if len(lineParts) < 2 {
|
||||
sampleErrors.WithLabelValues("not_enough_parts_after_colon").Inc()
|
||||
logger.Debug("bad line: not enough '|'-delimited parts after first ':'", "line", line)
|
||||
return events
|
||||
}
|
||||
if strings.Contains(lineParts[0], ":") {
|
||||
// handle DogStatsD extended aggregation
|
||||
isValidAggType := false
|
||||
switch lineParts[1] {
|
||||
case
|
||||
"ms", // timer
|
||||
"h", // histogram
|
||||
"d": // distribution
|
||||
isValidAggType = true
|
||||
}
|
||||
|
||||
if isValidAggType {
|
||||
aggValues := strings.Split(lineParts[0], ":")
|
||||
aggLines := make([]string, len(aggValues))
|
||||
_, aggLineSuffix, _ := strings.Cut(elements[1], "|")
|
||||
|
||||
for i, aggValue := range aggValues {
|
||||
aggLines[i] = strings.Join([]string{aggValue, aggLineSuffix}, "|")
|
||||
}
|
||||
samples = aggLines
|
||||
} else {
|
||||
sampleErrors.WithLabelValues("invalid_extended_aggregate_type").Inc()
|
||||
logger.Debug("bad line: invalid extended aggregate type", "line", line)
|
||||
return events
|
||||
}
|
||||
} else if usingDogStatsDTags {
|
||||
// disable multi-metrics
|
||||
samples = elements[1:]
|
||||
} else {
|
||||
|
@ -241,7 +271,7 @@ samples:
|
|||
components := strings.Split(sample, "|")
|
||||
if len(components) < 2 || len(components) > 4 {
|
||||
sampleErrors.WithLabelValues("malformed_component").Inc()
|
||||
level.Debug(logger).Log("msg", "Bad component", "line", line)
|
||||
logger.Debug("bad component", "line", line)
|
||||
continue
|
||||
}
|
||||
valueStr, statType := components[0], components[1]
|
||||
|
@ -253,7 +283,7 @@ samples:
|
|||
|
||||
value, err := strconv.ParseFloat(valueStr, 64)
|
||||
if err != nil {
|
||||
level.Debug(logger).Log("msg", "Bad value", "value", valueStr, "line", line)
|
||||
logger.Debug("bad value", "value", valueStr, "line", line)
|
||||
sampleErrors.WithLabelValues("malformed_value").Inc()
|
||||
continue
|
||||
}
|
||||
|
@ -262,7 +292,7 @@ samples:
|
|||
if len(components) >= 3 {
|
||||
for _, component := range components[2:] {
|
||||
if len(component) == 0 {
|
||||
level.Debug(logger).Log("msg", "Empty component", "line", line)
|
||||
logger.Debug("Empty component", "line", line)
|
||||
sampleErrors.WithLabelValues("malformed_component").Inc()
|
||||
continue samples
|
||||
}
|
||||
|
@ -274,7 +304,7 @@ samples:
|
|||
|
||||
samplingFactor, err := strconv.ParseFloat(component[1:], 64)
|
||||
if err != nil {
|
||||
level.Debug(logger).Log("msg", "Invalid sampling factor", "component", component[1:], "line", line)
|
||||
logger.Debug("Invalid sampling factor", "component", component[1:], "line", line)
|
||||
sampleErrors.WithLabelValues("invalid_sample_factor").Inc()
|
||||
}
|
||||
if samplingFactor == 0 {
|
||||
|
@ -291,7 +321,7 @@ samples:
|
|||
case '#':
|
||||
p.ParseDogStatsDTags(component[1:], labels, tagErrors, logger)
|
||||
default:
|
||||
level.Debug(logger).Log("msg", "Invalid sampling factor or tag section", "component", components[2], "line", line)
|
||||
logger.Debug("Invalid sampling factor or tag section", "component", components[2], "line", line)
|
||||
sampleErrors.WithLabelValues("invalid_sample_factor").Inc()
|
||||
continue
|
||||
}
|
||||
|
@ -305,7 +335,7 @@ samples:
|
|||
for i := 0; i < multiplyEvents; i++ {
|
||||
event, err := buildEvent(statType, metric, value, relative, labels)
|
||||
if err != nil {
|
||||
level.Debug(logger).Log("msg", "Error building event", "line", line, "error", err)
|
||||
logger.Debug("Error building event", "line", line, "error", err)
|
||||
sampleErrors.WithLabelValues("illegal_event").Inc()
|
||||
continue
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,26 +16,25 @@ package listener
|
|||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/prometheus/statsd_exporter/pkg/event"
|
||||
"github.com/prometheus/statsd_exporter/pkg/level"
|
||||
"github.com/prometheus/statsd_exporter/pkg/relay"
|
||||
)
|
||||
|
||||
type Parser interface {
|
||||
LineToEvents(line string, sampleErrors prometheus.CounterVec, samplesReceived prometheus.Counter, tagErrors prometheus.Counter, tagsReceived prometheus.Counter, logger log.Logger) event.Events
|
||||
LineToEvents(line string, sampleErrors prometheus.CounterVec, samplesReceived prometheus.Counter, tagErrors prometheus.Counter, tagsReceived prometheus.Counter, logger *slog.Logger) event.Events
|
||||
}
|
||||
|
||||
type StatsDUDPListener struct {
|
||||
Conn *net.UDPConn
|
||||
EventHandler event.EventHandler
|
||||
Logger log.Logger
|
||||
Logger *slog.Logger
|
||||
LineParser Parser
|
||||
UDPPackets prometheus.Counter
|
||||
UDPPacketDrops prometheus.Counter
|
||||
|
@ -64,7 +63,7 @@ func (l *StatsDUDPListener) Listen() {
|
|||
if strings.HasSuffix(err.Error(), "use of closed network connection") {
|
||||
return
|
||||
}
|
||||
level.Error(l.Logger).Log("error", err)
|
||||
l.Logger.Error("error reading from UDP connection", "err", err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -94,7 +93,7 @@ func (l *StatsDUDPListener) ProcessUdpPacketQueue() {
|
|||
func (l *StatsDUDPListener) HandlePacket(packet []byte) {
|
||||
lines := strings.Split(string(packet), "\n")
|
||||
for _, line := range lines {
|
||||
level.Debug(l.Logger).Log("msg", "Incoming line", "proto", "udp", "line", line)
|
||||
l.Logger.Debug("Incoming line", "proto", "udp", "line", line)
|
||||
l.LinesReceived.Inc()
|
||||
if l.Relay != nil && len(line) > 0 {
|
||||
l.Relay.RelayLine(line)
|
||||
|
@ -106,7 +105,7 @@ func (l *StatsDUDPListener) HandlePacket(packet []byte) {
|
|||
type StatsDTCPListener struct {
|
||||
Conn *net.TCPListener
|
||||
EventHandler event.EventHandler
|
||||
Logger log.Logger
|
||||
Logger *slog.Logger
|
||||
LineParser Parser
|
||||
LinesReceived prometheus.Counter
|
||||
EventsFlushed prometheus.Counter
|
||||
|
@ -133,7 +132,7 @@ func (l *StatsDTCPListener) Listen() {
|
|||
if strings.HasSuffix(err.Error(), "use of closed network connection") {
|
||||
return
|
||||
}
|
||||
level.Error(l.Logger).Log("msg", "AcceptTCP failed", "error", err)
|
||||
l.Logger.Error("AcceptTCP failed", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
go l.HandleConn(c)
|
||||
|
@ -151,14 +150,14 @@ func (l *StatsDTCPListener) HandleConn(c *net.TCPConn) {
|
|||
if err != nil {
|
||||
if err != io.EOF {
|
||||
l.TCPErrors.Inc()
|
||||
level.Debug(l.Logger).Log("msg", "Read failed", "addr", c.RemoteAddr(), "error", err)
|
||||
l.Logger.Debug("Read failed", "addr", c.RemoteAddr(), "error", err)
|
||||
}
|
||||
break
|
||||
}
|
||||
level.Debug(l.Logger).Log("msg", "Incoming line", "proto", "tcp", "line", string(line))
|
||||
l.Logger.Debug("Incoming line", "proto", "tcp", "line", string(line))
|
||||
if isPrefix {
|
||||
l.TCPLineTooLong.Inc()
|
||||
level.Debug(l.Logger).Log("msg", "Read failed: line too long", "addr", c.RemoteAddr())
|
||||
l.Logger.Debug("Read failed: line too long", "addr", c.RemoteAddr())
|
||||
break
|
||||
}
|
||||
l.LinesReceived.Inc()
|
||||
|
@ -172,7 +171,7 @@ func (l *StatsDTCPListener) HandleConn(c *net.TCPConn) {
|
|||
type StatsDUnixgramListener struct {
|
||||
Conn *net.UnixConn
|
||||
EventHandler event.EventHandler
|
||||
Logger log.Logger
|
||||
Logger *slog.Logger
|
||||
LineParser Parser
|
||||
UnixgramPackets prometheus.Counter
|
||||
LinesReceived prometheus.Counter
|
||||
|
@ -198,7 +197,7 @@ func (l *StatsDUnixgramListener) Listen() {
|
|||
if strings.HasSuffix(err.Error(), "use of closed network connection") {
|
||||
return
|
||||
}
|
||||
level.Error(l.Logger).Log(err)
|
||||
l.Logger.Error("error reading from unixgram connection", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
l.HandlePacket(buf[:n])
|
||||
|
@ -209,7 +208,7 @@ func (l *StatsDUnixgramListener) HandlePacket(packet []byte) {
|
|||
l.UnixgramPackets.Inc()
|
||||
lines := strings.Split(string(packet), "\n")
|
||||
for _, line := range lines {
|
||||
level.Debug(l.Logger).Log("msg", "Incoming line", "proto", "unixgram", "line", line)
|
||||
l.Logger.Debug("Incoming line", "proto", "unixgram", "line", line)
|
||||
l.LinesReceived.Inc()
|
||||
if l.Relay != nil && len(line) > 0 {
|
||||
l.Relay.RelayLine(line)
|
||||
|
|
|
@ -35,7 +35,7 @@ func (f *FSM) DumpFSM(w io.Writer) {
|
|||
if idx == 0 {
|
||||
// color for metric types
|
||||
w.Write([]byte(fmt.Sprintf("%d [color=\"#D6B656\",fillcolor=\"#FFF2CC\"];\n", len(states)-1)))
|
||||
} else if transition.transitions == nil || len(transition.transitions) == 0 {
|
||||
} else if len(transition.transitions) == 0 {
|
||||
// color for end state
|
||||
w.Write([]byte(fmt.Sprintf("%d [color=\"#82B366\",fillcolor=\"#D5E8D4\"];\n", len(states)-1)))
|
||||
}
|
||||
|
|
|
@ -14,12 +14,9 @@
|
|||
package fsm
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
|
||||
"github.com/prometheus/statsd_exporter/pkg/level"
|
||||
)
|
||||
|
||||
type mappingState struct {
|
||||
|
@ -234,7 +231,7 @@ func (f *FSM) GetMapping(statsdMetric string, statsdMetricType string) (*mapping
|
|||
|
||||
// TestIfNeedBacktracking tests if backtrack is needed for given list of mappings
|
||||
// and whether ordering is disabled.
|
||||
func TestIfNeedBacktracking(mappings []string, orderingDisabled bool, logger log.Logger) bool {
|
||||
func TestIfNeedBacktracking(mappings []string, orderingDisabled bool, logger *slog.Logger) bool {
|
||||
backtrackingNeeded := false
|
||||
// A has * in rules, but there's other transisitions at the same state,
|
||||
// this makes A the cause of backtracking
|
||||
|
@ -250,7 +247,7 @@ func TestIfNeedBacktracking(mappings []string, orderingDisabled bool, logger log
|
|||
metricRe = strings.Replace(metricRe, "*", "([^.]*)", -1)
|
||||
regex, err := regexp.Compile("^" + metricRe + "$")
|
||||
if err != nil {
|
||||
level.Warn(logger).Log("msg", "Invalid match, cannot compile regex in mapping", "mapping", mapping, "err", err)
|
||||
logger.Warn("Invalid match, cannot compile regex in mapping", "mapping", mapping, "err", err)
|
||||
}
|
||||
// put into array no matter there's error or not, we will skip later if regex is nil
|
||||
ruleREByLength[l] = append(ruleREByLength[l], regex)
|
||||
|
@ -293,7 +290,7 @@ func TestIfNeedBacktracking(mappings []string, orderingDisabled bool, logger log
|
|||
if i2 != i1 && len(re1.FindStringSubmatchIndex(r2)) > 0 {
|
||||
// log if we care about ordering and the superset occurs before
|
||||
if !orderingDisabled && i1 < i2 {
|
||||
level.Warn(logger).Log("msg", "match is a super set of match but in a lower order, the first will never be matched", "first_match", r1, "second_match", r2)
|
||||
logger.Warn("match is a super set of match but in a lower order, the first will never be matched", "first_match", r1, "second_match", r2)
|
||||
}
|
||||
currentRuleNeedBacktrack = false
|
||||
}
|
||||
|
@ -311,7 +308,7 @@ func TestIfNeedBacktracking(mappings []string, orderingDisabled bool, logger log
|
|||
}
|
||||
|
||||
if currentRuleNeedBacktrack {
|
||||
level.Warn(logger).Log("msg", "backtracking required because of match. Performance may be degraded", "match", r1)
|
||||
logger.Warn("backtracking required because of match. Performance may be degraded", "match", r1)
|
||||
backtrackingNeeded = true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,16 +15,16 @@ package mapper
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"regexp"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/common/promslog"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/prometheus/statsd_exporter/pkg/level"
|
||||
"github.com/prometheus/statsd_exporter/pkg/mapper/fsm"
|
||||
)
|
||||
|
||||
|
@ -53,7 +53,7 @@ type MetricMapper struct {
|
|||
|
||||
MappingsCount prometheus.Gauge
|
||||
|
||||
Logger log.Logger
|
||||
Logger *slog.Logger
|
||||
}
|
||||
|
||||
type SummaryOptions struct {
|
||||
|
@ -174,12 +174,12 @@ func (m *MetricMapper) InitFromYAMLString(fileContents string) error {
|
|||
|
||||
if currentMapping.LegacyQuantiles != nil &&
|
||||
(currentMapping.SummaryOptions == nil || currentMapping.SummaryOptions.Quantiles != nil) {
|
||||
level.Warn(m.Logger).Log("msg", "using the top level quantiles is deprecated. Please use quantiles in the summary_options hierarchy")
|
||||
m.Logger.Warn("using the top level quantiles is deprecated. Please use quantiles in the summary_options hierarchy")
|
||||
}
|
||||
|
||||
if currentMapping.LegacyBuckets != nil &&
|
||||
(currentMapping.HistogramOptions == nil || currentMapping.HistogramOptions.Buckets != nil) {
|
||||
level.Warn(m.Logger).Log("msg", "using the top level buckets is deprecated. Please use buckets in the histogram_options hierarchy")
|
||||
m.Logger.Warn("using the top level buckets is deprecated. Please use buckets in the histogram_options hierarchy")
|
||||
}
|
||||
|
||||
if currentMapping.SummaryOptions != nil &&
|
||||
|
@ -201,10 +201,10 @@ func (m *MetricMapper) InitFromYAMLString(fileContents string) error {
|
|||
if currentMapping.HistogramOptions == nil {
|
||||
currentMapping.HistogramOptions = &HistogramOptions{}
|
||||
}
|
||||
if currentMapping.LegacyBuckets != nil && len(currentMapping.LegacyBuckets) != 0 {
|
||||
if len(currentMapping.LegacyBuckets) != 0 {
|
||||
currentMapping.HistogramOptions.Buckets = currentMapping.LegacyBuckets
|
||||
}
|
||||
if currentMapping.HistogramOptions.Buckets == nil || len(currentMapping.HistogramOptions.Buckets) == 0 {
|
||||
if len(currentMapping.HistogramOptions.Buckets) == 0 {
|
||||
currentMapping.HistogramOptions.Buckets = n.Defaults.HistogramOptions.Buckets
|
||||
}
|
||||
}
|
||||
|
@ -216,10 +216,10 @@ func (m *MetricMapper) InitFromYAMLString(fileContents string) error {
|
|||
if currentMapping.SummaryOptions == nil {
|
||||
currentMapping.SummaryOptions = &SummaryOptions{}
|
||||
}
|
||||
if currentMapping.LegacyQuantiles != nil && len(currentMapping.LegacyQuantiles) != 0 {
|
||||
if len(currentMapping.LegacyQuantiles) != 0 {
|
||||
currentMapping.SummaryOptions.Quantiles = currentMapping.LegacyQuantiles
|
||||
}
|
||||
if currentMapping.SummaryOptions.Quantiles == nil || len(currentMapping.SummaryOptions.Quantiles) == 0 {
|
||||
if len(currentMapping.SummaryOptions.Quantiles) == 0 {
|
||||
currentMapping.SummaryOptions.Quantiles = n.Defaults.SummaryOptions.Quantiles
|
||||
}
|
||||
if currentMapping.SummaryOptions.MaxAge == 0 {
|
||||
|
@ -242,7 +242,7 @@ func (m *MetricMapper) InitFromYAMLString(fileContents string) error {
|
|||
defer m.mutex.Unlock()
|
||||
|
||||
if m.Logger == nil {
|
||||
m.Logger = log.NewNopLogger()
|
||||
m.Logger = promslog.NewNopLogger()
|
||||
}
|
||||
|
||||
m.Defaults = n.Defaults
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/common/promslog"
|
||||
|
||||
"github.com/prometheus/statsd_exporter/pkg/mappercache/lru"
|
||||
"github.com/prometheus/statsd_exporter/pkg/mappercache/randomreplacement"
|
||||
|
@ -245,7 +245,7 @@ mappings:
|
|||
}
|
||||
|
||||
mapper := MetricMapper{
|
||||
Logger: log.NewNopLogger(),
|
||||
Logger: promslog.NewNopLogger(),
|
||||
}
|
||||
err := mapper.InitFromYAMLString(config)
|
||||
if err != nil {
|
||||
|
|
|
@ -16,24 +16,22 @@ package relay
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"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
|
||||
logger *slog.Logger
|
||||
packetLength uint
|
||||
|
||||
packetsTotal prometheus.Counter
|
||||
|
@ -67,7 +65,7 @@ var (
|
|||
|
||||
// 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) {
|
||||
func NewRelay(l *slog.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)
|
||||
|
@ -110,24 +108,24 @@ func (r *Relay) relayOutput() {
|
|||
case <-relayInterval.C:
|
||||
err = r.sendPacket(buffer.Bytes())
|
||||
if err != nil {
|
||||
level.Error(r.logger).Log("msg", "Error sending UDP packet", "error", err)
|
||||
r.logger.Error("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())
|
||||
r.logger.Debug("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)
|
||||
r.logger.Error("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", string(b))
|
||||
r.logger.Debug("Adding line to buffer", "line", string(b))
|
||||
buffer.Write(b)
|
||||
}
|
||||
}
|
||||
|
@ -137,10 +135,10 @@ func (r *Relay) relayOutput() {
|
|||
// 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")
|
||||
r.logger.Debug("Empty buffer, nothing to send")
|
||||
return nil
|
||||
}
|
||||
level.Debug(r.logger).Log("msg", "Sending packet", "length", len(buf), "data", string(buf))
|
||||
r.logger.Debug("Sending packet", "length", len(buf), "data", string(buf))
|
||||
_, err := r.conn.WriteToUDP(buf, r.addr)
|
||||
r.packetsTotal.Inc()
|
||||
return err
|
||||
|
@ -150,15 +148,15 @@ func (r *Relay) sendPacket(buf []byte) error {
|
|||
func (r *Relay) RelayLine(l string) {
|
||||
lineLength := uint(len(l))
|
||||
if lineLength == 0 {
|
||||
level.Debug(r.logger).Log("msg", "Empty line, not relaying")
|
||||
r.logger.Debug("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.logger.Warn("line too long, not relaying", "length", lineLength, "max", r.packetLength)
|
||||
r.longLinesTotal.Inc()
|
||||
return
|
||||
}
|
||||
level.Debug(r.logger).Log("msg", "Relaying line", "line", string(l))
|
||||
r.logger.Debug("Relaying line", "line", string(l))
|
||||
if !strings.HasSuffix(l, "\n") {
|
||||
l = l + "\n"
|
||||
}
|
||||
|
|
|
@ -19,9 +19,9 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-kit/log"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
"github.com/prometheus/common/promslog"
|
||||
"github.com/prometheus/statsd_exporter/pkg/clock"
|
||||
"github.com/stvp/go-udp-testing"
|
||||
)
|
||||
|
@ -54,7 +54,7 @@ func TestRelay_RelayLine(t *testing.T) {
|
|||
}
|
||||
clock.ClockInstance.Instant = time.Unix(0, 0)
|
||||
|
||||
logger := log.NewNopLogger()
|
||||
logger := promslog.NewNopLogger()
|
||||
r, err := NewRelay(
|
||||
logger,
|
||||
"localhost:1160",
|
||||
|
|
Loading…
Reference in a new issue