Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: track config hash on config reload #1212

Merged
merged 3 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,29 @@ type App struct {
// program will exit.
func (a *App) Start() error {
a.Logger.Debug().Logf("Starting up App...")
a.Metrics.Register("config_hash", "gauge")
a.Metrics.Register("rule_config_hash", "gauge")

a.IncomingRouter.SetVersion(a.Version)
a.PeerRouter.SetVersion(a.Version)

a.Config.RegisterReloadCallback(func(configHash, rulesHash string) {
if a.Logger != nil {
a.Logger.Warn().WithFields(map[string]interface{}{
"configHash": configHash,
"rulesHash": rulesHash,
}).Logf("configuration change was detected and the configuration was reloaded.")

cfgMetric := config.ConfigHashMetrics(configHash)
ruleMetric := config.ConfigHashMetrics(rulesHash)

a.Metrics.Gauge("config_hash", cfgMetric)
a.Metrics.Gauge("rule_config_hash", ruleMetric)

}

})

// launch our main routers to listen for incoming event traffic from both peers
// and external sources
a.IncomingRouter.LnS("incoming")
Expand Down
6 changes: 0 additions & 6 deletions cmd/refinery/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,6 @@ func main() {
fmt.Println("Config and Rules validated successfully.")
os.Exit(0)
}
c.RegisterReloadCallback(func() {
if a.Logger != nil {
a.Logger.Info().Logf("configuration change was detected and the configuration was reloaded")
}
})

// get desired implementation for each dependency to inject
lgr := logger.GetLoggerImplementation(c)
collector := collect.GetCollectorImplementation(c)
Expand Down
2 changes: 1 addition & 1 deletion collect/collect.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func (i *InMemCollector) Start() error {
}

// sendReloadSignal will trigger the collector reloading its config, eventually.
func (i *InMemCollector) sendReloadSignal() {
func (i *InMemCollector) sendReloadSignal(cfgHash, ruleHash string) {
// non-blocking insert of the signal here so we don't leak goroutines
select {
case i.reload <- struct{}{}:
Expand Down
4 changes: 3 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type Config interface {
// consumers of configuration set config values on startup, they should
// check their values haven't changed and re-start anything that needs
// restarting with the new values.
RegisterReloadCallback(callback func())
RegisterReloadCallback(callback ConfigReloadCallback)

// GetListenAddr returns the address and port on which to listen for
// incoming events
Expand Down Expand Up @@ -191,6 +191,8 @@ type Config interface {
GetParentIdFieldNames() []string
}

type ConfigReloadCallback func(configHash, ruleCfgHash string)

type ConfigMetadata struct {
Type string `json:"type"`
ID string `json:"id"`
Expand Down
19 changes: 19 additions & 0 deletions config/configLoadHelpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"os"
"path/filepath"
"reflect"
"strconv"

"github.com/creasty/defaults"
"github.com/pelletier/go-toml/v2"
Expand Down Expand Up @@ -240,3 +241,21 @@ func readConfigInto(dest any, location string, opts *CmdEnv) (string, error) {

return hash, nil
}

// ConfigHashMetrics takes a config hash and returns a integer value for use in metrics.
// The value is the last 4 characters of the config hash, converted to an integer.
// If the config hash is too short, or if there is an error converting the hash to an integer,
// it returns 0.
func ConfigHashMetrics(hash string) int64 {
// get last 4 characters of config hash
if len(hash) < 4 {
return 0
}
suffix := hash[len(hash)-4:]
CfgDecimal, err := strconv.ParseInt(suffix, 16, 64)
if err != nil {
return 0
}

return CfgDecimal
}
20 changes: 20 additions & 0 deletions config/configLoadHelpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"strings"
"testing"
"time"

"github.com/stretchr/testify/require"
)

func Test_formatFromFilename(t *testing.T) {
Expand Down Expand Up @@ -127,3 +129,21 @@ func Test_loadMemsize(t *testing.T) {
})
}
}

func Test_ConfigHashMetrics(t *testing.T) {
testcases := []struct {
name string
hash string
expected int64
}{
{name: "valid hash", hash: "7f1237f7db723f4e874a7a8269081a77", expected: 6775},
VinozzZ marked this conversation as resolved.
Show resolved Hide resolved
{name: "invalid length", hash: "1a8", expected: 0},
}

for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
result := ConfigHashMetrics(tc.hash)
require.Equal(t, tc.expected, result)
})
}
}
2 changes: 1 addition & 1 deletion config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func TestReload(t *testing.T) {

ch := make(chan interface{}, 1)

c.RegisterReloadCallback(func() {
c.RegisterReloadCallback(func(cfgHash, ruleHash string) {
close(ch)
})

Expand Down
9 changes: 5 additions & 4 deletions config/file_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type fileConfig struct {
rulesConfig *V2SamplerConfig
rulesHash string
opts *CmdEnv
callbacks []func()
callbacks []ConfigReloadCallback
errorCallback func(error)
done chan struct{}
ticker *time.Ticker
Expand Down Expand Up @@ -412,7 +412,7 @@ func NewConfig(opts *CmdEnv, errorCallback func(error)) (Config, error) {
os.Exit(0)
}

cfg.callbacks = make([]func(), 0)
cfg.callbacks = make([]ConfigReloadCallback, 0)
cfg.errorCallback = errorCallback

if cfg.mainConfig.General.ConfigReloadInterval > 0 {
Expand Down Expand Up @@ -451,8 +451,9 @@ func (f *fileConfig) monitor() {
f.rulesConfig = cfg.rulesConfig
f.rulesHash = cfg.rulesHash
f.mux.Unlock() // can't defer -- routine never ends, and callbacks will deadlock

for _, cb := range f.callbacks {
cb()
cb(cfg.mainHash, cfg.rulesHash)
}
}
}
Expand All @@ -469,7 +470,7 @@ func (f *fileConfig) Stop() {
}
}

func (f *fileConfig) RegisterReloadCallback(cb func()) {
func (f *fileConfig) RegisterReloadCallback(cb ConfigReloadCallback) {
f.mux.Lock()
defer f.mux.Unlock()

Expand Down
6 changes: 3 additions & 3 deletions config/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
// MockConfig will respond with whatever config it's set to do during
// initialization
type MockConfig struct {
Callbacks []func()
Callbacks []ConfigReloadCallback
IsAPIKeyValidFunc func(string) bool
GetCollectorTypeErr error
GetCollectorTypeVal string
Expand Down Expand Up @@ -99,11 +99,11 @@ func (m *MockConfig) ReloadConfig() {
defer m.Mux.RUnlock()

for _, callback := range m.Callbacks {
callback()
callback("", "")
}
}

func (m *MockConfig) RegisterReloadCallback(callback func()) {
func (m *MockConfig) RegisterReloadCallback(callback ConfigReloadCallback) {
m.Mux.Lock()
m.Callbacks = append(m.Callbacks, callback)
m.Mux.Unlock()
Expand Down
2 changes: 1 addition & 1 deletion logger/honeycomb.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func (h *HoneycombLogger) readResponses() {
}
}

func (h *HoneycombLogger) reloadBuilder() {
func (h *HoneycombLogger) reloadBuilder(cfgHash, ruleHash string) {
h.Debug().Logf("reloading config for Honeycomb logger")
// preserve log level
h.level = h.Config.GetLoggerLevel()
Expand Down
2 changes: 1 addition & 1 deletion metrics/legacy.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func (h *LegacyMetrics) Start() error {
return nil
}

func (h *LegacyMetrics) reloadBuilder() {
func (h *LegacyMetrics) reloadBuilder(cfgHash, ruleHash string) {
h.Logger.Debug().Logf("reloading config for honeycomb metrics reporter")
mc := h.Config.GetLegacyMetricsConfig()
h.libhClient.Close()
Expand Down
2 changes: 1 addition & 1 deletion transmit/transmit.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func (d *DefaultTransmission) Start() error {
return nil
}

func (d *DefaultTransmission) reloadTransmissionBuilder() {
func (d *DefaultTransmission) reloadTransmissionBuilder(cfgHash, ruleHash string) {
d.Logger.Debug().Logf("reloading transmission config")
upstreamAPI, err := d.Config.GetHoneycombAPI()
if err != nil {
Expand Down
Loading