当环境变量/配置属性值更改时,我想做些观察
我发现毒蛇应该支持这种情况,但无法
使它工作。
我看到调用了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
答案 0 :(得分:1)
就我所知,您的代码没有错,因为fsnotify
确实可以触发。因此,罪魁祸首必须是解析。在setLogLevel(c.GetLogLevel())
回调之外对onConfigChange
的首次调用返回错误的值。将您的Yaml文件的内容更改为公正
log: 'level'
所有功能都应按要求工作。
logrus软件包按顺序支持以下级别(截至撰写本文时):Panic
,Fatal
,Error
,Warn
,Info
,Debug
和Trace
。相应的方法是:logrus.Panic()
,logrus.Fatal()
,logrus.Warn()
,logrus.Info()
,logrus.Debug()
和logrus.Trace()
。
例如,如果当前级别设置为Warn
,则呼叫logrus.Warn("boo!")
将输出boo!
。但是,调用logrus.Info("boo!")
不会显示任何内容。