简介
viper是go语言配置文件的一个管理库,github star 23.2K
viper有以下特性:
- 设置默认值
- 从json, toml,yaml,envfile 和 java properties格式的配置文件读取配置信息
- 实时监控和重新读区配置文件
- 从远程配置系统(etcd或consul)读取并监控配置变化
- 从命令行参数读取配置
- 从buffer读区配置
- 设置显式值
get started
下面来看看viper的简单用法, 以config.yml
为例
#install
go get github.com/spf13/viper
目录结构:
package main
import (
"fmt"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
"log"
"os"
"path"
)
type Config struct {
Use string `mapstructure:"use"`
Cfg []Server `mapstructure:"cfg"`
}
type Server struct {
Name string `mapstructure:"name"`
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
Likes []string `mapstructure:"likes"`
}
func main() {
pth := path.Join(os.Getenv("GOPATH"), "src/github.com/scott-x/test")
// name of config file (without extension)
viper.SetConfigName("config")
// REQUIRED if the config file does not have the extension in the name
viper.SetConfigType("yaml")
// optionally look for config in the working directory
viper.AddConfigPath(".")
// path to look for the config file in
viper.AddConfigPath(pth)
err := viper.ReadInConfig() // Find and read the config file
if err != nil { // Handle errors reading the config file
panic(fmt.Errorf("fatal error config file: %w", err))
}
var config Config
if err = viper.Unmarshal(&config); err != nil {
panic("Unmarshal failed:" + err.Error())
}
log.Println(config)
go func() {
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("Config file changed:", e.Name)
})
viper.WatchConfig()
}()
}
运行:
在不修改源码的情况下实现线上线下环境分离
思路:
- 1,线下创建一个环境变量,如果能够读到就为debug模式,否则为生产模式
- 2,利用flag 命令行指定环境 eg:
xx -env debug
下面展示环境变量的用法,eg:
export TEST_ENV=1
代码结构:
package main
import (
"fmt"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
"log"
"os"
"path"
)
type Config struct {
Mysql `mapstructure:"mysql"`
}
type Mysql struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"prot"`
Username string `mapstructure:"username"`
}
func main() {
pth := path.Join(os.Getenv("GOPATH"), "src/github.com/scott-x/test/env")
var configFileName, env string
if myenv := os.Getenv("TEST_ENV"); len(myenv) > 0 {
env = "debug"
} else {
env = "pro"
}
configFileName = fmt.Sprintf("config-%s.yml", env)
log.Println("configFileName:", configFileName)
// name of config file (without extension)
viper.SetConfigName(configFileName)
// REQUIRED if the config file does not have the extension in the name
viper.SetConfigType("yaml")
// optionally look for config in the working directory
viper.AddConfigPath(".")
// path to look for the config file in
viper.AddConfigPath(pth)
err := viper.ReadInConfig() // Find and read the config file
if err != nil { // Handle errors reading the config file
panic(fmt.Errorf("fatal error config file: %w", err))
}
var config Config
if err = viper.Unmarshal(&config); err != nil {
panic("Unmarshal failed:" + err.Error())
}
log.Println(config)
go func() {
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("Config file changed:", e.Name)
})
viper.WatchConfig()
}()
}
不设置环境变量运行:
设置环境变量后运行: