gpt4 book ai didi

go - 如何更改配置文件中的值未提供该值

转载 作者:行者123 更新时间:2023-12-03 02:24:57 26 4
gpt4 key购买 nike

我想在环境变量/配置属性值更改时进行一些监视我发现 viper 应该支持这种情况,但不能使其发挥作用。我看到调用了 OnConfigChange 但配置中的值更改时不会从配置中获取。配置加载成功

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

文件cfg.go

go/src/myproj/configuration/cfg.go

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)
}

我创建了一些示例 Web 应用程序服务器以使程序在后台运行(能够更改配置并查看wheatear 的某些内容发生了变化)

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:])
}

问题是函数GetLogLevel()带来了旧值并且没有从配置中读取值?

这是配置文件的示例(我将其与根项目文件夹下的 main.go 文件同级

这是项目结构

go/src/myproj
- main.go
- configuration #folder
-- cfg.go
- config.yaml
data:
config.yaml: 'log: debug'

当我将其从 info 更改为 debug (或其他选项)时,我看到事件 watch 已引发,但是它不会获取新值(如调试)。有什么想法吗?

更新当我像@Tom建议的那样更改配置文件时,我能够看到日志发生了变化,但没有看到级别,它保持在 warn

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

WARN[0000] loading config                                path=./config.yaml
WARN[0000] setting log level fields.level=info
&{0xc00012e300}
WARN[0008] Config file changed file=config.yaml
WARN[0008] setting log level fields.level=error
WARN[0020] Config file changed file=config.yaml
WARN[0020] setting log level fields.level=debug
WARN[0060] Config file changed file=config.yaml
WARN[0060] setting log level fields.level=warn

最佳答案

据我所知,您的代码没有任何问题,因为 fsnotify 确实触发了。所以罪魁祸首一定是在解析中。在 onConfigChange 回调之外首次调用 setLogLevel(c.GetLogLevel()) 将返回不正确的值。将 yaml 文件的内容更改为

log: 'level'

一切都应该按预期工作。

logrus 包按顺序支持以下级别(截至撰写本文时):PanicFatalError警告信息调试跟踪。对应的方法有:logrus.Panic()logrus.Fatal()logrus.Warn()logrus.Info ()logrus.Debug()logrus.Trace()

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

关于go - 如何更改配置文件中的值未提供该值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57852250/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com