Viper是golang的一个管理配置文件的工具,它支持JSON、TOML、YAML、HCL、envfile、Java properties。它支持以下特性:
设置默认值
从JSON、 TOML、 YAML、 HCL、INI、 envfile和 Java properties格式的配置文件读取配置信息
实时监控和重新读取配置文件(可选)
从环境变量中读取
从远程配置系统(etcd或Consul) 读取并监控配置变化
从命令行参数读取配置
从buffer读取配置
显式配置值
Viper优先级:
显示调用 Set设置值
命令行参数 (flag)
环境变量
配置文件
key/value存储
默认值
注意:
viper是大小写敏感的
把
Viper库的安装:
go get github.com/spf13/viper
viper的简单使用:
func ReadFromConfig() {
config := viper.New() //创建一个viper文件
config.AddConfigPath("./config") //配置文件所在目录
//config.SetConfigFile("./config.yaml") // 指定配置文件路径
//config.AddConfigPath("$HOME/.appname") // 多次调用以添加多个搜索路径
config.SetConfigName("account") //文件名
config.SetConfigType("json") //文件类型,配置文件的后缀
if err := config.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
panic("找不到配置文件")
} else {
panic(err)
}
}
//读取配置
user1 := config.GetString("section1.user")
user2 := config.GetString("section2.user")
height := config.GetInt32("section1.body.height")
weight := config.GetInt32("section1.body.weight")
fmt.Println(user1, user2, height, weight)
}
viper的其它用法
//设置配置的默认值
config.SetDefault("ContentKey", "content")
//写入配置文件
WriteConfig - 将当前的viper配置写入预定义的路径并覆盖(如果存在的话)。如果没有预定义的路径,则报错。
SafeWriteConfig - 将当前的viper配置写入预定义的路径。如果没有预定义的路径,则报错。如果存在内容,将不会覆盖当前的配置文件。
WriteConfigAs - 将当前的viper配置写入给定的文件路径。将覆盖给定的文件(如果它存在的话)。
SafeWriteConfigAs - 将当前的viper配置写入给定的文件路径。如果存在内容,不会覆盖给定的文件(如果它存在的话)。
监控并重新读取配置
Viper支持在运行时实时读取配置文件的功能。
需要重新启动服务器以使配置生效的日子已经一去不复返了,viper驱动的应用程序可以在运行时读取配置文件的更新,而不会错过任何消息。
只需告诉viper实例watchConfig。可选地,你可以为Viper提供一个回调函数,以便在每次发生更改时运行。
config.SetDefault("ContentDir", "content")
config.SetDefault("LayoutDir", "layouts")
config.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"})
config.WatchConfig()
config.OnConfigChange(func(in fsnotify.Event) {
fmt.Println("Config file changed:", in.Name)
config.ReadInConfig()
get := config.Get("ContentDir")
fmt.Println("contentdir:", get.(string))
})
注册和使用别名
config.RegisterAlias("contentdir", "dir") //创建一个新字段dir,当修改contentdir时,dir也会改变,修改dir时,contentdir也会改变
config.Set("contentdir", "/test") //覆盖contentdir,SetDefault是指当contentdir没值时才会set
json配置的获取
{
"datastore.metric.host": "0.0.0.0",
"host": {
"address": "localhost",
"port": 5799
},
"datastore": {
"metric": {
"host": "127.0.0.1",
"port": 3099
},
"warehouse": {
"host": "198.0.0.1",
"port": 2112
}
}
}
config := viper.New()
config.AddConfigPath("./")
config.SetConfigName("account")
config.SetConfigType("json")
err := config.ReadInConfig()
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
panic("config file not found")
} else if err != nil {
panic(err)
}
fmt.Println(config.GetString("host.address")) //通过.来获取json中的嵌套字段
使用环境变量:
SetEnvPrefix:用于不知道环境变量名时,viper自动查找的时候加的前缀名,BindEnv和AutomaticEnv都将使用这个前缀
config.SetEnvPrefix("spf") //自动将spf转为大写
BindEnv使用一个或者两个参数:第一个参数是键名称,第二个参数是环境变量名。环境变量的名称区分大小写。如果没有指定环境变量名,会把“前缀+“_”+键名全部大写”。作为默认的环境变量名。如果包含两个参数时,它不会自动加前缀
config.BindEnv("id") //一个参数时,使用SPF_ID作为默认的环境变量值
config.BindEnv("id","ID") //将ID绑定到id变量上
id:=config.Get("id")
获取子树
contentdir: /dir
dir: /dir
layoutdir: layouts
mysql:
dbname: sql_demo
host: 127.0.0.1
port: 13306
port: 8081
taxonomies:
category: categories
tag:
test: 1
test2: 2
subv := config.Sub("taxonomies.tag") //获取的是tag下的所有内容
fmt.Println(subv.GetInt("test"))
从json对象直接Unmarshal出值
type Config struct {
Port int `json:"port"`
Version string `json:"version"`
}
var Conf = new(Config)
func ReadFromConfig() {
config := viper.New()
config.AddConfigPath("./")
config.SetConfigName("account")
config.SetConfigType("json")
err := config.ReadInConfig()
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
panic("config file not found")
} else if err != nil {
panic(err)
}
if err := config.Unmarshal(&Conf); err != nil {
panic(err)
}
fmt.Println(Conf.Port, Conf.Version)
}