Skip to content

Commit

Permalink
Converted from log to slog (#154)
Browse files Browse the repository at this point in the history
  • Loading branch information
xonvanetta authored Jul 28, 2023
1 parent bd01426 commit cd0f569
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 18 deletions.
17 changes: 12 additions & 5 deletions cmd/exporter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/kuskoman/logstash-exporter/config"
"github.com/kuskoman/logstash-exporter/server"
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/exp/slog"
)

func main() {
Expand All @@ -16,21 +17,27 @@ func main() {
log.Println(warn)
}

logger, err := config.SetupSlog()
if err != nil {
log.Fatalf("failed to setup slog: %s", err)
}
slog.SetDefault(logger)

port := config.Port
host := config.Host
logstashUrl := config.LogstashUrl

log.Println("Application starting...")
slog.Debug("Application starting... ")
versionInfo := config.GetVersionInfo()
log.Println(versionInfo.String())
slog.Info(versionInfo.String())

collectorManager := collectors.NewCollectorManager(logstashUrl)
server := server.NewAppServer(host, port)
prometheus.MustRegister(collectorManager)

log.Printf("Starting server on port %s", port)
err := server.ListenAndServe()
slog.Info("Starting server on port", "port", port)
err = server.ListenAndServe()
if err != nil {
log.Fatal(err)
slog.Error("failed to listen and serve", "err", err)
}
}
11 changes: 6 additions & 5 deletions collectors/collector_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package collectors

import (
"context"
"log"
"sync"
"time"

"golang.org/x/exp/slog"

"github.com/kuskoman/logstash-exporter/collectors/nodeinfo"
"github.com/kuskoman/logstash-exporter/collectors/nodestats"
"github.com/kuskoman/logstash-exporter/config"
Expand Down Expand Up @@ -53,9 +54,9 @@ func (manager *CollectorManager) Collect(ch chan<- prometheus.Metric) {
waitGroup.Add(len(manager.collectors))
for name, collector := range manager.collectors {
go func(name string, collector Collector) {
log.Printf("executing collector %s", name)
slog.Debug("executing collector", "name", name)
manager.executeCollector(name, ctx, collector, ch)
log.Printf("collector %s finished", name)
slog.Debug("collector finished", "name", name)
waitGroup.Done()
}(name, collector)
}
Expand All @@ -73,10 +74,10 @@ func (manager *CollectorManager) executeCollector(name string, ctx context.Conte
var executionStatus string

if err != nil {
log.Printf("executor %s failed after %s: %s", name, executionDuration, err.Error())
slog.Error("executor failed", "name", name, "duration", executionDuration, "err", err)
executionStatus = "error"
} else {
log.Printf("executor %s succeeded after %s", name, executionDuration)
slog.Debug("executor succeeded", "name", name, "duration", executionDuration)
executionStatus = "success"
}

Expand Down
17 changes: 9 additions & 8 deletions collectors/nodestats/pipeline_subcollector.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package nodestats

import (
"fmt"
"log"
"time"

"golang.org/x/exp/slog"

"github.com/prometheus/client_golang/prometheus"

"github.com/kuskoman/logstash-exporter/fetcher/responses"
Expand Down Expand Up @@ -113,7 +114,7 @@ func NewPipelineSubcollector() *PipelineSubcollector {

func (collector *PipelineSubcollector) Collect(pipeStats *responses.SinglePipelineResponse, pipelineID string, ch chan<- prometheus.Metric) {
collectingStart := time.Now()
log.Printf("collecting pipeline stats for pipeline %s", pipelineID)
slog.Debug("collecting pipeline stats for pipeline", "pipelineID", pipelineID)

ch <- prometheus.MustNewConstMetric(collector.EventsOut, prometheus.CounterValue, float64(pipeStats.Events.Out), pipelineID)
ch <- prometheus.MustNewConstMetric(collector.EventsFiltered, prometheus.CounterValue, float64(pipeStats.Events.Filtered), pipelineID)
Expand Down Expand Up @@ -159,7 +160,7 @@ func (collector *PipelineSubcollector) Collect(pipeStats *responses.SinglePipeli
for _, output := range pipeStats.Plugins.Outputs {
pluginID := output.ID
pluginType := "output"
log.Printf("collecting output error stats for pipeline %s :: plugin type:%s name:%s id:%s", pipelineID, pluginType, output.Name, pluginID)
slog.Debug("collecting output error stats for pipeline", "pipelineID", pipelineID, "plugin type", pluginType, "name", output.Name, "id", pluginID)

// Response codes returned by output Bulk Requests
for code, count := range output.BulkRequests.Responses {
Expand All @@ -174,13 +175,13 @@ func (collector *PipelineSubcollector) Collect(pipeStats *responses.SinglePipeli
// Pipeline plugins metrics
for _, plugin := range pipeStats.Plugins.Inputs {
pluginType := "input"
log.Printf("collecting pipeline plugin stats for pipeline %s :: plugin type:%s name:%s id:%s", pipelineID, pluginType, plugin.Name, plugin.ID)
slog.Debug("collecting pipeline plugin stats for pipeline", "pipelineID", pipelineID, "plugin type", pluginType, "name", plugin.Name, "id", plugin.ID)
ch <- prometheus.MustNewConstMetric(collector.PipelinePluginEventsOut, prometheus.CounterValue, float64(plugin.Events.Out), pipelineID, pluginType, plugin.Name, plugin.ID)
ch <- prometheus.MustNewConstMetric(collector.PipelinePluginEventsQueuePushDuration, prometheus.CounterValue, float64(plugin.Events.QueuePushDurationInMillis), pipelineID, pluginType, plugin.Name, plugin.ID)
}

for _, plugin := range pipeStats.Plugins.Codecs {
log.Printf("collecting pipeline plugin stats for pipeline %s :: plugin type:%s name:%s id:%s", pipelineID, "codec", plugin.Name, plugin.ID)
slog.Debug("collecting pipeline plugin stats for pipeline", "pipelineID", pipelineID, "plugin type", "codec", "name", plugin.Name, "id", plugin.ID)
ch <- prometheus.MustNewConstMetric(collector.PipelinePluginEventsIn, prometheus.CounterValue, float64(plugin.Encode.WritesIn), pipelineID, "codec:encode", plugin.Name, plugin.ID)
ch <- prometheus.MustNewConstMetric(collector.PipelinePluginEventsIn, prometheus.CounterValue, float64(plugin.Decode.WritesIn), pipelineID, "codec:decode", plugin.Name, plugin.ID)
ch <- prometheus.MustNewConstMetric(collector.PipelinePluginEventsOut, prometheus.CounterValue, float64(plugin.Decode.Out), pipelineID, "codec:decode", plugin.Name, plugin.ID)
Expand All @@ -190,22 +191,22 @@ func (collector *PipelineSubcollector) Collect(pipeStats *responses.SinglePipeli

for _, plugin := range pipeStats.Plugins.Filters {
pluginType := "filter"
log.Printf("collecting pipeline plugin stats for pipeline %s :: plugin type:%s name:%s id:%s", pipelineID, pluginType, plugin.Name, plugin.ID)
slog.Debug("collecting pipeline plugin stats for pipeline", "pipelineID", pipelineID, "plugin type", pluginType, "name", plugin.Name, "id", plugin.ID)
ch <- prometheus.MustNewConstMetric(collector.PipelinePluginEventsIn, prometheus.CounterValue, float64(plugin.Events.In), pipelineID, pluginType, plugin.Name, plugin.ID)
ch <- prometheus.MustNewConstMetric(collector.PipelinePluginEventsOut, prometheus.CounterValue, float64(plugin.Events.Out), pipelineID, pluginType, plugin.Name, plugin.ID)
ch <- prometheus.MustNewConstMetric(collector.PipelinePluginEventsDuration, prometheus.CounterValue, float64(plugin.Events.DurationInMillis), pipelineID, pluginType, plugin.Name, plugin.ID)
}

for _, plugin := range pipeStats.Plugins.Outputs {
pluginType := "output"
log.Printf("collecting pipeline plugin stats for pipeline %s :: plugin type:%s name:%s id:%s", pipelineID, pluginType, plugin.Name, plugin.ID)
slog.Debug("collecting pipeline plugin stats for pipeline", "pipelineID", pipelineID, "plugin type", pluginType, "name", plugin.Name, "id", plugin.ID)
ch <- prometheus.MustNewConstMetric(collector.PipelinePluginEventsIn, prometheus.CounterValue, float64(plugin.Events.In), pipelineID, pluginType, plugin.Name, plugin.ID)
ch <- prometheus.MustNewConstMetric(collector.PipelinePluginEventsOut, prometheus.CounterValue, float64(plugin.Events.Out), pipelineID, pluginType, plugin.Name, plugin.ID)
ch <- prometheus.MustNewConstMetric(collector.PipelinePluginEventsDuration, prometheus.CounterValue, float64(plugin.Events.DurationInMillis), pipelineID, pluginType, plugin.Name, plugin.ID)
}

collectingEnd := time.Now()
log.Printf("collected pipeline stats for pipeline %s in %s", pipelineID, collectingEnd.Sub(collectingStart))
slog.Debug("collected pipeline stats for pipeline", "pipelineID", pipelineID, "duration", collectingEnd.Sub(collectingStart))
}

// isPipelineHealthy returns 1 if the pipeline is healthy, 0 if it is not
Expand Down
40 changes: 40 additions & 0 deletions config/slog_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package config

import (
"fmt"
"os"
"strings"

"golang.org/x/exp/slog"
)

var (
LogLevel = getEnvWithDefault("LOG_LEVEL", "info")
LogFormat = getEnvWithDefault("LOG_FORMAT", "text")

ErrUnknownLogFormat = fmt.Errorf("unknown log format")
)

func SetupSlog() (*slog.Logger, error) {
level := slog.LevelInfo
err := level.UnmarshalText([]byte(LogLevel))
if err != nil {
return nil, err
}

var handler slog.Handler
switch strings.ToLower(LogFormat) {
case "text":
handler = slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
Level: level,
})
case "json":
handler = slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
Level: level,
})
default:
return nil, ErrUnknownLogFormat
}

return slog.New(handler), nil
}
59 changes: 59 additions & 0 deletions config/slog_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package config

import (
"errors"
"testing"
)

func TestSetupSlog(t *testing.T) {
t.Run("Wrong type of log level", func(t *testing.T) {
LogLevel = "infox"
logger, err := SetupSlog()
if logger != nil {
t.Errorf("Expected logger to be nil, got %s\"", logger)
}
if err.Error() != "slog: level string \"infox\": unknown name" {
t.Errorf("Expected error to be '%s', got %s\"", "slog: level string \"infox\": unknown name", err)
}
})
t.Run("Wrong type of log level", func(t *testing.T) {
LogLevel = "warn"
logger, err := SetupSlog()
if err != nil {
t.Errorf("Expected error to be nil, got %s\"", err)
}
if logger == nil {
t.Errorf("Expected logger to be not nil, got %s\"", logger)
}
})
t.Run("Wrong type of log format", func(t *testing.T) {
LogFormat = "test"
logger, err := SetupSlog()
if logger != nil {
t.Errorf("Expected logger to be nil, got %s\"", logger)
}
if !errors.Is(err, ErrUnknownLogFormat) {
t.Errorf("Expected error to be '%s', got %s\"", ErrUnknownLogFormat, err)
}
})
t.Run("Correct type of log format", func(t *testing.T) {
LogFormat = "text"
logger, err := SetupSlog()
if err != nil {
t.Errorf("Expected error to be nil, got %s\"", err)
}
if logger == nil {
t.Errorf("Expected logger to be not nil, got %s\"", logger)
}
})
t.Run("Json type of log format", func(t *testing.T) {
LogFormat = "json"
logger, err := SetupSlog()
if err != nil {
t.Errorf("Expected error to be nil, got %s\"", err)
}
if logger == nil {
t.Errorf("Expected logger to be not nil, got %s\"", logger)
}
})
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.20
require (
github.com/joho/godotenv v1.5.1
github.com/prometheus/client_golang v1.16.0
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1
)

require (
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down

0 comments on commit cd0f569

Please sign in to comment.