Skip to content

Commit

Permalink
chore!: adopt log/slog, drop go-kit/log
Browse files Browse the repository at this point in the history
Requires: prometheus/common#697

This PR includes:

- linter updates to enable sloglint linter
- Go dep updates for prometheus/{client_golang,common,exporter-toolkit}
  libs
- refactorings to adopt log/slog in favor of go-kit/log

The bulk of this PR was automated by the following script which is being
used to aid in converting the various exporters/projects to use slog:

https://gist.github.com/tjhop/49f96fb7ebbe55b12deee0b0312d8434

Builds and passes tests locally with go workspaces and up-to-date main
branch of prometheus/common.

Signed-off-by: TJ Hoplock <t.hoplock@gmail.com>
  • Loading branch information
tjhop committed Sep 29, 2024
1 parent 49e616d commit 21171cf
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 59 deletions.
28 changes: 13 additions & 15 deletions cmd/memcached_exporter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@ import (
"strings"

"github.com/alecthomas/kingpin/v2"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/collectors"
versioncollector "github.com/prometheus/client_golang/prometheus/collectors/version"
"github.com/prometheus/client_golang/prometheus/promhttp"
promconfig "github.com/prometheus/common/config"
"github.com/prometheus/common/promlog"
"github.com/prometheus/common/promlog/flag"
"github.com/prometheus/common/promslog"
"github.com/prometheus/common/promslog/flag"
"github.com/prometheus/common/version"
"github.com/prometheus/exporter-toolkit/web"
webflag "github.com/prometheus/exporter-toolkit/web/kingpinflag"
Expand All @@ -53,15 +52,15 @@ func main() {
scrapePath = kingpin.Flag("web.scrape-path", "Path under which to receive scrape requests.").Default("/scrape").String()
)

promlogConfig := &promlog.Config{}
flag.AddFlags(kingpin.CommandLine, promlogConfig)
promslogConfig := &promslog.Config{}
flag.AddFlags(kingpin.CommandLine, promslogConfig)
kingpin.HelpFlag.Short('h')
kingpin.Version(version.Print("memcached_exporter"))
kingpin.Parse()
logger := promlog.New(promlogConfig)
logger := promslog.New(promslogConfig)

level.Info(logger).Log("msg", "Starting memcached_exporter", "version", version.Info())
level.Info(logger).Log("msg", "Build context", "context", version.BuildContext())
logger.Info("Starting memcached_exporter", "version", version.Info())
logger.Info("Build context", "context", version.BuildContext())

var (
tlsConfig *tls.Config
Expand All @@ -72,11 +71,10 @@ func main() {
*serverName, _, err = net.SplitHostPort(*address)
if err != nil {
if strings.Contains(*address, "/") {
level.Error(logger).Log("msg",
"If --memcached.tls.enable is set and --memcached.address is a unix socket, "+
"you must also specify --memcached.tls.server-name")
logger.Error("If --memcached.tls.enable is set and --memcached.address is a unix socket, " +
"you must also specify --memcached.tls.server-name")
} else {
level.Error(logger).Log("msg", "Error parsing memcached address", "err", err)
logger.Error("Error parsing memcached address", "err", err)
}
os.Exit(1)
}
Expand All @@ -89,7 +87,7 @@ func main() {
InsecureSkipVerify: *insecureSkipVerify,
})
if err != nil {
level.Error(logger).Log("msg", "Failed to create TLS config", "err", err)
logger.Error("Failed to create TLS config", "err", err)
os.Exit(1)
}
}
Expand Down Expand Up @@ -126,15 +124,15 @@ func main() {
}
landingPage, err := web.NewLandingPage(landingConfig)
if err != nil {
level.Error(logger).Log("err", err)
logger.Error("Error creating landing page", "err", err)
os.Exit(1)
}
http.Handle("/", landingPage)
}

srv := &http.Server{}
if err := web.ListenAndServe(srv, webConfig, logger); err != nil {
level.Error(logger).Log("msg", "Error running HTTP server", "err", err)
logger.Error("Error running HTTP server", "err", err)
os.Exit(1)
}
}
2 changes: 0 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ go 1.23.0

require (
github.com/alecthomas/kingpin/v2 v2.4.0
github.com/go-kit/log v0.2.1
github.com/grobie/gomemcache v0.0.0-20230213081705-239240bbc445
github.com/prometheus/client_golang v1.20.4
github.com/prometheus/common v0.59.1
Expand All @@ -16,7 +15,6 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/jpillora/backoff v1.0.0 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/mdlayher/socket v0.4.1 // indirect
Expand Down
4 changes: 0 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
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/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
Expand Down
45 changes: 22 additions & 23 deletions pkg/exporter/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@ package exporter
import (
"crypto/tls"
"errors"
"log/slog"
"net"
"strconv"
"strings"
"time"

"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/grobie/gomemcache/memcache"
"github.com/prometheus/client_golang/prometheus"
)
Expand All @@ -39,7 +38,7 @@ var errKeyNotFound = errors.New("key not found")
type Exporter struct {
address string
timeout time.Duration
logger log.Logger
logger *slog.Logger
tlsConfig *tls.Config

up *prometheus.Desc
Expand Down Expand Up @@ -133,7 +132,7 @@ type Exporter struct {
}

// New returns an initialized exporter.
func New(server string, timeout time.Duration, logger log.Logger, tlsConfig *tls.Config) *Exporter {
func New(server string, timeout time.Duration, logger *slog.Logger, tlsConfig *tls.Config) *Exporter {
return &Exporter{
address: server,
timeout: timeout,
Expand Down Expand Up @@ -770,7 +769,7 @@ func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
c, err := memcache.New(e.address)
if err != nil {
ch <- prometheus.MustNewConstMetric(e.up, prometheus.GaugeValue, 0)
level.Error(e.logger).Log("msg", "Failed to connect to memcached", "err", err)
e.logger.Error("Failed to connect to memcached", "err", err)
return
}
c.Timeout = e.timeout
Expand All @@ -779,12 +778,12 @@ func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
up := float64(1)
stats, err := c.Stats()
if err != nil {
level.Error(e.logger).Log("msg", "Failed to collect stats from memcached", "err", err)
e.logger.Error("Failed to collect stats from memcached", "err", err)
up = 0
}
statsSettings, err := c.StatsSettings()
if err != nil {
level.Error(e.logger).Log("msg", "Could not query stats settings", "err", err)
e.logger.Error("Could not query stats settings", "err", err)
up = 0
}

Expand Down Expand Up @@ -857,11 +856,11 @@ func (e *Exporter) parseStats(ch chan<- prometheus.Metric, stats map[net.Addr]me
if cas, casErr := sum(s, "cas_misses", "cas_hits", "cas_badval"); casErr == nil {
ch <- prometheus.MustNewConstMetric(e.commands, prometheus.CounterValue, setCmd-cas, "set", "hit")
} else {
level.Error(e.logger).Log("msg", "Failed to parse cas", "err", casErr)
e.logger.Error("Failed to parse cas", "err", casErr)
parseError = casErr
}
} else {
level.Error(e.logger).Log("msg", "Failed to parse set", "err", err)
e.logger.Error("Failed to parse set", "err", err)
parseError = err
}

Expand Down Expand Up @@ -973,11 +972,11 @@ func (e *Exporter) parseStats(ch chan<- prometheus.Metric, stats map[net.Addr]me
if slabCas, slabCasErr := sum(v, "cas_hits", "cas_badval"); slabCasErr == nil {
ch <- prometheus.MustNewConstMetric(e.slabsCommands, prometheus.CounterValue, slabSetCmd-slabCas, slab, "set", "hit")
} else {
level.Error(e.logger).Log("msg", "Failed to parse cas", "err", slabCasErr)
e.logger.Error("Failed to parse cas", "err", slabCasErr)
parseError = slabCasErr
}
} else {
level.Error(e.logger).Log("msg", "Failed to parse set", "err", err)
e.logger.Error("Failed to parse set", "err", err)
parseError = err
}

Expand Down Expand Up @@ -1038,7 +1037,7 @@ func (e *Exporter) parseTimevalAndNewMetric(ch chan<- prometheus.Metric, desc *p
return e.extractValueAndNewMetric(ch, desc, valueType, parseTimeval, stats, key, labelValues...)
}

func (e *Exporter) extractValueAndNewMetric(ch chan<- prometheus.Metric, desc *prometheus.Desc, valueType prometheus.ValueType, f func(map[string]string, string, log.Logger) (float64, error), stats map[string]string, key string, labelValues ...string) error {
func (e *Exporter) extractValueAndNewMetric(ch chan<- prometheus.Metric, desc *prometheus.Desc, valueType prometheus.ValueType, f func(map[string]string, string, *slog.Logger) (float64, error), stats map[string]string, key string, labelValues ...string) error {
v, err := f(stats, key, e.logger)
if err == errKeyNotFound {
return nil
Expand All @@ -1051,25 +1050,25 @@ func (e *Exporter) extractValueAndNewMetric(ch chan<- prometheus.Metric, desc *p
return nil
}

func parse(stats map[string]string, key string, logger log.Logger) (float64, error) {
func parse(stats map[string]string, key string, logger *slog.Logger) (float64, error) {
value, ok := stats[key]
if !ok {
level.Debug(logger).Log("msg", "Key not found", "key", key)
logger.Debug("Key not found", "key", key)
return 0, errKeyNotFound
}

v, err := strconv.ParseFloat(value, 64)
if err != nil {
level.Error(logger).Log("msg", "Failed to parse", "key", key, "value", value, "err", err)
logger.Error("Failed to parse", "key", key, "value", value, "err", err)
return 0, err
}
return v, nil
}

func parseBool(stats map[string]string, key string, logger log.Logger) (float64, error) {
func parseBool(stats map[string]string, key string, logger *slog.Logger) (float64, error) {
value, ok := stats[key]
if !ok {
level.Debug(logger).Log("msg", "Key not found", "key", key)
logger.Debug("Key not found", "key", key)
return 0, errKeyNotFound
}

Expand All @@ -1079,33 +1078,33 @@ func parseBool(stats map[string]string, key string, logger log.Logger) (float64,
case "no":
return 0, nil
default:
level.Error(logger).Log("msg", "Failed to parse", "key", key, "value", value)
logger.Error("Failed to parse", "key", key, "value", value)
return 0, errors.New("failed parse a bool value")
}
}

func parseTimeval(stats map[string]string, key string, logger log.Logger) (float64, error) {
func parseTimeval(stats map[string]string, key string, logger *slog.Logger) (float64, error) {
value, ok := stats[key]
if !ok {
level.Debug(logger).Log("msg", "Key not found", "key", key)
logger.Debug("Key not found", "key", key)
return 0, errKeyNotFound
}
values := strings.Split(value, ".")

if len(values) != 2 {
level.Error(logger).Log("msg", "Failed to parse", "key", key, "value", value)
logger.Error("Failed to parse", "key", key, "value", value)
return 0, errors.New("failed parse a timeval value")
}

seconds, err := strconv.ParseFloat(values[0], 64)
if err != nil {
level.Error(logger).Log("msg", "Failed to parse", "key", key, "value", value, "err", err)
logger.Error("Failed to parse", "key", key, "value", value, "err", err)
return 0, errors.New("failed parse a timeval value")
}

microseconds, err := strconv.ParseFloat(values[1], 64)
if err != nil {
level.Error(logger).Log("msg", "Failed to parse", "key", key, "value", value, "err", err)
logger.Error("Failed to parse", "key", key, "value", value, "err", err)
return 0, errors.New("failed parse a timeval value")
}

Expand Down
10 changes: 5 additions & 5 deletions pkg/exporter/exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import (
"testing"
"time"

"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/promslog"
)

func TestParseStatsSettings(t *testing.T) {
Expand All @@ -46,7 +46,7 @@ func TestParseStatsSettings(t *testing.T) {
},
}
ch := make(chan prometheus.Metric, 100)
e := New("", 100*time.Millisecond, log.NewNopLogger(), nil)
e := New("", 100*time.Millisecond, promslog.NewNopLogger(), nil)
if err := e.parseStatsSettings(ch, statsSettings); err != nil {
t.Errorf("expect return error, error: %v", err)
}
Expand All @@ -69,7 +69,7 @@ func TestParseStatsSettings(t *testing.T) {
},
}
ch := make(chan prometheus.Metric, 100)
e := New("", 100*time.Millisecond, log.NewNopLogger(), nil)
e := New("", 100*time.Millisecond, promslog.NewNopLogger(), nil)
if err := e.parseStatsSettings(ch, statsSettings); err == nil {
t.Error("expect return error but not")
}
Expand All @@ -79,15 +79,15 @@ func TestParseStatsSettings(t *testing.T) {
func TestParseTimeval(t *testing.T) {
t.Run("Success", func(t *testing.T) {
t.Parallel()
_, err := parseTimeval(map[string]string{"rusage_system": "3.5"}, "rusage_system", log.NewNopLogger())
_, err := parseTimeval(map[string]string{"rusage_system": "3.5"}, "rusage_system", promslog.NewNopLogger())
if err != nil {
t.Errorf("expect return error, error: %v", err)
}
})

t.Run("Failure", func(t *testing.T) {
t.Parallel()
_, err := parseTimeval(map[string]string{"rusage_system": "35"}, "rusage_system", log.NewNopLogger())
_, err := parseTimeval(map[string]string{"rusage_system": "35"}, "rusage_system", promslog.NewNopLogger())
if err == nil {
t.Error("expect return error but not")
}
Expand Down
13 changes: 6 additions & 7 deletions scraper/scraper.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,26 @@ package scraper

import (
"crypto/tls"
"log/slog"
"net/http"
"time"

"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/prometheus/memcached_exporter/pkg/exporter"
)

type Scraper struct {
logger log.Logger
logger *slog.Logger
timeout time.Duration
tlsConfig *tls.Config

scrapeCount prometheus.Counter
scrapeErrors prometheus.Counter
}

func New(timeout time.Duration, logger log.Logger, tlsConfig *tls.Config) *Scraper {
level.Debug(logger).Log("msg", "Started scrapper")
func New(timeout time.Duration, logger *slog.Logger, tlsConfig *tls.Config) *Scraper {
logger.Debug("Started scrapper")
return &Scraper{
logger: logger,
timeout: timeout,
Expand All @@ -54,12 +53,12 @@ func New(timeout time.Duration, logger log.Logger, tlsConfig *tls.Config) *Scrap
func (s *Scraper) Handler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
target := r.URL.Query().Get("target")
level.Debug(s.logger).Log("msg", "scrapping memcached", "target", target)
s.logger.Debug("scrapping memcached", "target", target)
s.scrapeCount.Inc()

if target == "" {
errorStr := "'target' parameter must be specified"
level.Warn(s.logger).Log("msg", errorStr)
s.logger.Warn(errorStr)
http.Error(w, errorStr, http.StatusBadRequest)
s.scrapeErrors.Inc()
return
Expand Down
6 changes: 3 additions & 3 deletions scraper/scraper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ import (
"testing"
"time"

"github.com/go-kit/log"
"github.com/prometheus/common/promslog"
)

func TestHandler(t *testing.T) {
t.Run("Success", func(t *testing.T) {
t.Parallel()

s := New(1*time.Second, log.NewNopLogger(), nil)
s := New(1*time.Second, promslog.NewNopLogger(), nil)

req, err := http.NewRequest("GET", "/?target=127.0.0.1:11211", nil)

Expand Down Expand Up @@ -55,7 +55,7 @@ func TestHandler(t *testing.T) {
t.Run("No target", func(t *testing.T) {
t.Parallel()

s := New(1*time.Second, log.NewNopLogger(), nil)
s := New(1*time.Second, promslog.NewNopLogger(), nil)

req, err := http.NewRequest("GET", "/", nil)

Expand Down

0 comments on commit 21171cf

Please sign in to comment.