From 319537f42c930fc02a61b88bda1ea172a399c7b6 Mon Sep 17 00:00:00 2001 From: Dave Henderson Date: Thu, 30 May 2024 21:05:08 -0400 Subject: [PATCH] feat(logging): Switch from go-kit/log to log/slog (#181) Signed-off-by: Dave Henderson --- collector.go | 30 ++++---------- collector_cm.go | 22 +++++------ collector_router.go | 14 +++---- collector_wifi.go | 12 +++--- go.mod | 6 +-- go.sum | 13 +++--- main.go | 96 +++++++++++++++++++++++++++++---------------- 7 files changed, 100 insertions(+), 93 deletions(-) diff --git a/collector.go b/collector.go index 0e1d212..a2c79c7 100644 --- a/collector.go +++ b/collector.go @@ -2,17 +2,14 @@ package main import ( "context" - "fmt" + "log/slog" - "github.com/go-kit/log" - "github.com/go-kit/log/level" hitron "github.com/hairyhenderson/hitron_coda" "github.com/prometheus/client_golang/prometheus" ) type collector struct { ctx context.Context - logger log.Logger client *hitron.CableModem rc routerCollector cc cmCollector @@ -23,22 +20,11 @@ type collector struct { config config } -type debugLogAdapter struct { - log.Logger -} - -func (l debugLogAdapter) Logf(format string, args ...interface{}) { - l.Log("msg", fmt.Sprintf(format, args...)) -} - -func newCollector(ctx context.Context, conf config, logger log.Logger) *collector { - debugLogger := debugLogAdapter{level.Debug(logger)} - ctx = hitron.ContextWithDebugLogger(ctx, debugLogger) - - c := &collector{ctx: ctx, config: conf, logger: logger} - c.rc = newRouterCollector(ctx, logger, c.getClient) - c.cc = newCMCollector(ctx, logger, c.getClient) - c.wc = newWiFiCollector(ctx, logger, c.getClient) +func newCollector(ctx context.Context, conf config) *collector { + c := &collector{ctx: ctx, config: conf} + c.rc = newRouterCollector(ctx, c.getClient) + c.cc = newCMCollector(ctx, c.getClient) + c.wc = newWiFiCollector(ctx, c.getClient) c.up = prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: metricsNS, @@ -72,7 +58,7 @@ func (c *collector) Collect(ch chan<- prometheus.Metric) { c.client, err = hitron.New(c.config.Host, c.config.Username, c.config.Password) if err != nil { - level.Error(c.logger).Log("msg", "Error scraping target", "err", err) + slog.ErrorContext(c.ctx, "Error creating client", "err", err) exporterClientErrors.Inc() return @@ -80,7 +66,7 @@ func (c *collector) Collect(ch chan<- prometheus.Metric) { err = c.client.Login(c.ctx) if err != nil { - level.Error(c.logger).Log("msg", "Error logging in", "err", err) + slog.ErrorContext(c.ctx, "Error logging in", "err", err) exporterClientErrors.Inc() return diff --git a/collector_cm.go b/collector_cm.go index a9e0361..a4de55a 100644 --- a/collector_cm.go +++ b/collector_cm.go @@ -3,10 +3,9 @@ package main import ( "context" "fmt" + "log/slog" "strconv" - "github.com/go-kit/log" - "github.com/go-kit/log/level" hitron "github.com/hairyhenderson/hitron_coda" "github.com/prometheus/client_golang/prometheus" ) @@ -15,7 +14,6 @@ import ( type cmCollector struct { ctx context.Context client func() *hitron.CableModem - logger log.Logger sysInfo struct { usDataRate prometheus.Gauge dsDataRate prometheus.Gauge @@ -49,8 +47,8 @@ type cmCollector struct { } //nolint:funlen -func newCMCollector(ctx context.Context, logger log.Logger, clientProvider func() *hitron.CableModem) cmCollector { - c := cmCollector{ctx: ctx, logger: logger, client: clientProvider} +func newCMCollector(ctx context.Context, clientProvider func() *hitron.CableModem) cmCollector { + c := cmCollector{ctx: ctx, client: clientProvider} sub := "cm" @@ -220,7 +218,7 @@ func (c cmCollector) Collect(ch chan<- prometheus.Metric) { client := c.client() if client == nil { err := fmt.Errorf("client not initialized: %v", client) - level.Error(c.logger).Log("msg", "Error scraping target", "err", err) + slog.ErrorContext(c.ctx, "Error scraping target", slog.Any("err", err)) exporterClientErrors.Inc() return @@ -236,7 +234,7 @@ func (c cmCollector) Collect(ch chan<- prometheus.Metric) { func (c cmCollector) collectVersionInfo(ch chan<- prometheus.Metric, client *hitron.CableModem) { vi, err := client.CMVersion(c.ctx) if err != nil { - level.Error(c.logger).Log("msg", "Error scraping CMVersion", "err", err) + slog.ErrorContext(c.ctx, "Error scraping CMVersion", slog.Any("err", err)) exporterRequestErrors.Inc() return @@ -258,7 +256,7 @@ func (c cmCollector) collectVersionInfo(ch chan<- prometheus.Metric, client *hit func (c cmCollector) collectSysInfo(ch chan<- prometheus.Metric, client *hitron.CableModem) { si, err := client.CMSysInfo(c.ctx) if err != nil { - level.Error(c.logger).Log("msg", "Error scraping CMSysInfo", "err", err) + slog.ErrorContext(c.ctx, "Error scraping CMSysInfo", slog.Any("err", err)) exporterRequestErrors.Inc() return @@ -283,7 +281,7 @@ func (c cmCollector) collectSysInfo(ch chan<- prometheus.Metric, client *hitron. func (c cmCollector) collectDsInfo(ch chan<- prometheus.Metric, client *hitron.CableModem) { dsinfo, err := client.CMDsInfo(c.ctx) if err != nil { - level.Error(c.logger).Log("msg", "Error scraping CMDsInfo", "err", err) + slog.ErrorContext(c.ctx, "Error scraping CMDsInfo", slog.Any("err", err)) exporterRequestErrors.Inc() return @@ -315,7 +313,7 @@ func (c cmCollector) collectDsInfo(ch chan<- prometheus.Metric, client *hitron.C func (c cmCollector) collectUsInfo(ch chan<- prometheus.Metric, client *hitron.CableModem) { usinfo, err := client.CMUsInfo(c.ctx) if err != nil { - level.Error(c.logger).Log("msg", "Error scraping CMUsInfo", "err", err) + slog.ErrorContext(c.ctx, "Error scraping CMUsInfo", slog.Any("err", err)) exporterRequestErrors.Inc() return @@ -343,7 +341,7 @@ func (c cmCollector) collectUsInfo(ch chan<- prometheus.Metric, client *hitron.C func (c cmCollector) collectOfdm(ch chan<- prometheus.Metric, client *hitron.CableModem) { usofdm, err := client.CMUsOfdm(c.ctx) if err != nil { - level.Error(c.logger).Log("msg", "Error scraping CMUsOfdm", "err", err) + slog.ErrorContext(c.ctx, "Error scraping CMUsOfdm", slog.Any("err", err)) exporterRequestErrors.Inc() } else { for _, channel := range usofdm.Channels { @@ -369,7 +367,7 @@ func (c cmCollector) collectOfdm(ch chan<- prometheus.Metric, client *hitron.Cab dsofdm, err := client.CMDsOfdm(c.ctx) if err != nil { - level.Error(c.logger).Log("msg", "Error scraping CMDsOfdm", "err", err) + slog.ErrorContext(c.ctx, "Error scraping CMDsOfdm", slog.Any("err", err)) exporterRequestErrors.Inc() } else { for _, receiver := range dsofdm.Receivers { diff --git a/collector_router.go b/collector_router.go index 29bdcd5..e9d99aa 100644 --- a/collector_router.go +++ b/collector_router.go @@ -3,9 +3,8 @@ package main import ( "context" "fmt" + "log/slog" - "github.com/go-kit/log" - "github.com/go-kit/log/level" hitron "github.com/hairyhenderson/hitron_coda" "github.com/prometheus/client_golang/prometheus" ) @@ -14,7 +13,6 @@ import ( type routerCollector struct { ctx context.Context client func() *hitron.CableModem - logger log.Logger sysInfo struct { systemTimeSeconds prometheus.Gauge lanReceiveBytesTotal *prometheus.CounterVec @@ -30,8 +28,8 @@ type routerCollector struct { } //nolint:funlen -func newRouterCollector(ctx context.Context, logger log.Logger, clientProvider func() *hitron.CableModem) routerCollector { - c := routerCollector{ctx: ctx, logger: logger, client: clientProvider} +func newRouterCollector(ctx context.Context, clientProvider func() *hitron.CableModem) routerCollector { + c := routerCollector{ctx: ctx, client: clientProvider} sub := "router" @@ -112,7 +110,7 @@ func (c routerCollector) Collect(ch chan<- prometheus.Metric) { client := c.client() if client == nil { err := fmt.Errorf("client not initialized: %v", client) - level.Error(c.logger).Log("msg", "Error scraping target", "err", err) + slog.ErrorContext(c.ctx, "Error scraping target", "err", err) exporterClientErrors.Inc() return @@ -120,7 +118,7 @@ func (c routerCollector) Collect(ch chan<- prometheus.Metric) { si, err := client.RouterSysInfo(c.ctx) if err != nil { - level.Error(c.logger).Log("msg", "Error scraping RouterSysInfo", "err", err) + slog.ErrorContext(c.ctx, "Error scraping RouterSysInfo", "err", err) exporterRequestErrors.Inc() } else { c.sysInfo.systemTimeSeconds.Set(float64(si.SystemTime.Unix())) @@ -153,7 +151,7 @@ func (c routerCollector) Collect(ch chan<- prometheus.Metric) { loc, err := client.RouterLocation(c.ctx) if err != nil { - level.Error(c.logger).Log("msg", "Error scraping RouterLocation", "err", err) + slog.ErrorContext(c.ctx, "Error scraping RouterLocation", "err", err) exporterRequestErrors.Inc() } else { c.sysInfo.info.With(routerSysInfoLabels(si, loc)).Set(1) diff --git a/collector_wifi.go b/collector_wifi.go index 9e2842c..7a1a9f8 100644 --- a/collector_wifi.go +++ b/collector_wifi.go @@ -3,9 +3,8 @@ package main import ( "context" "fmt" + "log/slog" - "github.com/go-kit/log" - "github.com/go-kit/log/level" hitron "github.com/hairyhenderson/hitron_coda" "github.com/prometheus/client_golang/prometheus" ) @@ -14,7 +13,6 @@ import ( type wifiCollector struct { ctx context.Context client func() *hitron.CableModem - logger log.Logger clientStats struct { rssi *prometheus.GaugeVec @@ -23,8 +21,8 @@ type wifiCollector struct { } } -func newWiFiCollector(ctx context.Context, logger log.Logger, clientProvider func() *hitron.CableModem) wifiCollector { - c := wifiCollector{ctx: ctx, logger: logger, client: clientProvider} +func newWiFiCollector(ctx context.Context, clientProvider func() *hitron.CableModem) wifiCollector { + c := wifiCollector{ctx: ctx, client: clientProvider} sub := "wifi" @@ -63,7 +61,7 @@ func (c wifiCollector) Collect(ch chan<- prometheus.Metric) { client := c.client() if client == nil { err := fmt.Errorf("client not initialized: %v", client) - level.Error(c.logger).Log("msg", "Error scraping target", "err", err) + slog.ErrorContext(c.ctx, "Error scraping target", "err", err) exporterClientErrors.Inc() return @@ -71,7 +69,7 @@ func (c wifiCollector) Collect(ch chan<- prometheus.Metric) { wc, err := client.WiFiClient(c.ctx) if err != nil { - level.Error(c.logger).Log("msg", "Error scraping WiFiClient", "err", err) + slog.ErrorContext(c.ctx, "Error scraping WiFiClient", "err", err) exporterRequestErrors.Inc() return diff --git a/go.mod b/go.mod index 88ea046..a3eab9f 100644 --- a/go.mod +++ b/go.mod @@ -4,10 +4,8 @@ go 1.22.3 require ( github.com/alecthomas/kingpin/v2 v2.4.0 - github.com/go-kit/log v0.2.1 - github.com/hairyhenderson/hitron_coda v0.1.1 + github.com/hairyhenderson/hitron_coda v0.2.0 github.com/prometheus/client_golang v1.19.1 - github.com/prometheus/common v0.53.0 github.com/stretchr/testify v1.9.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -17,10 +15,10 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/kr/text v0.2.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.0 // indirect + github.com/prometheus/common v0.53.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect golang.org/x/sys v0.18.0 // indirect diff --git a/go.sum b/go.sum index 4e0926a..6e4a434 100644 --- a/go.sum +++ b/go.sum @@ -10,14 +10,12 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 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/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/hairyhenderson/hitron_coda v0.1.1 h1:8AKT/t9iTNGYFMxXkJt1NHnVmhl/42YFCulHHfrpiJ0= -github.com/hairyhenderson/hitron_coda v0.1.1/go.mod h1:D9tCPDr43YjCLLSFlq4fLstxJ96TXDf7gKARmH04WKk= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/hairyhenderson/hitron_coda v0.2.0 h1:FSF1T+3kNNsXmWMnfRL00gkR9/eOXvXIejS060CQl1A= +github.com/hairyhenderson/hitron_coda v0.2.0/go.mod h1:EBtf1/EpqRdabuFKLl5G8HQW+L3NmibWPgeetpGHGUo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -31,6 +29,7 @@ github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3 github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= @@ -45,7 +44,7 @@ google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGm google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 5dcca4e..9f59618 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "log/slog" "net/http" "net/http/pprof" "os" @@ -11,27 +12,20 @@ import ( _ "time/tzdata" "github.com/alecthomas/kingpin/v2" - "github.com/go-kit/log" - "github.com/go-kit/log/level" "github.com/hairyhenderson/hitron_coda_exporter/internal/version" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" - "github.com/prometheus/common/promlog" - "github.com/prometheus/common/promlog/flag" ) var ( - configFile = kingpin.Flag("config.file", "Path to configuration file.").Default("hitron_coda.yml").String() - listenAddress = kingpin.Flag("web.listen-address", "Address to listen on for web interface and telemetry.").Default(":9780").String() - sc = &safeConfig{ C: &config{}, } reloadCh chan chan error ) -func handler(w http.ResponseWriter, r *http.Request, logger log.Logger) { - level.Debug(logger).Log("msg", "Starting scrape") +func handler(w http.ResponseWriter, r *http.Request) { + slog.DebugContext(r.Context(), "Starting scrape") start := time.Now() @@ -40,7 +34,7 @@ func handler(w http.ResponseWriter, r *http.Request, logger log.Logger) { sc.RUnlock() registry := prometheus.NewRegistry() - collector := newCollector(r.Context(), conf, logger) + collector := newCollector(r.Context(), conf) registry.MustRegister(collector) // Delegate http serving to Prometheus client library, which will call collector.Collect. @@ -51,10 +45,10 @@ func handler(w http.ResponseWriter, r *http.Request, logger log.Logger) { exporterDurationSummary.Observe(duration) exporterDuration.Observe(duration) - level.Debug(logger).Log("msg", "Finished scrape", "duration_seconds", duration) + slog.DebugContext(r.Context(), "Finished scrape", slog.Float64("duration_seconds", duration)) } -func handleHUP(logger log.Logger) { +func handleHUP(configFile string) { hup := make(chan os.Signal, 1) signal.Notify(hup, syscall.SIGHUP) @@ -64,17 +58,17 @@ func handleHUP(logger log.Logger) { for { select { case <-hup: - if err := sc.ReloadConfig(*configFile); err != nil { - level.Error(logger).Log("msg", "Error reloading config", "err", err) + if err := sc.ReloadConfig(configFile); err != nil { + slog.Error("Error reloading config", "err", err) } else { - level.Info(logger).Log("msg", "Loaded config file") + slog.Info("Loaded config file") } case rc := <-reloadCh: - if err := sc.ReloadConfig(*configFile); err != nil { - level.Error(logger).Log("msg", "Error reloading config", "err", err) + if err := sc.ReloadConfig(configFile); err != nil { + slog.Error("Error reloading config", "err", err) rc <- err } else { - level.Info(logger).Log("msg", "Loaded config file") + slog.Info("Loaded config file") rc <- nil } } @@ -82,17 +76,17 @@ func handleHUP(logger log.Logger) { }() } -func initRoutes(logger log.Logger) http.Handler { +func initRoutes() http.Handler { mux := http.NewServeMux() mux.Handle("/metrics", promhttp.Handler()) // Endpoint to do scrapes. mux.HandleFunc("/scrape", func(w http.ResponseWriter, r *http.Request) { - handler(w, r, logger) + handler(w, r) }) mux.HandleFunc("/-/reload", func(w http.ResponseWriter, r *http.Request) { switch r.Method { case "POST": - level.Debug(logger).Log("msg", "Reloading config from HTTP endpoint") + slog.DebugContext(r.Context(), "Reloading config from HTTP endpoint") rc := make(chan error) reloadCh <- rc @@ -145,45 +139,81 @@ func main() { defer func() { os.Exit(exitCode) }() - promlogConfig := &promlog.Config{} - flag.AddFlags(kingpin.CommandLine, promlogConfig) + level := "info" + format := "logfmt" + configFile := "hitron_coda.yml" + listenAddress := ":9780" + kingpin.HelpFlag.Short('h') kingpin.Version(version.Version) kingpin.CommandLine.VersionFlag.Short('v') - kingpin.Parse() + kingpin.Flag("log.level", "log level (debug, info, warn, error)").Default("info").StringVar(&level) + kingpin.Flag("log.format", "log format (logfmt, json)").Default("logfmt").StringVar(&format) + kingpin.Flag("config.file", "Path to configuration file.").Default("hitron_coda.yml").StringVar(&configFile) + kingpin.Flag("web.listen-address", "Address to listen on for web interface and telemetry.").Default(":9780").StringVar(&listenAddress) - logger := promlog.New(promlogConfig) + kingpin.Parse() initExporterMetrics() - level.Info(logger).Log("msg", "Starting hitron_coda_exporter", "version", version.Version, "commit", version.GitCommit) + initLogger(level, format) + + slog.Info("Starting hitron_coda_exporter", "version", version.Version, "commit", version.GitCommit) // Bail early if the config is bad. - err := sc.ReloadConfig(*configFile) + err := sc.ReloadConfig(configFile) if err != nil { - level.Error(logger).Log("msg", "Error parsing config file", "err", err) + slog.Error("Error parsing config file", "err", err) exitCode = 1 return } - handleHUP(logger) + handleHUP(configFile) - mux := initRoutes(logger) + mux := initRoutes() - level.Info(logger).Log("msg", "Listening on", "address", *listenAddress) + slog.Info("Listening on", "address", listenAddress) srv := &http.Server{ - Addr: *listenAddress, + Addr: listenAddress, Handler: mux, //nolint:gomnd ReadHeaderTimeout: 2 * time.Second, } if err := srv.ListenAndServe(); err != nil { - level.Error(logger).Log("msg", "Error starting HTTP server", "err", err) + slog.Error("Error starting HTTP server", "err", err) exitCode = 1 } } + +func initLogger(level, format string) { + lvl := slog.LevelInfo + + switch level { + case "debug": + lvl = slog.LevelDebug + case "info": + lvl = slog.LevelInfo + case "warn": + lvl = slog.LevelWarn + case "error": + lvl = slog.LevelError + } + + opts := &slog.HandlerOptions{Level: lvl} + + var handler slog.Handler + + switch format { + case "json": + handler = slog.NewJSONHandler(os.Stderr, opts) + default: + handler = slog.NewTextHandler(os.Stderr, opts) + } + + slog.SetDefault(slog.New(handler)) +}