如何在配置文件中更改值不提供该值

时间:2019-09-09 10:32:52

标签: go

当环境变量/配置属性值更改时,我想做些观察 我发现毒蛇应该支持这种情况,但无法 使它工作。 我看到调用了2.4.0.cloudera,但是config中的值 更改时不会从配置中获取。配置成功加载

我创建了一个示例来演示该问题。

文件OnConfigChange

cfg.go

go/src/myproj/configuration/cfg.go

然后我创建了一些示例Web应用程序服务器,以使程序在后台运行 (为了能够更改配置并查看Wheatear某些更改)

package configuration import ( "fmt" "os" "strings" "github.com/fsnotify/fsnotify" "github.com/sirupsen/logrus" "github.com/spf13/viper" ) const ( varLogLevel = "log" varPathToConfig = "config.file" ) type Configuration struct { v *viper.Viper } func New() *Configuration { c := Configuration{ v: viper.New(), } c.v.SetDefault(varPathToConfig, "./config.yaml") c.v.SetDefault(varLogLevel, "info") c.v.AutomaticEnv() c.v.SetConfigFile(c.GetPathToConfig()) err := c.v.ReadInConfig() // Find and read the config file logrus.WithField("path", c.GetPathToConfig()).Warn("loading config") // just use the default value(s) if the config file was not found if _, ok := err.(*os.PathError); ok { logrus.Warnf("no config file '%s' not found. Using default values", c.GetPathToConfig()) } else if err != nil { // Handle other errors that occurred while reading the config file panic(fmt.Errorf("fatal error while reading the config file: %s", err)) } setLogLevel(c.GetLogLevel()) // monitor the changes in the config file c.v.WatchConfig() c.v.OnConfigChange(func(e fsnotify.Event) { logrus.WithField("file", e.Name).Warn("Config file changed") setLogLevel(c.GetLogLevel()) }) return &c } // GetLogLevel returns the log level func (c *Configuration) GetLogLevel() string { s := c.v.GetString(varLogLevel) return s } // GetPathToConfig returns the path to the config file func (c *Configuration) GetPathToConfig() string { return c.v.GetString(varPathToConfig) } func setLogLevel(logLevel string) { logrus.WithField("level", logLevel).Warn("setting log level") level, err := logrus.ParseLevel(logLevel) if err != nil { logrus.WithField("level", logLevel).Fatalf("failed to start: %s", err.Error()) } logrus.SetLevel(level) }

go/src/myproj

问题是函数package main import ( "fmt" "net/http" "myproj/configuration" ) func main() { cfg := configuration.New() fmt.Println(cfg) http.HandleFunc("/", HelloServer) http.ListenAndServe(":8080", nil) } func HelloServer(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:]) } 带来了旧值,而不从config中读取值?

这是配置文件的示例(我已将其同级到根项目文件夹下的GetLogLevel()文件

这是项目结构

main.go
go/src/myproj
  - main.go
  - configuration #folder
  -- cfg.go
  - config.yaml

当我将其从data: config.yaml: 'log: debug' 更改为info(或其他选项)时,我看到事件debug被引发,但是 它不会获取新值(如调试)。有想法吗?

更新 当我像@Tom建议的那样更改配置文件时,我能够看到日志已更改但级别未更改,它保留在watch

这是日志,我仍然看到警告

warn

1 个答案:

答案 0 :(得分:1)

就我所知,您的代码没有错,因为fsnotify确实可以触发。因此,罪魁祸首必须是解析。在setLogLevel(c.GetLogLevel())回调之外对onConfigChange的首次调用返回错误的值。将您的Yaml文件的内容更改为公正

log: 'level'

所有功能都应按要求工作。

logrus软件包按顺序支持以下级别(截至撰写本文时):PanicFatalErrorWarnInfoDebugTrace。相应的方法是:logrus.Panic()logrus.Fatal()logrus.Warn()logrus.Info()logrus.Debug()logrus.Trace()

例如,如果当前级别设置为Warn,则呼叫logrus.Warn("boo!")将输出boo!。但是,调用logrus.Info("boo!")不会显示任何内容。