我正在尝试使用golang viper阅读我的应用程序配置,并希望始终阅读最新的配置。请在下面找到我的代码
config.go
package config
import (
"github.com/spf13/viper"
"log"
"github.com/fsnotify/fsnotify"
"time"
)
type Reader interface {
GetAllKeys() []string
Get(key string) interface{}
GetBool(key string) bool
GetString(key string) string
}
type viperConfigReader struct {
viper *viper.Viper
}
var TestConfReader *viperConfigReader
func (v viperConfigReader) GetAllKeys() []string{
return v.viper.AllKeys()
}
func (v viperConfigReader) Get(key string) interface{} {
return v.viper.Get(key)
}
func (v viperConfigReader) GetBool(key string) bool {
return v.viper.GetBool(key)
}
func (v viperConfigReader) GetString(key string) string {
return v.viper.GetString(key)
}
func init() {
v:= viper.New()
v.SetConfigName("test")
v.AddConfigPath("/tmp/")
err := v.ReadInConfig()
if err != nil {
log.Panic("Not able to read configuration", err.Error())
}
TestConfReader = &viperConfigReader{
viper: v,
}
go func() {
for {
time.Sleep(time.Second * 5)
v.WatchConfig()
v.OnConfigChange(func(e fsnotify.Event) {
log.Println("config file changed", e.Name)
})
}
}()
}
main.go
package main
import (
"github.com/xxxx/xxxx/config"
"log"
"time"
)
func main() {
conf := config.TestConfReader
log.Println(conf.GetAllKeys())
log.Println(conf.GetString("test1"))
time.Sleep(20 * time.Second)
log.Println(conf.GetString("test1"))
}
当主程序运行时,我尝试更新配置并期望看到OnConfigChange日志消息,但它从未出现过。
如何修复此程序?。
有人可以举例说明使用viper watchconfig& onconfigchange方法来读取最新的配置
答案 0 :(得分:2)
comment ymonad位于正确的轨道上,具体取决于您在viper / fsnotify时可能遇到的操作系统。
例如,我在Mac OS X(Sierra)上运行了您的示例代码并注意到您描述的相同症状:当配置文件位于/tmp
时,viper WatchConfig
调用未导致viper OnConfigChange
函数被调用。
但是,当我更改AddConfigPath
以使用当前工作目录或我的主目录时,我会看到来自OnConfigChange
函数的日志记录。例如,尝试:
v.AddConfigPath("./")
我建议尝试使用不同的目录位置来查看这是否是某种viper / fsnotify错误或限制。出于某种原因,它似乎没有检测到Mac OS X上/tmp
目录的变化,至少,它不适用于我的设置。我无法在OS X上找到/tmp
的任何问题,但fsnotify CONTRIBUTING.md确实提到了" shared" Vagrant下的目录也许有些文件系统配置不会触发通知:
注意:fsnotify文件系统事件不会在共享文件夹中触发。测试通过使用/ tmp目录来解决这个限制。
此外,您不需要通过goroutine继续致电WatchConfig
和OnConfigChange
。您可以完全消除goroutine,只需将相关行移动到init
。