package config import ( "fmt" "log" "path" "path/filepath" "sync" "github.com/fsnotify/fsnotify" "github.com/spf13/viper" ) type ConfigInterface interface { Load() RegisterOnChangeCallback(f func()) Get(key string) interface{} } type Config struct { cbLock sync.Mutex Callbacks []func() Env string } func NewConfig() ConfigInterface { return &Config{} } func (c *Config) Load() { pathConfig := "./../config.json" realPath, err := filepath.Abs(pathConfig) if err != nil { log.Fatal(err.Error()) } viper.SetConfigName("config") viper.SetConfigType("json") viper.AddConfigPath(path.Dir(realPath)) if err := viper.ReadInConfig(); err != nil { log.Fatalf("Failed To Read Configuration File: %v", err) } c.SetEnv() viper.WatchConfig() viper.OnConfigChange(func(e fsnotify.Event) { c.SetEnv() log.Printf("Configuration File Changed : %s", e.Name) c.cbLock.Lock() for _, callback := range c.Callbacks { if callback != nil { callback() } } c.cbLock.Unlock() }) } func (c *Config) RegisterOnChangeCallback(f func()) { c.cbLock.Lock() defer c.cbLock.Unlock() c.Callbacks = append(c.Callbacks, f) } func (c *Config) SetEnv() { envString := viper.GetString("env") log.Println(envString) c.Env = envString } func (c *Config) Get(key string) interface{} { envString := fmt.Sprintf("%v.%v", "config", c.Env) return viper.Get(fmt.Sprintf("%v.%v", envString, key)) }