Skip to content

Commit

Permalink
Merge pull request #60 from kpetremann/linter
Browse files Browse the repository at this point in the history
chore: add linters and fix issues
  • Loading branch information
kpetremann authored Dec 22, 2023
2 parents 1d8fe98 + d5ab3b0 commit ce1f9a5
Show file tree
Hide file tree
Showing 17 changed files with 146 additions and 91 deletions.
63 changes: 63 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
run:
linters:
enable:
- asasalint
- asciicheck
- bodyclose
- dupword
- durationcheck
- errcheck
- errname
- errorlint
- exhaustive
- gocheckcompilerdirectives
- gocritic
- godot
- gofmt
- goimports
- goprintffuncname
- gosec
- gosimple
- govet
- grouper
- ineffassign
- makezero
- nilerr
- nilnil
- nolintlint
- nosprintfhostport
- prealloc
- predeclared
- reassign
- staticcheck
- stylecheck
- tenv
- testableexamples
- thelper
- tparallel
- typecheck
- unconvert
- unparam
- unused
- usestdlibvars
- wastedassign
- whitespace
- zerologlint
fast: false

# Issues configuration
issues:
exclude: []
exclude-case-sensitive: false
exclude-rules:
- path: '(.+)_test\.go'
linters:
- goconst
- path: '(.+)_test\.go'
linters:
- govet
text: 'fieldalignment: .*'
fix: false
max-issues-per-linter: 0
max-same-issues: 0
2 changes: 1 addition & 1 deletion cmd/salt-exporter/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func getConfig(configFileName string, healthMinions bool) (Config, error) {

err := viper.ReadInConfig()
if err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
if _, ok := err.(viper.ConfigFileNotFoundError); !ok { //nolint: errorlint // ConfigFileNotFoundError not implementing error
return Config{}, fmt.Errorf("invalid config file: %w", err)
}
}
Expand Down
7 changes: 4 additions & 3 deletions cmd/salt-exporter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"os/signal"
"syscall"
"time"

"github.com/kpetremann/salt-exporter/internal/logging"
"github.com/kpetremann/salt-exporter/internal/metrics"
Expand Down Expand Up @@ -65,7 +66,7 @@ func start(config Config) {
if config.Metrics.HealthMinions {
pkiWatcher, err := listener.NewPKIWatcher(ctx, config.PKIDir, watchChan)
if err != nil {
log.Fatal().Msgf("unable to watch PKI for minions change: %v", err)
log.Fatal().Msgf("unable to watch PKI for minions change: %v", err) //nolint:gocritic // force exit
}

go pkiWatcher.StartWatching()
Expand All @@ -78,7 +79,7 @@ func start(config Config) {

mux := http.NewServeMux()
mux.Handle("/metrics", promhttp.Handler())
httpServer := http.Server{Addr: listenSocket, Handler: mux}
httpServer := http.Server{Addr: listenSocket, Handler: mux, ReadHeaderTimeout: 2 * time.Second}

go func() {
var err error
Expand Down Expand Up @@ -108,7 +109,7 @@ func main() {

config, err := ReadConfig(configFileName)
if err != nil {
log.Fatal().Err(err).Msg("failed to load settings during initialization")
log.Fatal().Err(err).Msg("failed to load settings during initialization") //nolint:gocritic // force exit
}

logging.SetLevel(config.LogLevel)
Expand Down
2 changes: 1 addition & 1 deletion cmd/salt-live/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,6 @@ func main() {
p := tea.NewProgram(tui.NewModel(eventChan, *maxItems, *filter), tea.WithMouseCellMotion())
if _, err := p.Run(); err != nil {
fmt.Printf("Alas, there's been an error: %v", err)
os.Exit(1)
os.Exit(1) //nolint:gocritic // force exit
}
}
1 change: 0 additions & 1 deletion internal/filters/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ func matchTerm(s string, pattern string) bool {
// - Match("foo", []string{"*o*"}) -> true
func Match(value string, filters []string) bool {
for _, pattern := range filters {

if matchTerm(value, pattern) {
return true
}
Expand Down
2 changes: 1 addition & 1 deletion internal/logging/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func Configure() {

// SetLogLevel configures the loglevel.
//
// logLevel: The log level to use, in zerolog format
// logLevel: The log level to use, in zerolog format.
func SetLevel(logLevel string) {
level, err := zerolog.ParseLevel(logLevel)
fmt.Println(logLevel)
Expand Down
55 changes: 27 additions & 28 deletions internal/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"

"github.com/kpetremann/salt-exporter/pkg/event"
evt "github.com/kpetremann/salt-exporter/pkg/event"
"github.com/rs/zerolog/log"
)

Expand All @@ -15,26 +14,26 @@ func boolToFloat64(b bool) float64 {
return 0.0
}

func eventToMetrics(event event.SaltEvent, r *Registry) {
if event.Module == evt.BeaconModule {
if event.Type != "status" {
func eventToMetrics(e event.SaltEvent, r *Registry) {
if e.Module == event.BeaconModule {
if e.Type != "status" {
return
}
r.UpdateLastHeartbeat(event.Data.Id)
r.UpdateLastHeartbeat(e.Data.ID)
return
}

switch event.Type {
switch e.Type {
case "new":
state := event.ExtractState()
r.IncreaseNewJobTotal(event.Data.Fun, state)
r.IncreaseExpectedResponsesTotal(event.Data.Fun, state, float64(event.TargetNumber))
state := e.ExtractState()
r.IncreaseNewJobTotal(e.Data.Fun, state)
r.IncreaseExpectedResponsesTotal(e.Data.Fun, state, float64(e.TargetNumber))

case "ret":
state := event.ExtractState()
success := event.Data.Success
state := e.ExtractState()
success := e.Data.Success

if event.IsScheduleJob {
if e.IsScheduleJob {
// for scheduled job, when the states in the job actually failed
// - the global "success" value is always true
// - the state module success is false, but the global retcode is > 0
Expand All @@ -43,17 +42,17 @@ func eventToMetrics(event event.SaltEvent, r *Registry) {
//
// using retcode and state module success could be enough, but we combine all values
// in case there are other corner cases.
success = event.Data.Success && (event.Data.Retcode == 0)
if event.StateModuleSuccess != nil {
success = success && *event.StateModuleSuccess
success = e.Data.Success && (e.Data.Retcode == 0)
if e.StateModuleSuccess != nil {
success = success && *e.StateModuleSuccess
}
r.IncreaseScheduledJobReturnTotal(event.Data.Fun, state, event.Data.Id, success)
r.IncreaseScheduledJobReturnTotal(e.Data.Fun, state, e.Data.ID, success)
} else {
r.IncreaseFunctionResponsesTotal(event.Data.Fun, state, event.Data.Id, success)
r.IncreaseFunctionResponsesTotal(e.Data.Fun, state, e.Data.ID, success)
}

r.IncreaseResponseTotal(event.Data.Id, success)
r.SetFunctionStatus(event.Data.Id, event.Data.Fun, state, success)
r.IncreaseResponseTotal(e.Data.ID, success)
r.SetFunctionStatus(e.Data.ID, e.Data.Fun, state, success)
}
}

Expand All @@ -65,22 +64,22 @@ func ExposeMetrics(ctx context.Context, eventChan <-chan event.SaltEvent, watchC
case <-ctx.Done():
log.Info().Msg("stopping event listener")
return
case event := <-watchChan:
if event.Op == evt.Accepted {
registry.AddObservableMinion(event.MinionName)
case e := <-watchChan:
if e.Op == event.Accepted {
registry.AddObservableMinion(e.MinionName)
}
if event.Op == evt.Removed {
registry.DeleteObservableMinion(event.MinionName)
if e.Op == event.Removed {
registry.DeleteObservableMinion(e.MinionName)
}
case event := <-eventChan:
if config.Global.Filters.IgnoreTest && event.IsTest {
case e := <-eventChan:
if config.Global.Filters.IgnoreTest && e.IsTest {
return
}
if config.Global.Filters.IgnoreMock && event.IsMock {
if config.Global.Filters.IgnoreMock && e.IsMock {
return
}

eventToMetrics(event, &registry)
eventToMetrics(e, &registry)
}
}
}
7 changes: 3 additions & 4 deletions internal/tui/tui.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ func watchEvent(m model) tea.Cmd {
return func() tea.Msg {
for {
e := <-m.eventChan
var sender string = "master"
if e.Data.Id != "" {
sender = e.Data.Id
sender := "master"
if e.Data.ID != "" {
sender = e.Data.ID
}
eventJSON, err := e.RawToJSON(true)
if err != nil {
Expand Down Expand Up @@ -234,7 +234,6 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.updateTitle()

return m, tea.Batch(cmds...)

}

func (m *model) updateSideInfos() {
Expand Down
17 changes: 9 additions & 8 deletions pkg/event/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type EventData struct {
Cmd string `msgpack:"cmd"`
Fun string `msgpack:"fun"`
FunArgs []interface{} `msgpack:"fun_args"`
Id string `msgpack:"id"`
ID string `msgpack:"id"`
Jid string `msgpack:"jid"`
JidStamp string `msgpack:"jid_stamp"`
Minions []string `msgpack:"minions"`
Expand Down Expand Up @@ -66,7 +66,7 @@ type SaltEvent struct {

// RawToJSON converts raw body to JSON
//
// If indent is true, the JSON will be indented
// If indent is true, the JSON will be indented.
func (e SaltEvent) RawToJSON(indent bool) ([]byte, error) {
if e.RawBody == nil {
return nil, errors.New("raw body not registered")
Expand All @@ -83,7 +83,7 @@ func (e SaltEvent) RawToJSON(indent bool) ([]byte, error) {
}
}

// RawToYAML converts raw body to YAML
// RawToYAML converts raw body to YAML.
func (e SaltEvent) RawToYAML() ([]byte, error) {
if e.RawBody == nil {
return nil, errors.New("raw body not registered")
Expand Down Expand Up @@ -114,7 +114,7 @@ func GetEventModule(tag string) EventModule {
}
}

// extractStateFromArgs extracts embedded state info
// extractStateFromArgs extracts embedded state info.
func extractStateFromArgs(args interface{}, key string) string {
// args only
if v, ok := args.(string); ok {
Expand All @@ -134,15 +134,16 @@ func extractStateFromArgs(args interface{}, key string) string {
return ""
}

// Extract state info from event
// Extract state info from event.
func (e *SaltEvent) ExtractState() string {
switch e.Data.Fun {
case "state.sls", "state.apply":
if len(e.Data.Arg) > 0 {
switch {
case len(e.Data.Arg) > 0:
return extractStateFromArgs(e.Data.Arg[0], "mods")
} else if len(e.Data.FunArgs) > 0 {
case len(e.Data.FunArgs) > 0:
return extractStateFromArgs(e.Data.FunArgs[0], "mods")
} else if e.Data.Fun == "state.apply" {
case e.Data.Fun == "state.apply":
return "highstate"
}
case "state.single":
Expand Down
1 change: 0 additions & 1 deletion pkg/event/event_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,4 @@ func TestExtractState(t *testing.T) {
t.Errorf("Mismatch for '%s', wants '%s' got '%s' ", test.name, test.want, res)
}
}

}
12 changes: 6 additions & 6 deletions pkg/listener/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type eventParser interface {

const DefaultIPCFilepath = "/var/run/salt/master/master_event_pub.ipc"

// EventListener listens to the salt-master event bus and sends events to the event channel
// EventListener listens to the salt-master event bus and sends events to the event channel.
type EventListener struct {
// ctx specificies the context used mainly for cancellation
ctx context.Context
Expand All @@ -37,7 +37,7 @@ type EventListener struct {
eventParser eventParser
}

// Open opens the salt-master event bus
// Open opens the salt-master event bus.
func (e *EventListener) Open() {
log.Info().Str("file", e.iPCFilepath).Msg("connecting to salt-master event bus")
var err error
Expand All @@ -61,7 +61,7 @@ func (e *EventListener) Open() {
}
}

// Close closes the salt-master event bus
// Close closes the salt-master event bus.
func (e *EventListener) Close() error {
log.Info().Msg("disconnecting from salt-master event bus")
if e.saltEventBus != nil {
Expand All @@ -71,7 +71,7 @@ func (e *EventListener) Close() error {
}
}

// Reconnect reconnects to the salt-master event bus
// Reconnect reconnects to the salt-master event bus.
func (e *EventListener) Reconnect() {
select {
case <-e.ctx.Done():
Expand Down Expand Up @@ -99,12 +99,12 @@ func NewEventListener(ctx context.Context, eventParser eventParser, eventChan ch
//
// The IPC file must be readable by the user running the exporter.
//
// Default: /var/run/salt/master/master_event_pub.ipc
// Default: /var/run/salt/master/master_event_pub.ipc.
func (e *EventListener) SetIPCFilepath(filepath string) {
e.iPCFilepath = filepath
}

// ListenEvents listens to the salt-master event bus and sends events to the event channel
// ListenEvents listens to the salt-master event bus and sends events to the event channel.
func (e *EventListener) ListenEvents() {
e.Open()

Expand Down
Loading

0 comments on commit ce1f9a5

Please sign in to comment.