mirror of
https://github.com/prometheus/statsd_exporter.git
synced 2024-11-29 02:31:00 +00:00
Merge pull request #586 from prometheus/superq/slog
Update exporter-toolkit
This commit is contained in:
commit
8aac1cabf3
20 changed files with 184 additions and 403 deletions
|
@ -5,7 +5,7 @@ executors:
|
||||||
# Whenever the Go version is updated here, .promu.yml should also be updated.
|
# Whenever the Go version is updated here, .promu.yml should also be updated.
|
||||||
golang:
|
golang:
|
||||||
docker:
|
docker:
|
||||||
- image: cimg/go:1.22
|
- image: cimg/go:1.23
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
executor: golang
|
executor: golang
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
go:
|
go:
|
||||||
# Whenever the Go version is updated here, .circle/config.yml should also
|
# Whenever the Go version is updated here, .circle/config.yml should also
|
||||||
# be updated.
|
# be updated.
|
||||||
version: 1.22
|
version: 1.23
|
||||||
repository:
|
repository:
|
||||||
path: github.com/prometheus/statsd_exporter
|
path: github.com/prometheus/statsd_exporter
|
||||||
build:
|
build:
|
||||||
|
|
|
@ -15,14 +15,15 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"net"
|
"net"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-kit/log"
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
dto "github.com/prometheus/client_model/go"
|
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/clock"
|
||||||
"github.com/prometheus/statsd_exporter/pkg/event"
|
"github.com/prometheus/statsd_exporter/pkg/event"
|
||||||
|
@ -592,7 +593,7 @@ func TestHandlePacket(t *testing.T) {
|
||||||
for k, l := range []statsDPacketHandler{&listener.StatsDUDPListener{
|
for k, l := range []statsDPacketHandler{&listener.StatsDUDPListener{
|
||||||
Conn: nil,
|
Conn: nil,
|
||||||
EventHandler: nil,
|
EventHandler: nil,
|
||||||
Logger: log.NewNopLogger(),
|
Logger: promslog.NewNopLogger(),
|
||||||
LineParser: parser,
|
LineParser: parser,
|
||||||
UDPPackets: udpPackets,
|
UDPPackets: udpPackets,
|
||||||
UDPPacketDrops: udpPacketDrops,
|
UDPPacketDrops: udpPacketDrops,
|
||||||
|
@ -605,7 +606,7 @@ func TestHandlePacket(t *testing.T) {
|
||||||
}, &mockStatsDTCPListener{listener.StatsDTCPListener{
|
}, &mockStatsDTCPListener{listener.StatsDTCPListener{
|
||||||
Conn: nil,
|
Conn: nil,
|
||||||
EventHandler: nil,
|
EventHandler: nil,
|
||||||
Logger: log.NewNopLogger(),
|
Logger: promslog.NewNopLogger(),
|
||||||
LineParser: parser,
|
LineParser: parser,
|
||||||
LinesReceived: linesReceived,
|
LinesReceived: linesReceived,
|
||||||
EventsFlushed: eventsFlushed,
|
EventsFlushed: eventsFlushed,
|
||||||
|
@ -616,7 +617,7 @@ func TestHandlePacket(t *testing.T) {
|
||||||
TCPConnections: tcpConnections,
|
TCPConnections: tcpConnections,
|
||||||
TCPErrors: tcpErrors,
|
TCPErrors: tcpErrors,
|
||||||
TCPLineTooLong: tcpLineTooLong,
|
TCPLineTooLong: tcpLineTooLong,
|
||||||
}, log.NewNopLogger()}} {
|
}, promslog.NewNopLogger()}} {
|
||||||
events := make(chan event.Events, 32)
|
events := make(chan event.Events, 32)
|
||||||
l.SetEventHandler(&event.UnbufferedEventHandler{C: events})
|
l.SetEventHandler(&event.UnbufferedEventHandler{C: events})
|
||||||
for i, scenario := range scenarios {
|
for i, scenario := range scenarios {
|
||||||
|
@ -649,7 +650,7 @@ type statsDPacketHandler interface {
|
||||||
|
|
||||||
type mockStatsDTCPListener struct {
|
type mockStatsDTCPListener struct {
|
||||||
listener.StatsDTCPListener
|
listener.StatsDTCPListener
|
||||||
log.Logger
|
*slog.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ml *mockStatsDTCPListener) HandlePacket(packet []byte) {
|
func (ml *mockStatsDTCPListener) HandlePacket(packet []byte) {
|
||||||
|
@ -710,7 +711,7 @@ mappings:
|
||||||
events := make(chan event.Events)
|
events := make(chan event.Events)
|
||||||
defer close(events)
|
defer close(events)
|
||||||
go func() {
|
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)
|
ex.Listen(events)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/go-kit/log"
|
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"github.com/prometheus/common/promslog"
|
||||||
|
|
||||||
"github.com/prometheus/statsd_exporter/pkg/event"
|
"github.com/prometheus/statsd_exporter/pkg/event"
|
||||||
"github.com/prometheus/statsd_exporter/pkg/exporter"
|
"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",
|
"some_very_useful_metrics_with_quite_a_log_name:13|c",
|
||||||
}
|
}
|
||||||
bytesInput := make([]string, len(input)*times)
|
bytesInput := make([]string, len(input)*times)
|
||||||
logger := log.NewNopLogger()
|
logger := promslog.NewNopLogger()
|
||||||
for run := 0; run < times; run++ {
|
for run := 0; run < times; run++ {
|
||||||
for i := 0; i < len(input); i++ {
|
for i := 0; i < len(input); i++ {
|
||||||
bytesInput[run*len(input)+i] = fmt.Sprintf("run%d%s", run, 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)
|
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
|
// reset benchmark timer to not measure startup costs
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
|
22
go.mod
22
go.mod
|
@ -1,15 +1,14 @@
|
||||||
module github.com/prometheus/statsd_exporter
|
module github.com/prometheus/statsd_exporter
|
||||||
|
|
||||||
go 1.21
|
go 1.22
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/alecthomas/kingpin/v2 v2.4.0
|
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/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
|
||||||
github.com/prometheus/client_golang v1.20.3
|
github.com/prometheus/client_golang v1.20.4
|
||||||
github.com/prometheus/client_model v0.6.1
|
github.com/prometheus/client_model v0.6.1
|
||||||
github.com/prometheus/common v0.57.0
|
github.com/prometheus/common v0.60.0
|
||||||
github.com/prometheus/exporter-toolkit v0.11.0
|
github.com/prometheus/exporter-toolkit v0.13.0
|
||||||
github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807
|
github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
)
|
)
|
||||||
|
@ -19,18 +18,19 @@ require (
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
|
||||||
github.com/jpillora/backoff v1.0.0 // indirect
|
github.com/jpillora/backoff v1.0.0 // indirect
|
||||||
github.com/klauspost/compress v1.17.9 // 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/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
||||||
github.com/prometheus/procfs v0.15.1 // indirect
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
|
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
|
||||||
golang.org/x/crypto v0.26.0 // indirect
|
golang.org/x/crypto v0.27.0 // indirect
|
||||||
golang.org/x/net v0.28.0 // indirect
|
golang.org/x/net v0.29.0 // indirect
|
||||||
golang.org/x/oauth2 v0.22.0 // indirect
|
golang.org/x/oauth2 v0.23.0 // indirect
|
||||||
golang.org/x/sync v0.8.0 // indirect
|
golang.org/x/sync v0.8.0 // indirect
|
||||||
golang.org/x/sys v0.24.0 // indirect
|
golang.org/x/sys v0.25.0 // indirect
|
||||||
golang.org/x/text v0.17.0 // indirect
|
golang.org/x/text v0.18.0 // indirect
|
||||||
google.golang.org/protobuf v1.34.2 // indirect
|
google.golang.org/protobuf v1.34.2 // indirect
|
||||||
)
|
)
|
||||||
|
|
40
go.sum
40
go.sum
|
@ -11,10 +11,6 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
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 h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
@ -30,20 +26,24 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
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/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 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
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 h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4=
|
github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI=
|
||||||
github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
github.com/prometheus/client_golang v1.20.4/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 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||||
github.com/prometheus/common v0.57.0 h1:Ro/rKjwdq9mZn1K5QPctzh+MA4Lp0BuYk5ZZEVhoNcY=
|
github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA=
|
||||||
github.com/prometheus/common v0.57.0/go.mod h1:7uRPFSUTbfZWsJ7MHY56sqt7hLQu3bxXHDnNhl8E9qI=
|
github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw=
|
||||||
github.com/prometheus/exporter-toolkit v0.11.0 h1:yNTsuZ0aNCNFQ3aFTD2uhPOvr4iD7fdBvKPAEGkNf+g=
|
github.com/prometheus/exporter-toolkit v0.13.0 h1:lmA0Q+8IaXgmFRKw09RldZmZdnvu9wwcDLIXGmTPw1c=
|
||||||
github.com/prometheus/exporter-toolkit v0.11.0/go.mod h1:BVnENhnNecpwoTLiABx7mrPB/OLRIgN74qlQbV+FK1Q=
|
github.com/prometheus/exporter-toolkit v0.13.0/go.mod h1:2uop99EZl80KdXhv/MxVI2181fMcwlsumFOqBecGkG0=
|
||||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
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/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 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||||
|
@ -61,18 +61,18 @@ github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807 h1:LUsDduamluc
|
||||||
github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc=
|
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 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=
|
||||||
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
|
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
|
||||||
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||||
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
||||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
||||||
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
|
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
||||||
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
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 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
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 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|
|
@ -16,7 +16,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/go-kit/log"
|
"github.com/prometheus/common/promslog"
|
||||||
|
|
||||||
"github.com/prometheus/statsd_exporter/pkg/line"
|
"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",
|
"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",
|
"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) {
|
func benchmarkLinesToEvents(times int, b *testing.B, input []string) {
|
||||||
|
|
93
main.go
93
main.go
|
@ -16,6 +16,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
_ "net/http/pprof"
|
_ "net/http/pprof"
|
||||||
|
@ -25,20 +26,18 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/alecthomas/kingpin/v2"
|
"github.com/alecthomas/kingpin/v2"
|
||||||
"github.com/go-kit/log"
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
versioncollector "github.com/prometheus/client_golang/prometheus/collectors/version"
|
versioncollector "github.com/prometheus/client_golang/prometheus/collectors/version"
|
||||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
"github.com/prometheus/common/promlog"
|
"github.com/prometheus/common/promslog"
|
||||||
"github.com/prometheus/common/promlog/flag"
|
"github.com/prometheus/common/promslog/flag"
|
||||||
"github.com/prometheus/common/version"
|
"github.com/prometheus/common/version"
|
||||||
"github.com/prometheus/exporter-toolkit/web"
|
"github.com/prometheus/exporter-toolkit/web"
|
||||||
|
|
||||||
"github.com/prometheus/statsd_exporter/pkg/address"
|
"github.com/prometheus/statsd_exporter/pkg/address"
|
||||||
"github.com/prometheus/statsd_exporter/pkg/event"
|
"github.com/prometheus/statsd_exporter/pkg/event"
|
||||||
"github.com/prometheus/statsd_exporter/pkg/exporter"
|
"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/line"
|
||||||
"github.com/prometheus/statsd_exporter/pkg/listener"
|
"github.com/prometheus/statsd_exporter/pkg/listener"
|
||||||
"github.com/prometheus/statsd_exporter/pkg/mapper"
|
"github.com/prometheus/statsd_exporter/pkg/mapper"
|
||||||
|
@ -174,49 +173,49 @@ var (
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
func serveHTTP(mux http.Handler, listenAddress string, logger log.Logger) {
|
func serveHTTP(mux http.Handler, listenAddress string, logger *slog.Logger) {
|
||||||
level.Error(logger).Log("msg", http.ListenAndServe(listenAddress, mux))
|
logger.Error(http.ListenAndServe(listenAddress, mux).Error())
|
||||||
os.Exit(1)
|
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)
|
signals := make(chan os.Signal, 1)
|
||||||
signal.Notify(signals, syscall.SIGHUP)
|
signal.Notify(signals, syscall.SIGHUP)
|
||||||
|
|
||||||
for s := range signals {
|
for s := range signals {
|
||||||
if fileName == "" {
|
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
level.Info(logger).Log("msg", "Received signal, attempting reload", "signal", s)
|
logger.Info("Received signal, attempting reload", "signal", s)
|
||||||
|
|
||||||
reloadConfig(fileName, mapper, logger)
|
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)
|
err := mapper.InitFromFile(fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
level.Info(logger).Log("msg", "Error reloading config", "error", err)
|
logger.Info("Error reloading config", "error", err)
|
||||||
configLoads.WithLabelValues("failure").Inc()
|
configLoads.WithLabelValues("failure").Inc()
|
||||||
} else {
|
} else {
|
||||||
level.Info(logger).Log("msg", "Config reloaded successfully")
|
logger.Info("Config reloaded successfully")
|
||||||
configLoads.WithLabelValues("success").Inc()
|
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)
|
f, err := os.Create(dumpFilename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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)
|
w := bufio.NewWriter(f)
|
||||||
mapper.FSM.DumpFSM(w)
|
mapper.FSM.DumpFSM(w)
|
||||||
w.Flush()
|
w.Flush()
|
||||||
f.Close()
|
f.Close()
|
||||||
level.Info(logger).Log("msg", "Finish dumping FSM")
|
logger.Info("Finish dumping FSM")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,17 +270,13 @@ func main() {
|
||||||
udpPacketQueueSize = kingpin.Flag("statsd.udp-packet-queue-size", "Size of internal queue for processing UDP packets.").Default("10000").Int()
|
udpPacketQueueSize = kingpin.Flag("statsd.udp-packet-queue-size", "Size of internal queue for processing UDP packets.").Default("10000").Int()
|
||||||
)
|
)
|
||||||
|
|
||||||
promlogConfig := &promlog.Config{}
|
promslogConfig := &promslog.Config{}
|
||||||
flag.AddFlags(kingpin.CommandLine, promlogConfig)
|
flag.AddFlags(kingpin.CommandLine, promslogConfig)
|
||||||
kingpin.Version(version.Print("statsd_exporter"))
|
kingpin.Version(version.Print("statsd_exporter"))
|
||||||
kingpin.CommandLine.UsageWriter(os.Stdout)
|
kingpin.CommandLine.UsageWriter(os.Stdout)
|
||||||
kingpin.HelpFlag.Short('h')
|
kingpin.HelpFlag.Short('h')
|
||||||
kingpin.Parse()
|
kingpin.Parse()
|
||||||
logger := promlog.New(promlogConfig)
|
logger := promslog.New(promslogConfig)
|
||||||
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(versioncollector.NewCollector("statsd_exporter"))
|
prometheus.MustRegister(versioncollector.NewCollector("statsd_exporter"))
|
||||||
|
|
||||||
parser := line.NewParser()
|
parser := line.NewParser()
|
||||||
|
@ -298,8 +293,8 @@ func main() {
|
||||||
parser.EnableSignalFXParsing()
|
parser.EnableSignalFXParsing()
|
||||||
}
|
}
|
||||||
|
|
||||||
level.Info(logger).Log("msg", "Starting StatsD -> Prometheus Exporter", "version", version.Info())
|
logger.Info("Starting StatsD -> Prometheus Exporter", "version", version.Info())
|
||||||
level.Info(logger).Log("msg", "Build context", "context", version.BuildContext())
|
logger.Info("Build context", "context", version.BuildContext())
|
||||||
|
|
||||||
events := make(chan event.Events, *eventQueueSize)
|
events := make(chan event.Events, *eventQueueSize)
|
||||||
defer close(events)
|
defer close(events)
|
||||||
|
@ -309,7 +304,7 @@ func main() {
|
||||||
|
|
||||||
cache, err := getCache(*cacheSize, *cacheType, thisMapper.Registerer)
|
cache, err := getCache(*cacheSize, *cacheType, thisMapper.Registerer)
|
||||||
if err != nil {
|
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)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
thisMapper.UseCache(cache)
|
thisMapper.UseCache(cache)
|
||||||
|
@ -317,13 +312,13 @@ func main() {
|
||||||
if *mappingConfig != "" {
|
if *mappingConfig != "" {
|
||||||
err := thisMapper.InitFromFile(*mappingConfig)
|
err := thisMapper.InitFromFile(*mappingConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
level.Error(logger).Log("msg", "error loading config", "error", err)
|
logger.Error("error loading config", "error", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
if *dumpFSMPath != "" {
|
if *dumpFSMPath != "" {
|
||||||
err := dumpFSM(thisMapper, *dumpFSMPath, logger)
|
err := dumpFSM(thisMapper, *dumpFSMPath, logger)
|
||||||
if err != nil {
|
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
|
// 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
|
// didn't happen) but not fatal (the exporter is fully functional
|
||||||
// afterwards).
|
// afterwards).
|
||||||
|
@ -334,7 +329,7 @@ func main() {
|
||||||
exporter := exporter.NewExporter(prometheus.DefaultRegisterer, thisMapper, logger, eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
exporter := exporter.NewExporter(prometheus.DefaultRegisterer, thisMapper, logger, eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount)
|
||||||
|
|
||||||
if *checkConfig {
|
if *checkConfig {
|
||||||
level.Info(logger).Log("msg", "Configuration check successful, exiting")
|
logger.Info("Configuration check successful, exiting")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,35 +338,35 @@ func main() {
|
||||||
var err error
|
var err error
|
||||||
relayTarget, err = relay.NewRelay(logger, *relayAddr, *relayPacketLen)
|
relayTarget, err = relay.NewRelay(logger, *relayAddr, *relayPacketLen)
|
||||||
if err != nil {
|
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)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
level.Info(logger).Log("msg", "Accepting StatsD Traffic", "udp", *statsdListenUDP, "tcp", *statsdListenTCP, "unixgram", *statsdListenUnixgram)
|
logger.Info("Accepting StatsD Traffic", "udp", *statsdListenUDP, "tcp", *statsdListenTCP, "unixgram", *statsdListenUnixgram)
|
||||||
level.Info(logger).Log("msg", "Accepting Prometheus Requests", "addr", *listenAddress)
|
logger.Info("Accepting Prometheus Requests", "addr", *listenAddress)
|
||||||
|
|
||||||
if *statsdListenUDP == "" && *statsdListenTCP == "" && *statsdListenUnixgram == "" {
|
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)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if *statsdListenUDP != "" {
|
if *statsdListenUDP != "" {
|
||||||
udpListenAddr, err := address.UDPAddrFromString(*statsdListenUDP)
|
udpListenAddr, err := address.UDPAddrFromString(*statsdListenUDP)
|
||||||
if err != nil {
|
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)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
uconn, err := net.ListenUDP("udp", udpListenAddr)
|
uconn, err := net.ListenUDP("udp", udpListenAddr)
|
||||||
if err != nil {
|
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)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if *readBuffer != 0 {
|
if *readBuffer != 0 {
|
||||||
err = uconn.SetReadBuffer(*readBuffer)
|
err = uconn.SetReadBuffer(*readBuffer)
|
||||||
if err != nil {
|
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)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -401,12 +396,12 @@ func main() {
|
||||||
if *statsdListenTCP != "" {
|
if *statsdListenTCP != "" {
|
||||||
tcpListenAddr, err := address.TCPAddrFromString(*statsdListenTCP)
|
tcpListenAddr, err := address.TCPAddrFromString(*statsdListenTCP)
|
||||||
if err != nil {
|
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)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
tconn, err := net.ListenTCP("tcp", tcpListenAddr)
|
tconn, err := net.ListenTCP("tcp", tcpListenAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
level.Error(logger).Log("msg", err)
|
logger.Error("failed to start TCP listener", "err", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
defer tconn.Close()
|
defer tconn.Close()
|
||||||
|
@ -434,7 +429,7 @@ func main() {
|
||||||
if *statsdListenUnixgram != "" {
|
if *statsdListenUnixgram != "" {
|
||||||
var err error
|
var err error
|
||||||
if _, err = os.Stat(*statsdListenUnixgram); !os.IsNotExist(err) {
|
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)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
uxgconn, err := net.ListenUnixgram("unixgram", &net.UnixAddr{
|
uxgconn, err := net.ListenUnixgram("unixgram", &net.UnixAddr{
|
||||||
|
@ -442,7 +437,7 @@ func main() {
|
||||||
Name: *statsdListenUnixgram,
|
Name: *statsdListenUnixgram,
|
||||||
})
|
})
|
||||||
if err != nil {
|
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)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +446,7 @@ func main() {
|
||||||
if *readBuffer != 0 {
|
if *readBuffer != 0 {
|
||||||
err = uxgconn.SetReadBuffer(*readBuffer)
|
err = uxgconn.SetReadBuffer(*readBuffer)
|
||||||
if err != nil {
|
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)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -481,11 +476,11 @@ func main() {
|
||||||
// convert the string to octet
|
// convert the string to octet
|
||||||
perm, err := strconv.ParseInt("0"+string(*statsdUnixSocketMode), 8, 32)
|
perm, err := strconv.ParseInt("0"+string(*statsdUnixSocketMode), 8, 32)
|
||||||
if err != nil {
|
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 {
|
} else {
|
||||||
err = os.Chmod(*statsdListenUnixgram, os.FileMode(perm))
|
err = os.Chmod(*statsdListenUnixgram, os.FileMode(perm))
|
||||||
if err != nil {
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -507,7 +502,7 @@ func main() {
|
||||||
}
|
}
|
||||||
landingPage, err := web.NewLandingPage(landingConfig)
|
landingPage, err := web.NewLandingPage(landingConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
level.Error(logger).Log("err", err)
|
logger.Error("error creating landing page", "err", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
mux.Handle("/", landingPage)
|
mux.Handle("/", landingPage)
|
||||||
|
@ -520,10 +515,10 @@ func main() {
|
||||||
if r.Method == http.MethodPut || r.Method == http.MethodPost {
|
if r.Method == http.MethodPut || r.Method == http.MethodPost {
|
||||||
fmt.Fprintf(w, "Requesting reload")
|
fmt.Fprintf(w, "Requesting reload")
|
||||||
if *mappingConfig == "" {
|
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
|
return
|
||||||
}
|
}
|
||||||
level.Info(logger).Log("msg", "Received lifecycle api reload, attempting reload")
|
logger.Info("Received lifecycle api reload, attempting reload")
|
||||||
reloadConfig(*mappingConfig, thisMapper, logger)
|
reloadConfig(*mappingConfig, thisMapper, logger)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -537,7 +532,7 @@ func main() {
|
||||||
|
|
||||||
mux.HandleFunc("/-/healthy", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/-/healthy", func(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method == http.MethodGet {
|
if r.Method == http.MethodGet {
|
||||||
level.Debug(logger).Log("msg", "Received health check")
|
logger.Debug("Received health check")
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
fmt.Fprintf(w, "Statsd Exporter is Healthy.\n")
|
fmt.Fprintf(w, "Statsd Exporter is Healthy.\n")
|
||||||
}
|
}
|
||||||
|
@ -545,7 +540,7 @@ func main() {
|
||||||
|
|
||||||
mux.HandleFunc("/-/ready", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/-/ready", func(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method == http.MethodGet {
|
if r.Method == http.MethodGet {
|
||||||
level.Debug(logger).Log("msg", "Received ready check")
|
logger.Debug("Received ready check")
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
fmt.Fprintf(w, "Statsd Exporter is Ready.\n")
|
fmt.Fprintf(w, "Statsd Exporter is Ready.\n")
|
||||||
}
|
}
|
||||||
|
@ -562,8 +557,8 @@ func main() {
|
||||||
// quit if we get a message on either channel
|
// quit if we get a message on either channel
|
||||||
select {
|
select {
|
||||||
case sig := <-signals:
|
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:
|
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
|
package exporter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-kit/log"
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
|
||||||
"github.com/prometheus/statsd_exporter/pkg/clock"
|
"github.com/prometheus/statsd_exporter/pkg/clock"
|
||||||
"github.com/prometheus/statsd_exporter/pkg/event"
|
"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/mapper"
|
||||||
"github.com/prometheus/statsd_exporter/pkg/registry"
|
"github.com/prometheus/statsd_exporter/pkg/registry"
|
||||||
)
|
)
|
||||||
|
@ -43,7 +42,7 @@ type Registry interface {
|
||||||
type Exporter struct {
|
type Exporter struct {
|
||||||
Mapper *mapper.MetricMapper
|
Mapper *mapper.MetricMapper
|
||||||
Registry Registry
|
Registry Registry
|
||||||
Logger log.Logger
|
Logger *slog.Logger
|
||||||
EventsActions *prometheus.CounterVec
|
EventsActions *prometheus.CounterVec
|
||||||
EventsUnmapped prometheus.Counter
|
EventsUnmapped prometheus.Counter
|
||||||
ErrorEventStats *prometheus.CounterVec
|
ErrorEventStats *prometheus.CounterVec
|
||||||
|
@ -63,7 +62,7 @@ func (b *Exporter) Listen(e <-chan event.Events) {
|
||||||
b.Registry.RemoveStaleMetrics()
|
b.Registry.RemoveStaleMetrics()
|
||||||
case events, ok := <-e:
|
case events, ok := <-e:
|
||||||
if !ok {
|
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()
|
removeStaleMetricsTicker.Stop()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -99,7 +98,7 @@ func (b *Exporter) handleEvent(thisEvent event.Event) {
|
||||||
prometheusLabels := thisEvent.Labels()
|
prometheusLabels := thisEvent.Labels()
|
||||||
if present {
|
if present {
|
||||||
if mapping.Name == "" {
|
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()
|
b.ErrorEventStats.WithLabelValues("empty_metric_name").Inc()
|
||||||
return
|
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
|
// 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.
|
// will cause the exporter to panic. Instead we will warn and continue to the next event.
|
||||||
if eventValue < 0.0 {
|
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()
|
b.ErrorEventStats.WithLabelValues("illegal_negative_counter").Inc()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -137,7 +136,7 @@ func (b *Exporter) handleEvent(thisEvent event.Event) {
|
||||||
counter.Add(eventValue)
|
counter.Add(eventValue)
|
||||||
b.EventStats.WithLabelValues("counter").Inc()
|
b.EventStats.WithLabelValues("counter").Inc()
|
||||||
} else {
|
} 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()
|
b.ConflictingEventStats.WithLabelValues("counter").Inc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +151,7 @@ func (b *Exporter) handleEvent(thisEvent event.Event) {
|
||||||
}
|
}
|
||||||
b.EventStats.WithLabelValues("gauge").Inc()
|
b.EventStats.WithLabelValues("gauge").Inc()
|
||||||
} else {
|
} 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()
|
b.ConflictingEventStats.WithLabelValues("gauge").Inc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +171,7 @@ func (b *Exporter) handleEvent(thisEvent event.Event) {
|
||||||
histogram.Observe(eventValue)
|
histogram.Observe(eventValue)
|
||||||
b.EventStats.WithLabelValues("observer").Inc()
|
b.EventStats.WithLabelValues("observer").Inc()
|
||||||
} else {
|
} 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()
|
b.ConflictingEventStats.WithLabelValues("observer").Inc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,22 +181,22 @@ func (b *Exporter) handleEvent(thisEvent event.Event) {
|
||||||
summary.Observe(eventValue)
|
summary.Observe(eventValue)
|
||||||
b.EventStats.WithLabelValues("observer").Inc()
|
b.EventStats.WithLabelValues("observer").Inc()
|
||||||
} else {
|
} 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()
|
b.ConflictingEventStats.WithLabelValues("observer").Inc()
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
level.Error(b.Logger).Log("msg", "unknown observer type", "type", t)
|
b.Logger.Error("unknown observer type", "type", t)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
level.Debug(b.Logger).Log("msg", "Unsupported event type")
|
b.Logger.Debug("Unsupported event type")
|
||||||
b.EventStats.WithLabelValues("illegal").Inc()
|
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{
|
return &Exporter{
|
||||||
Mapper: mapper,
|
Mapper: mapper,
|
||||||
Registry: registry.NewRegistry(reg, mapper),
|
Registry: registry.NewRegistry(reg, mapper),
|
||||||
|
|
|
@ -15,13 +15,14 @@ package exporter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-kit/log"
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
dto "github.com/prometheus/client_model/go"
|
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/clock"
|
||||||
"github.com/prometheus/statsd_exporter/pkg/event"
|
"github.com/prometheus/statsd_exporter/pkg/event"
|
||||||
|
@ -172,7 +173,7 @@ func TestNegativeCounter(t *testing.T) {
|
||||||
|
|
||||||
testMapper := mapper.MetricMapper{}
|
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)
|
ex.Listen(events)
|
||||||
|
|
||||||
updated := getTelemetryCounterValue(errorCounter)
|
updated := getTelemetryCounterValue(errorCounter)
|
||||||
|
@ -253,7 +254,7 @@ mappings:
|
||||||
t.Fatalf("Config load error: %s %s", config, err)
|
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)
|
ex.Listen(events)
|
||||||
|
|
||||||
metrics, err := prometheus.DefaultGatherer.Gather()
|
metrics, err := prometheus.DefaultGatherer.Gather()
|
||||||
|
@ -316,7 +317,7 @@ mappings:
|
||||||
t.Fatalf("Config load error: %s %s", config, err)
|
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)
|
ex.Listen(events)
|
||||||
|
|
||||||
metrics, err := prometheus.DefaultGatherer.Gather()
|
metrics, err := prometheus.DefaultGatherer.Gather()
|
||||||
|
@ -359,14 +360,14 @@ mappings:
|
||||||
honor_labels: true
|
honor_labels: true
|
||||||
`
|
`
|
||||||
testMapper := &mapper.MetricMapper{
|
testMapper := &mapper.MetricMapper{
|
||||||
Logger: log.NewNopLogger(),
|
Logger: promslog.NewNopLogger(),
|
||||||
}
|
}
|
||||||
err := testMapper.InitFromYAMLString(config)
|
err := testMapper.InitFromYAMLString(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Config load error: %s %s", config, err)
|
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)
|
ex.Listen(events)
|
||||||
|
|
||||||
metrics, err := prometheus.DefaultGatherer.Gather()
|
metrics, err := prometheus.DefaultGatherer.Gather()
|
||||||
|
@ -647,7 +648,7 @@ mappings:
|
||||||
close(events)
|
close(events)
|
||||||
}()
|
}()
|
||||||
reg := prometheus.NewRegistry()
|
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)
|
ex.Listen(events)
|
||||||
|
|
||||||
metrics, err := reg.Gather()
|
metrics, err := reg.Gather()
|
||||||
|
@ -702,7 +703,7 @@ mappings:
|
||||||
errorCounter := errorEventStats.WithLabelValues("empty_metric_name")
|
errorCounter := errorEventStats.WithLabelValues("empty_metric_name")
|
||||||
prev := getTelemetryCounterValue(errorCounter)
|
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)
|
ex.Listen(events)
|
||||||
|
|
||||||
updated := getTelemetryCounterValue(errorCounter)
|
updated := getTelemetryCounterValue(errorCounter)
|
||||||
|
@ -736,7 +737,7 @@ func TestInvalidUtf8InDatadogTagValue(t *testing.T) {
|
||||||
for _, l := range []statsDPacketHandler{&listener.StatsDUDPListener{
|
for _, l := range []statsDPacketHandler{&listener.StatsDUDPListener{
|
||||||
Conn: nil,
|
Conn: nil,
|
||||||
EventHandler: nil,
|
EventHandler: nil,
|
||||||
Logger: log.NewNopLogger(),
|
Logger: promslog.NewNopLogger(),
|
||||||
LineParser: parser,
|
LineParser: parser,
|
||||||
UDPPackets: udpPackets,
|
UDPPackets: udpPackets,
|
||||||
UDPPacketDrops: udpPacketDrops,
|
UDPPacketDrops: udpPacketDrops,
|
||||||
|
@ -749,7 +750,7 @@ func TestInvalidUtf8InDatadogTagValue(t *testing.T) {
|
||||||
}, &mockStatsDTCPListener{listener.StatsDTCPListener{
|
}, &mockStatsDTCPListener{listener.StatsDTCPListener{
|
||||||
Conn: nil,
|
Conn: nil,
|
||||||
EventHandler: nil,
|
EventHandler: nil,
|
||||||
Logger: log.NewNopLogger(),
|
Logger: promslog.NewNopLogger(),
|
||||||
LineParser: parser,
|
LineParser: parser,
|
||||||
LinesReceived: linesReceived,
|
LinesReceived: linesReceived,
|
||||||
EventsFlushed: eventsFlushed,
|
EventsFlushed: eventsFlushed,
|
||||||
|
@ -760,7 +761,7 @@ func TestInvalidUtf8InDatadogTagValue(t *testing.T) {
|
||||||
TCPConnections: tcpConnections,
|
TCPConnections: tcpConnections,
|
||||||
TCPErrors: tcpErrors,
|
TCPErrors: tcpErrors,
|
||||||
TCPLineTooLong: tcpLineTooLong,
|
TCPLineTooLong: tcpLineTooLong,
|
||||||
}, log.NewNopLogger()}} {
|
}, promslog.NewNopLogger()}} {
|
||||||
l.SetEventHandler(ueh)
|
l.SetEventHandler(ueh)
|
||||||
l.HandlePacket([]byte("bar:200|c|#tag:value\nbar:200|c|#tag:\xc3\x28invalid"))
|
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{}
|
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)
|
ex.Listen(events)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -782,7 +783,7 @@ func TestSummaryWithQuantilesEmptyMapping(t *testing.T) {
|
||||||
go func() {
|
go func() {
|
||||||
testMapper := mapper.MetricMapper{}
|
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)
|
ex.Listen(events)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -825,7 +826,7 @@ func TestHistogramUnits(t *testing.T) {
|
||||||
events := make(chan event.Events)
|
events := make(chan event.Events)
|
||||||
go func() {
|
go func() {
|
||||||
testMapper := mapper.MetricMapper{}
|
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.Mapper.Defaults.ObserverType = mapper.ObserverTypeHistogram
|
||||||
ex.Listen(events)
|
ex.Listen(events)
|
||||||
}()
|
}()
|
||||||
|
@ -861,7 +862,7 @@ func TestCounterIncrement(t *testing.T) {
|
||||||
events := make(chan event.Events)
|
events := make(chan event.Events)
|
||||||
go func() {
|
go func() {
|
||||||
testMapper := mapper.MetricMapper{}
|
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)
|
ex.Listen(events)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -908,7 +909,7 @@ func TestGaugeIncrementDecrement(t *testing.T) {
|
||||||
events := make(chan event.Events)
|
events := make(chan event.Events)
|
||||||
go func() {
|
go func() {
|
||||||
testMapper := mapper.MetricMapper{}
|
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)
|
ex.Listen(events)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -970,7 +971,7 @@ func TestScaledMapping(t *testing.T) {
|
||||||
|
|
||||||
// Start exporter with a synchronous channel
|
// Start exporter with a synchronous channel
|
||||||
go func() {
|
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)
|
ex.Listen(events)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -1018,7 +1019,7 @@ type statsDPacketHandler interface {
|
||||||
|
|
||||||
type mockStatsDTCPListener struct {
|
type mockStatsDTCPListener struct {
|
||||||
listener.StatsDTCPListener
|
listener.StatsDTCPListener
|
||||||
log.Logger
|
*slog.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ml *mockStatsDTCPListener) HandlePacket(packet []byte) {
|
func (ml *mockStatsDTCPListener) HandlePacket(packet []byte) {
|
||||||
|
@ -1079,7 +1080,7 @@ mappings:
|
||||||
events := make(chan event.Events)
|
events := make(chan event.Events)
|
||||||
defer close(events)
|
defer close(events)
|
||||||
go func() {
|
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)
|
ex.Listen(events)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -1291,7 +1292,7 @@ func BenchmarkParseDogStatsDTags(b *testing.B) {
|
||||||
b.Run(name, func(b *testing.B) {
|
b.Run(name, func(b *testing.B) {
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
labels := map[string]string{}
|
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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/go-kit/log"
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
|
||||||
"github.com/prometheus/statsd_exporter/pkg/event"
|
"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/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
|
// Entirely empty tag is an error
|
||||||
if len(tag) == 0 {
|
if len(tag) == 0 {
|
||||||
tagErrors.Inc()
|
tagErrors.Inc()
|
||||||
level.Debug(logger).Log("msg", "Empty name tag", "component", component)
|
logger.Debug("Empty name tag", "component", component)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +110,7 @@ func parseTag(component, tag string, separator rune, labels map[string]string, t
|
||||||
if len(k) == 0 || len(v) == 0 {
|
if len(k) == 0 || len(v) == 0 {
|
||||||
// Empty key or value is an error
|
// Empty key or value is an error
|
||||||
tagErrors.Inc()
|
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 {
|
} else {
|
||||||
labels[mapper.EscapeMetricName(k)] = v
|
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
|
// Missing separator (no value) is an error
|
||||||
tagErrors.Inc()
|
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
|
lastTagEndIndex := 0
|
||||||
for i, c := range component {
|
for i, c := range component {
|
||||||
if c == ',' {
|
if c == ',' {
|
||||||
|
@ -148,7 +147,7 @@ func trimLeftHash(s string) string {
|
||||||
return s
|
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 {
|
if p.DogstatsdTagsEnabled {
|
||||||
lastTagEndIndex := 0
|
lastTagEndIndex := 0
|
||||||
for i, c := range component {
|
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 {
|
if p.SignalFXTagsEnabled {
|
||||||
// check for SignalFx tags first
|
// check for SignalFx tags first
|
||||||
// `[` delimits start of tags by SignalFx
|
// `[` 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:]
|
return name[:startIdx] + name[endIdx+1:]
|
||||||
case (startIdx != -1) != (endIdx != -1):
|
case (startIdx != -1) != (endIdx != -1):
|
||||||
// only one bracket, return unparsed
|
// 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()
|
tagErrors.Inc()
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
@ -202,7 +201,7 @@ func (p *Parser) parseNameAndTags(name string, labels map[string]string, tagErro
|
||||||
return name
|
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{}
|
events := event.Events{}
|
||||||
if line == "" {
|
if line == "" {
|
||||||
return events
|
return events
|
||||||
|
@ -211,7 +210,7 @@ func (p *Parser) LineToEvents(line string, sampleErrors prometheus.CounterVec, s
|
||||||
elements := strings.SplitN(line, ":", 2)
|
elements := strings.SplitN(line, ":", 2)
|
||||||
if len(elements) < 2 || len(elements[0]) == 0 || !utf8.ValidString(line) {
|
if len(elements) < 2 || len(elements[0]) == 0 || !utf8.ValidString(line) {
|
||||||
sampleErrors.WithLabelValues("malformed_line").Inc()
|
sampleErrors.WithLabelValues("malformed_line").Inc()
|
||||||
level.Debug(logger).Log("msg", "bad line", "line", line)
|
logger.Debug("bad line", "line", line)
|
||||||
return events
|
return events
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +222,7 @@ func (p *Parser) LineToEvents(line string, sampleErrors prometheus.CounterVec, s
|
||||||
|
|
||||||
// don't allow mixed tagging styles
|
// don't allow mixed tagging styles
|
||||||
sampleErrors.WithLabelValues("mixed_tagging_styles").Inc()
|
sampleErrors.WithLabelValues("mixed_tagging_styles").Inc()
|
||||||
level.Debug(logger).Log("msg", "bad line: multiple tagging styles", "line", line)
|
logger.Debug("bad line: multiple tagging styles", "line", line)
|
||||||
return events
|
return events
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,7 +230,7 @@ func (p *Parser) LineToEvents(line string, sampleErrors prometheus.CounterVec, s
|
||||||
lineParts := strings.SplitN(elements[1], "|", 3)
|
lineParts := strings.SplitN(elements[1], "|", 3)
|
||||||
if len(lineParts) < 2 {
|
if len(lineParts) < 2 {
|
||||||
sampleErrors.WithLabelValues("not_enough_parts_after_colon").Inc()
|
sampleErrors.WithLabelValues("not_enough_parts_after_colon").Inc()
|
||||||
level.Debug(logger).Log("msg", "bad line: not enough '|'-delimited parts after first ':'", "line", line)
|
logger.Debug("bad line: not enough '|'-delimited parts after first ':'", "line", line)
|
||||||
return events
|
return events
|
||||||
}
|
}
|
||||||
if strings.Contains(lineParts[0], ":") {
|
if strings.Contains(lineParts[0], ":") {
|
||||||
|
@ -256,7 +255,7 @@ func (p *Parser) LineToEvents(line string, sampleErrors prometheus.CounterVec, s
|
||||||
samples = aggLines
|
samples = aggLines
|
||||||
} else {
|
} else {
|
||||||
sampleErrors.WithLabelValues("invalid_extended_aggregate_type").Inc()
|
sampleErrors.WithLabelValues("invalid_extended_aggregate_type").Inc()
|
||||||
level.Debug(logger).Log("msg", "bad line: invalid extended aggregate type", "line", line)
|
logger.Debug("bad line: invalid extended aggregate type", "line", line)
|
||||||
return events
|
return events
|
||||||
}
|
}
|
||||||
} else if usingDogStatsDTags {
|
} else if usingDogStatsDTags {
|
||||||
|
@ -272,7 +271,7 @@ samples:
|
||||||
components := strings.Split(sample, "|")
|
components := strings.Split(sample, "|")
|
||||||
if len(components) < 2 || len(components) > 4 {
|
if len(components) < 2 || len(components) > 4 {
|
||||||
sampleErrors.WithLabelValues("malformed_component").Inc()
|
sampleErrors.WithLabelValues("malformed_component").Inc()
|
||||||
level.Debug(logger).Log("msg", "bad component", "line", line)
|
logger.Debug("bad component", "line", line)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
valueStr, statType := components[0], components[1]
|
valueStr, statType := components[0], components[1]
|
||||||
|
@ -284,7 +283,7 @@ samples:
|
||||||
|
|
||||||
value, err := strconv.ParseFloat(valueStr, 64)
|
value, err := strconv.ParseFloat(valueStr, 64)
|
||||||
if err != nil {
|
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()
|
sampleErrors.WithLabelValues("malformed_value").Inc()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -293,7 +292,7 @@ samples:
|
||||||
if len(components) >= 3 {
|
if len(components) >= 3 {
|
||||||
for _, component := range components[2:] {
|
for _, component := range components[2:] {
|
||||||
if len(component) == 0 {
|
if len(component) == 0 {
|
||||||
level.Debug(logger).Log("msg", "Empty component", "line", line)
|
logger.Debug("Empty component", "line", line)
|
||||||
sampleErrors.WithLabelValues("malformed_component").Inc()
|
sampleErrors.WithLabelValues("malformed_component").Inc()
|
||||||
continue samples
|
continue samples
|
||||||
}
|
}
|
||||||
|
@ -305,7 +304,7 @@ samples:
|
||||||
|
|
||||||
samplingFactor, err := strconv.ParseFloat(component[1:], 64)
|
samplingFactor, err := strconv.ParseFloat(component[1:], 64)
|
||||||
if err != nil {
|
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()
|
sampleErrors.WithLabelValues("invalid_sample_factor").Inc()
|
||||||
}
|
}
|
||||||
if samplingFactor == 0 {
|
if samplingFactor == 0 {
|
||||||
|
@ -322,7 +321,7 @@ samples:
|
||||||
case '#':
|
case '#':
|
||||||
p.ParseDogStatsDTags(component[1:], labels, tagErrors, logger)
|
p.ParseDogStatsDTags(component[1:], labels, tagErrors, logger)
|
||||||
default:
|
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()
|
sampleErrors.WithLabelValues("invalid_sample_factor").Inc()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -336,7 +335,7 @@ samples:
|
||||||
for i := 0; i < multiplyEvents; i++ {
|
for i := 0; i < multiplyEvents; i++ {
|
||||||
event, err := buildEvent(statType, metric, value, relative, labels)
|
event, err := buildEvent(statType, metric, value, relative, labels)
|
||||||
if err != nil {
|
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()
|
sampleErrors.WithLabelValues("illegal_event").Inc()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,8 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/go-kit/log"
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"github.com/prometheus/common/promslog"
|
||||||
|
|
||||||
"github.com/prometheus/statsd_exporter/pkg/event"
|
"github.com/prometheus/statsd_exporter/pkg/event"
|
||||||
)
|
)
|
||||||
|
@ -49,7 +49,7 @@ var (
|
||||||
Help: "The number of errors parsing DogStatsD tags.",
|
Help: "The number of errors parsing DogStatsD tags.",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
nopLogger = log.NewNopLogger()
|
nopLogger = promslog.NewNopLogger()
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLineToEvents(t *testing.T) {
|
func TestLineToEvents(t *testing.T) {
|
||||||
|
|
|
@ -16,26 +16,25 @@ package listener
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"io"
|
"io"
|
||||||
|
"log/slog"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-kit/log"
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
|
||||||
"github.com/prometheus/statsd_exporter/pkg/event"
|
"github.com/prometheus/statsd_exporter/pkg/event"
|
||||||
"github.com/prometheus/statsd_exporter/pkg/level"
|
|
||||||
"github.com/prometheus/statsd_exporter/pkg/relay"
|
"github.com/prometheus/statsd_exporter/pkg/relay"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Parser interface {
|
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 {
|
type StatsDUDPListener struct {
|
||||||
Conn *net.UDPConn
|
Conn *net.UDPConn
|
||||||
EventHandler event.EventHandler
|
EventHandler event.EventHandler
|
||||||
Logger log.Logger
|
Logger *slog.Logger
|
||||||
LineParser Parser
|
LineParser Parser
|
||||||
UDPPackets prometheus.Counter
|
UDPPackets prometheus.Counter
|
||||||
UDPPacketDrops prometheus.Counter
|
UDPPacketDrops prometheus.Counter
|
||||||
|
@ -64,7 +63,7 @@ func (l *StatsDUDPListener) Listen() {
|
||||||
if strings.HasSuffix(err.Error(), "use of closed network connection") {
|
if strings.HasSuffix(err.Error(), "use of closed network connection") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
level.Error(l.Logger).Log("error", err)
|
l.Logger.Error("error reading from UDP connection", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +93,7 @@ func (l *StatsDUDPListener) ProcessUdpPacketQueue() {
|
||||||
func (l *StatsDUDPListener) HandlePacket(packet []byte) {
|
func (l *StatsDUDPListener) HandlePacket(packet []byte) {
|
||||||
lines := strings.Split(string(packet), "\n")
|
lines := strings.Split(string(packet), "\n")
|
||||||
for _, line := range lines {
|
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()
|
l.LinesReceived.Inc()
|
||||||
if l.Relay != nil && len(line) > 0 {
|
if l.Relay != nil && len(line) > 0 {
|
||||||
l.Relay.RelayLine(line)
|
l.Relay.RelayLine(line)
|
||||||
|
@ -106,7 +105,7 @@ func (l *StatsDUDPListener) HandlePacket(packet []byte) {
|
||||||
type StatsDTCPListener struct {
|
type StatsDTCPListener struct {
|
||||||
Conn *net.TCPListener
|
Conn *net.TCPListener
|
||||||
EventHandler event.EventHandler
|
EventHandler event.EventHandler
|
||||||
Logger log.Logger
|
Logger *slog.Logger
|
||||||
LineParser Parser
|
LineParser Parser
|
||||||
LinesReceived prometheus.Counter
|
LinesReceived prometheus.Counter
|
||||||
EventsFlushed prometheus.Counter
|
EventsFlushed prometheus.Counter
|
||||||
|
@ -133,7 +132,7 @@ func (l *StatsDTCPListener) Listen() {
|
||||||
if strings.HasSuffix(err.Error(), "use of closed network connection") {
|
if strings.HasSuffix(err.Error(), "use of closed network connection") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
level.Error(l.Logger).Log("msg", "AcceptTCP failed", "error", err)
|
l.Logger.Error("AcceptTCP failed", "error", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
go l.HandleConn(c)
|
go l.HandleConn(c)
|
||||||
|
@ -151,14 +150,14 @@ func (l *StatsDTCPListener) HandleConn(c *net.TCPConn) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != io.EOF {
|
if err != io.EOF {
|
||||||
l.TCPErrors.Inc()
|
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
|
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 {
|
if isPrefix {
|
||||||
l.TCPLineTooLong.Inc()
|
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
|
break
|
||||||
}
|
}
|
||||||
l.LinesReceived.Inc()
|
l.LinesReceived.Inc()
|
||||||
|
@ -172,7 +171,7 @@ func (l *StatsDTCPListener) HandleConn(c *net.TCPConn) {
|
||||||
type StatsDUnixgramListener struct {
|
type StatsDUnixgramListener struct {
|
||||||
Conn *net.UnixConn
|
Conn *net.UnixConn
|
||||||
EventHandler event.EventHandler
|
EventHandler event.EventHandler
|
||||||
Logger log.Logger
|
Logger *slog.Logger
|
||||||
LineParser Parser
|
LineParser Parser
|
||||||
UnixgramPackets prometheus.Counter
|
UnixgramPackets prometheus.Counter
|
||||||
LinesReceived prometheus.Counter
|
LinesReceived prometheus.Counter
|
||||||
|
@ -198,7 +197,7 @@ func (l *StatsDUnixgramListener) Listen() {
|
||||||
if strings.HasSuffix(err.Error(), "use of closed network connection") {
|
if strings.HasSuffix(err.Error(), "use of closed network connection") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
level.Error(l.Logger).Log(err)
|
l.Logger.Error("error reading from unixgram connection", "err", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
l.HandlePacket(buf[:n])
|
l.HandlePacket(buf[:n])
|
||||||
|
@ -209,7 +208,7 @@ func (l *StatsDUnixgramListener) HandlePacket(packet []byte) {
|
||||||
l.UnixgramPackets.Inc()
|
l.UnixgramPackets.Inc()
|
||||||
lines := strings.Split(string(packet), "\n")
|
lines := strings.Split(string(packet), "\n")
|
||||||
for _, line := range lines {
|
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()
|
l.LinesReceived.Inc()
|
||||||
if l.Relay != nil && len(line) > 0 {
|
if l.Relay != nil && len(line) > 0 {
|
||||||
l.Relay.RelayLine(line)
|
l.Relay.RelayLine(line)
|
||||||
|
|
|
@ -14,12 +14,9 @@
|
||||||
package fsm
|
package fsm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log/slog"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-kit/log"
|
|
||||||
|
|
||||||
"github.com/prometheus/statsd_exporter/pkg/level"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type mappingState struct {
|
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
|
// TestIfNeedBacktracking tests if backtrack is needed for given list of mappings
|
||||||
// and whether ordering is disabled.
|
// 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
|
backtrackingNeeded := false
|
||||||
// A has * in rules, but there's other transisitions at the same state,
|
// A has * in rules, but there's other transisitions at the same state,
|
||||||
// this makes A the cause of backtracking
|
// this makes A the cause of backtracking
|
||||||
|
@ -250,7 +247,7 @@ func TestIfNeedBacktracking(mappings []string, orderingDisabled bool, logger log
|
||||||
metricRe = strings.Replace(metricRe, "*", "([^.]*)", -1)
|
metricRe = strings.Replace(metricRe, "*", "([^.]*)", -1)
|
||||||
regex, err := regexp.Compile("^" + metricRe + "$")
|
regex, err := regexp.Compile("^" + metricRe + "$")
|
||||||
if err != nil {
|
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
|
// put into array no matter there's error or not, we will skip later if regex is nil
|
||||||
ruleREByLength[l] = append(ruleREByLength[l], regex)
|
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 {
|
if i2 != i1 && len(re1.FindStringSubmatchIndex(r2)) > 0 {
|
||||||
// log if we care about ordering and the superset occurs before
|
// log if we care about ordering and the superset occurs before
|
||||||
if !orderingDisabled && i1 < i2 {
|
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
|
currentRuleNeedBacktrack = false
|
||||||
}
|
}
|
||||||
|
@ -311,7 +308,7 @@ func TestIfNeedBacktracking(mappings []string, orderingDisabled bool, logger log
|
||||||
}
|
}
|
||||||
|
|
||||||
if currentRuleNeedBacktrack {
|
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
|
backtrackingNeeded = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,16 +15,16 @@ package mapper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-kit/log"
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"github.com/prometheus/common/promslog"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
|
||||||
"github.com/prometheus/statsd_exporter/pkg/level"
|
|
||||||
"github.com/prometheus/statsd_exporter/pkg/mapper/fsm"
|
"github.com/prometheus/statsd_exporter/pkg/mapper/fsm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ type MetricMapper struct {
|
||||||
|
|
||||||
MappingsCount prometheus.Gauge
|
MappingsCount prometheus.Gauge
|
||||||
|
|
||||||
Logger log.Logger
|
Logger *slog.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
type SummaryOptions struct {
|
type SummaryOptions struct {
|
||||||
|
@ -174,12 +174,12 @@ func (m *MetricMapper) InitFromYAMLString(fileContents string) error {
|
||||||
|
|
||||||
if currentMapping.LegacyQuantiles != nil &&
|
if currentMapping.LegacyQuantiles != nil &&
|
||||||
(currentMapping.SummaryOptions == nil || currentMapping.SummaryOptions.Quantiles != 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 &&
|
if currentMapping.LegacyBuckets != nil &&
|
||||||
(currentMapping.HistogramOptions == nil || currentMapping.HistogramOptions.Buckets != 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 &&
|
if currentMapping.SummaryOptions != nil &&
|
||||||
|
@ -242,7 +242,7 @@ func (m *MetricMapper) InitFromYAMLString(fileContents string) error {
|
||||||
defer m.mutex.Unlock()
|
defer m.mutex.Unlock()
|
||||||
|
|
||||||
if m.Logger == nil {
|
if m.Logger == nil {
|
||||||
m.Logger = log.NewNopLogger()
|
m.Logger = promslog.NewNopLogger()
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Defaults = n.Defaults
|
m.Defaults = n.Defaults
|
||||||
|
|
|
@ -18,7 +18,7 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"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/lru"
|
||||||
"github.com/prometheus/statsd_exporter/pkg/mappercache/randomreplacement"
|
"github.com/prometheus/statsd_exporter/pkg/mappercache/randomreplacement"
|
||||||
|
@ -245,7 +245,7 @@ mappings:
|
||||||
}
|
}
|
||||||
|
|
||||||
mapper := MetricMapper{
|
mapper := MetricMapper{
|
||||||
Logger: log.NewNopLogger(),
|
Logger: promslog.NewNopLogger(),
|
||||||
}
|
}
|
||||||
err := mapper.InitFromYAMLString(config)
|
err := mapper.InitFromYAMLString(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -16,24 +16,22 @@ package relay
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/prometheus/statsd_exporter/pkg/clock"
|
"github.com/prometheus/statsd_exporter/pkg/clock"
|
||||||
|
|
||||||
"github.com/go-kit/log"
|
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||||
"github.com/prometheus/statsd_exporter/pkg/level"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Relay struct {
|
type Relay struct {
|
||||||
addr *net.UDPAddr
|
addr *net.UDPAddr
|
||||||
bufferChannel chan []byte
|
bufferChannel chan []byte
|
||||||
conn *net.UDPConn
|
conn *net.UDPConn
|
||||||
logger log.Logger
|
logger *slog.Logger
|
||||||
packetLength uint
|
packetLength uint
|
||||||
|
|
||||||
packetsTotal prometheus.Counter
|
packetsTotal prometheus.Counter
|
||||||
|
@ -67,7 +65,7 @@ var (
|
||||||
|
|
||||||
// NewRelay creates a statsd UDP relay. It can be used to send copies of statsd raw
|
// NewRelay creates a statsd UDP relay. It can be used to send copies of statsd raw
|
||||||
// lines to a separate service.
|
// 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)
|
addr, err := net.ResolveUDPAddr("udp", target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to resolve target %s, err: %w", target, err)
|
return nil, fmt.Errorf("unable to resolve target %s, err: %w", target, err)
|
||||||
|
@ -110,24 +108,24 @@ func (r *Relay) relayOutput() {
|
||||||
case <-relayInterval.C:
|
case <-relayInterval.C:
|
||||||
err = r.sendPacket(buffer.Bytes())
|
err = r.sendPacket(buffer.Bytes())
|
||||||
if err != nil {
|
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
|
return
|
||||||
}
|
}
|
||||||
// Clear out the buffer.
|
// Clear out the buffer.
|
||||||
buffer.Reset()
|
buffer.Reset()
|
||||||
case b := <-r.bufferChannel:
|
case b := <-r.bufferChannel:
|
||||||
if uint(len(b)+buffer.Len()) > r.packetLength {
|
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())
|
err = r.sendPacket(buffer.Bytes())
|
||||||
if err != nil {
|
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
|
return
|
||||||
}
|
}
|
||||||
// Seed the new buffer with the new line.
|
// Seed the new buffer with the new line.
|
||||||
buffer.Reset()
|
buffer.Reset()
|
||||||
buffer.Write(b)
|
buffer.Write(b)
|
||||||
} else {
|
} 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)
|
buffer.Write(b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,10 +135,10 @@ func (r *Relay) relayOutput() {
|
||||||
// sendPacket sends a single relay line to the destination target.
|
// sendPacket sends a single relay line to the destination target.
|
||||||
func (r *Relay) sendPacket(buf []byte) error {
|
func (r *Relay) sendPacket(buf []byte) error {
|
||||||
if len(buf) == 0 {
|
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
|
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)
|
_, err := r.conn.WriteToUDP(buf, r.addr)
|
||||||
r.packetsTotal.Inc()
|
r.packetsTotal.Inc()
|
||||||
return err
|
return err
|
||||||
|
@ -150,15 +148,15 @@ func (r *Relay) sendPacket(buf []byte) error {
|
||||||
func (r *Relay) RelayLine(l string) {
|
func (r *Relay) RelayLine(l string) {
|
||||||
lineLength := uint(len(l))
|
lineLength := uint(len(l))
|
||||||
if lineLength == 0 {
|
if lineLength == 0 {
|
||||||
level.Debug(r.logger).Log("msg", "Empty line, not relaying")
|
r.logger.Debug("Empty line, not relaying")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if lineLength > r.packetLength-1 {
|
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()
|
r.longLinesTotal.Inc()
|
||||||
return
|
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") {
|
if !strings.HasSuffix(l, "\n") {
|
||||||
l = l + "\n"
|
l = l + "\n"
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,9 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-kit/log"
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
dto "github.com/prometheus/client_model/go"
|
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/clock"
|
||||||
"github.com/stvp/go-udp-testing"
|
"github.com/stvp/go-udp-testing"
|
||||||
)
|
)
|
||||||
|
@ -54,7 +54,7 @@ func TestRelay_RelayLine(t *testing.T) {
|
||||||
}
|
}
|
||||||
clock.ClockInstance.Instant = time.Unix(0, 0)
|
clock.ClockInstance.Instant = time.Unix(0, 0)
|
||||||
|
|
||||||
logger := log.NewNopLogger()
|
logger := promslog.NewNopLogger()
|
||||||
r, err := NewRelay(
|
r, err := NewRelay(
|
||||||
logger,
|
logger,
|
||||||
"localhost:1160",
|
"localhost:1160",
|
||||||
|
|
Loading…
Reference in a new issue