简介
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()
  }()
}
不设置环境变量运行:

设置环境变量后运行:

