Skip to content

Commit

Permalink
perf: reduce allocs when reading credential files (#3111)
Browse files Browse the repository at this point in the history
refactor: remove cyclic dependency in logging
  • Loading branch information
cgrinds authored Aug 19, 2024
1 parent f95fef1 commit 504a2c1
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 20 deletions.
3 changes: 2 additions & 1 deletion cmd/poller/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ package options

import (
"github.com/netapp/harvest/v2/pkg/conf"
"github.com/netapp/harvest/v2/pkg/logging"
"github.com/rs/zerolog"
"os"
"path/filepath"
Expand Down Expand Up @@ -81,7 +82,7 @@ func (o *Options) SetDefaults() *Options {
}

o.HomePath = conf.Path("")
o.LogPath = conf.GetHarvestLogPath()
o.LogPath = logging.GetLogPath()
o.SetConfPath(o.ConfPath)

// If both debug and loglevel are set, loglevel wins
Expand Down
56 changes: 39 additions & 17 deletions pkg/conf/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
package conf

import (
"cmp"
"errors"
"fmt"
"github.com/netapp/harvest/v2/pkg/errs"
"github.com/netapp/harvest/v2/pkg/logging"
"github.com/netapp/harvest/v2/pkg/tree/node"
"github.com/netapp/harvest/v2/pkg/util"
"github.com/netapp/harvest/v2/third_party/mergo"
Expand All @@ -20,10 +20,16 @@ import (
"sort"
"strconv"
"strings"
"sync"
)

var Config = HarvestConfig{}
var configRead = false
var (
Config = HarvestConfig{}
configRead = false
readMu = sync.Mutex{}
credentialModTime = int64(0)
credConfig HarvestConfig
)

const (
DefaultAPIVersion = "1.3"
Expand Down Expand Up @@ -222,22 +228,28 @@ func DecodeConfig(contents []byte) error {
}

func ReadCredentialFile(credPath string, p *Poller) error {
contents, err := os.ReadFile(credPath)
fileChanged, err := hasFileChanged(credPath)
if err != nil {
abs, err2 := filepath.Abs(credPath)
if err2 != nil {
abs = credPath
return err
}
if fileChanged {
logging.Get().Info().Str("credPath", credPath).Msg("reading credentials")
contents, err := os.ReadFile(credPath)
if err != nil {
abs, err2 := filepath.Abs(credPath)
if err2 != nil {
abs = credPath
}
return fmt.Errorf("failed to read file=%s error: %w", abs, err)
}
err = yaml.Unmarshal(contents, &credConfig)
if err != nil {
return err
}
return fmt.Errorf("failed to read file=%s error: %w", abs, err)
}
if p == nil {
return nil
}
var credConfig HarvestConfig
err = yaml.Unmarshal(contents, &credConfig)
if err != nil {
return err
}

credPoller := credConfig.Pollers[p.Name]
if credPoller == nil {
Expand Down Expand Up @@ -272,6 +284,20 @@ func ReadCredentialFile(credPath string, p *Poller) error {
return nil
}

func hasFileChanged(path string) (bool, error) {
readMu.Lock()
defer readMu.Unlock()
stat, err := os.Stat(path)
if err != nil {
return false, fmt.Errorf("failed to stat file=%s error: %w", path, err)
}
if stat.ModTime().Unix() > credentialModTime {
credentialModTime = stat.ModTime().Unix()
return true, nil
}
return false, nil
}

func PollerNamed(name string) (*Poller, error) {
poller, ok := Config.Pollers[name]
if !ok {
Expand Down Expand Up @@ -299,10 +325,6 @@ func Path(aPath string) string {
return filepath.Join(confDir, aPath)
}

func GetHarvestLogPath() string {
return cmp.Or(os.Getenv("HARVEST_LOGS"), "/var/log/harvest/")
}

// GetLastPromPort returns the Prometheus port for the given poller
// If multiple Prometheus exporters are configured for a poller, the port for the last exporter is returned.
func GetLastPromPort(pollerName string, validatePortInUse bool) (int, error) {
Expand Down
8 changes: 6 additions & 2 deletions pkg/logging/logger.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package logging

import (
"github.com/netapp/harvest/v2/pkg/conf"
"cmp"
"io"
"os"
"path"
Expand Down Expand Up @@ -67,7 +67,7 @@ func Get() *Logger {
PrefixValue: defaultPrefixValue,
LogLevel: defaultLogLevel,
FileLoggingEnabled: defaultFileLoggingEnabled,
Directory: conf.GetHarvestLogPath(),
Directory: GetLogPath(),
Filename: defaultLogFileName,
MaxSize: DefaultLogMaxMegaBytes,
MaxBackups: DefaultLogMaxBackups,
Expand All @@ -78,6 +78,10 @@ func Get() *Logger {
return logger
}

func GetLogPath() string {
return cmp.Or(os.Getenv("HARVEST_LOGS"), "/var/log/harvest/")
}

// SubLogger adds the field key with val as a string to the logger context and returns sublogger
func (l *Logger) SubLogger(key string, value string) *Logger {
if l != nil {
Expand Down

0 comments on commit 504a2c1

Please sign in to comment.