文章博客地址:golang 使用 viper 加载配置 自动反序列化到结构
golang viper 其中可以用来 查找、加载和反序列化JSON、TOML、YAML、HCL、INI、envfile和格式的配置文件
配置文件 test_toml.toml
http_addr = ":8082"
grpc_addr = ":8083"
jaeger_url= "http://localhost:14268/api/traces"
tracing= true
golang代码
type ConfigTest struct {
HttpAddr string `json:"http_addr" toml:"http_addr" yaml:"http_addr"`
GrpcAddr string `json:"grpc_addr" toml:"grpc_addr" yaml:"grpc_addr"`
JaegerUrl string `json:"jaeger_url" toml:"jaeger_url" yaml:"jaeger_url" mapstructure:"jaeger_url"`
Tracing bool `toml:"tracing" json:"tracing" yaml:"tracing" ` // opentelemetry tracing
}
// jaeger 加载配置文件
func TestSourceFile_Unmarshal(t *testing.T) {
filePath := "./test_toml.toml"
viper.SetConfigFile(filePath)
if err := viper.ReadInConfig(); err != nil {
t.Error(err)
}
c := &ConfigTest{}
if err := viper.Unmarshal(c); err != nil {
t.Error(err)
}
logger.Infow("Unmarshal file sucess", "v", c)
}
打印返序列化的配置结构
{"level":"info","ts":"2023-08-27T21:35:27.041+0800","caller":"config/source_file_test.go:31","msg":"Unmarshal file sucess","v":{"http_addr":"","grpc_addr":"","jaeger_url":"http://localhost:14268/api/traces","tracing":true}}
可以看到带下划线的字段,不加 mapstructure 标签,是不会反序列化
func (v *Viper) Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error {
return decode(v.AllSettings(), defaultDecoderConfig(rawVal, opts...))
}
func decode(input interface{}, config *mapstructure.DecoderConfig) error {
decoder, err := mapstructure.NewDecoder(config)
if err != nil {
return err
}
return decoder.Decode(input)
}
func NewDecoder(config *DecoderConfig) (*Decoder, error) {
if config.TagName == "" {
config.TagName = "mapstructure"
}
// ...
}
func TestSourceFile_Unmarshal1(t *testing.T) {
filePath := "./test_toml.toml"
c := &ConfigTest{}
if err := viperUnmarshal(c, filePath); err != nil {
t.Error(err)
}
logger.Infow("Unmarshal file sucess", "v", c)
}
func viperUnmarshal(v interface{}, configPath string) error {
var tagName string
ext := filepath.Ext(configPath)
if len(ext) > 1 {
tagName = ext[1:]
}
// set decode tag_name, default is mapstructure
decoderConfigOption := func(c *mapstructure.DecoderConfig) {
c.TagName = tagName
}
cViper := viper.New()
cViper.SetConfigFile(configPath)
if err := cViper.ReadInConfig(); err != nil {
return err
}
return cViper.Unmarshal(v, decoderConfigOption)
}
{"level":"info","ts":"2023-08-27T21:35:34.553+0800","caller":"config/source_file_test.go:40","msg":"Unmarshal file sucess","v":{"http_addr":":8082","grpc_addr":":8083","jaeger_url":"http://localhost:14268/api/traces","tracing":true}}
我已将viper加载配置集成进自己的项目,完整example 代码可以查看 source_file_test.go