viper 简介
Viper 是 Go 应用程序的完整配置解决方案,包括 12-Factor 应用程序。它旨在在应用程序中工作,并且可以处理所有类型的配置需求和格式。它支持:
- 设置默认值
- 从 JSON、TOML、YAML、HCL、envfile 和 Java 属性配置文件中读取
- 实时观看和重新读取配置文件(可选)
- 从环境变量中读取
- 从远程配置系统(etcd 或 Consul)读取,并观察变化
- 从命令行标志读取
- 从缓冲区读取
- 设置显式值
读取配置文件
app.yaml
1
2
3
4
5
6
|
server:
host: 0.0.0.0
port: 9090
log:
level: debug
format: json
|
main.go
创建配置文件结构体
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
var cfg Cfg
type Cfg struct {
Server Server `yaml:"server"`
Log Log `yaml:"log"`
}
type Server struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
}
type Log struct {
Level string `yaml:"level"`
Format string `yaml:"format"`
}
|
使用 viper 读取配置文件并解析到结构体
1
2
3
4
5
6
7
8
9
10
11
12
|
func initConfig() {
viper.AddConfigPath("./")
viper.SetConfigName("apps")
viper.SetConfigType("yaml")
if err := viper.ReadInConfig(); err != nil {
log.Fatalf("read config file failed, %v", err)
}
if err := viper.Unmarshal(&cfg); err != nil {
log.Printf("unmarshal config file failed, %v", err)
}
log.Printf("%#v", cfg)
}
|
设置日志相关参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
func initLog() {
switch strings.ToLower(cfg.Log.Level) {
case "panic":
logrus.SetLevel(logrus.PanicLevel)
case "fatal":
logrus.SetLevel(logrus.FatalLevel)
case "error":
logrus.SetLevel(logrus.ErrorLevel)
case "warn", "warning":
logrus.SetLevel(logrus.WarnLevel)
case "info":
logrus.SetLevel(logrus.InfoLevel)
case "debug":
logrus.SetLevel(logrus.DebugLevel)
case "trace":
logrus.SetLevel(logrus.TraceLevel)
default:
logrus.SetLevel(logrus.InfoLevel)
}
switch strings.ToLower(cfg.Log.Format) {
case "json":
logrus.SetFormatter(&logrus.JSONFormatter{})
case "text":
logrus.SetFormatter(&logrus.TextFormatter{})
default:
logrus.SetFormatter(&logrus.TextFormatter{})
}
}
|
main 函数
1
2
3
4
5
6
7
8
|
func main() {
r := gin.Default()
logrus.Debug("i'm a debug log")
logrus.Info("i'm a info log")
logrus.Warn("i'm a warn log")
logrus.Error("i'm a error log")
r.Run(cfg.Server.Host + ":" + strconv.Itoa(cfg.Server.Port))
}
|
go run main.go
输出结果
1
2
3
4
5
6
7
8
9
10
11
12
|
main.Cfg{Server:main.Server{Host:"0.0.0.0", Port:9090}, Log:main.Log{Level:"debug", Format:"json"}}
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
{"level":"debug","msg":"i'm a debug log","time":"2021-06-30T10:12:16+08:00"}
{"level":"info","msg":"i'm a info log","time":"2021-06-30T10:12:16+08:00"}
{"level":"warning","msg":"i'm a warn log","time":"2021-06-30T10:12:16+08:00"}
{"level":"error","msg":"i'm a error log","time":"2021-06-30T10:12:16+08:00"}
[GIN-debug] Listening and serving HTTP on 0.0.0.0:9090
|
可以看到已经从配置文件读取到配置了。
从环境变量读取配置
1.修改 initConfig 函数,开启自动注入环境变量功能
在读取配置文件之前使用 AutomaticEnv,并使用 SetEnvKeyReplacer 将".“替换为”_"
1
2
3
4
5
|
viper.SetConfigType("yaml")
viper.AutomaticEnv()
replacer := strings.NewReplacer(".", "_")
viper.SetEnvKeyReplacer(replacer)
if err := viper.ReadInConfig(); err != nil { }
|
环境变量的格式为:SERVER_PORT
2.运行测试
SERVER_PORT=10086 go run main.go
修改日志相关变量
LOG_LEVEL=info LOG_FORMAT=text go run main.go
参考
https://huangzhongde.cn/post/Golang/%E4%BD%BF%E7%94%A8viper%E8%AF%BB%E5%8F%96%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E5%B9%B6%E5%85%81%E8%AE%B8%E4%BD%BF%E7%94%A8%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F/