文章目录
golang常用库之-kelseyhightower/envconfig | 读取和设置环境变量、根据环境变量填充指定的结构
背景-读取和设置环境变量
除了读取文件和命令行传递参数外,环境变量是另一个向应用传递参数的方式。
什么是kelseyhightower/envconfig包
github: https://github.com/kelseyhightower/envconfig
Golang库,用于管理环境变量的配置数据。
使用os包可以很容易的设置和读取环境变量。第三方库envconfig使用结构体tag将环境变量映射给结构体的方式很方便。
使用的核心就是,调用envconfig.Process
根据环境变量填充指定的结构
err := envconfig.Process(envPrefix, config)
代码demo
官方demo: 读取环境变量
设置一些环境变量:
export MYAPP_DEBUG=false
export MYAPP_PORT=8080
export MYAPP_USER=Kelsey
export MYAPP_RATE="0.5"
export MYAPP_TIMEOUT="3m"
export MYAPP_USERS="rob,ken,robert"
export MYAPP_COLORCODES="red:1,green:2,blue:3"
package main
import (
"fmt"
"log"
"time"
"github.com/kelseyhightower/envconfig"
)
type Specification struct {
Debug bool
Port int
User string
Users []string
Rate float32
Timeout time.Duration
ColorCodes map[string]int
}
func main() {
var s Specification
err := envconfig.Process("myapp", &s)
if err != nil {
log.Fatal(err.Error())
}
format := "Debug: %v\nPort: %d\nUser: %s\nRate: %f\nTimeout: %s\n"
_, err = fmt.Printf(format, s.Debug, s.Port, s.User, s.Rate, s.Timeout)
if err != nil {
log.Fatal(err.Error())
}
fmt.Println("Users:")
for _, u := range s.Users {
fmt.Printf(" %s\n", u)
}
fmt.Println("Color codes:")
for k, v := range s.ColorCodes {
fmt.Printf(" %s: %d\n", k, v)
}
}
网上demo:从json文件和环境变量中捕获的配置
参考自:https://www.kancloud.cn/mutouzhang/gocookbook/693410
package main
import (
"bytes"
"encoding/json"
"fmt"
"github.com/kelseyhightower/envconfig"
"github.com/pkg/errors"
"io/ioutil"
"os"
)
// Config 将保存我们从json文件和环境变量中捕获的配置
type Config struct {
Version string `json:"version" required:"true"`
IsSafe bool `json:"is_safe" default:"true"`
Secret string `json:"secret"`
}
// LoadConfig将从存储在路径中的json文件中选择加载文件,
// 然后根据envconfig struct标记覆盖这些值。
// envPrefix是我们为环境变量添加的前缀。
func LoadConfig(path, envPrefix string, config interface{}) error {
if path != "" {
err := LoadFile(path, config)
if err != nil {
return errors.Wrap(err, "error loading config from file")
}
}
// envconfig.Process根据环境变量填充指定的结构
err := envconfig.Process(envPrefix, config)
return errors.Wrap(err, "error loading config from env")
}
// LoadFile 解析一个json文件并填充到config中
func LoadFile(path string, config interface{}) error {
configFile, err := os.Open(path)
if err != nil {
return errors.Wrap(err, "failed to read config file")
}
defer configFile.Close()
decoder := json.NewDecoder(configFile)
if err = decoder.Decode(config); err != nil {
return errors.Wrap(err, "failed to decode config file")
}
return nil
}
func main() {
var err error
// 建立一个临时json配置文件
tf, err := ioutil.TempFile("", "tmp")
if err != nil {
panic(err)
}
defer tf.Close()
defer os.Remove(tf.Name())
// json 配置文件的内容
secrets := `{
"secret": "so so secret"
}`
if _, err = tf.Write(bytes.NewBufferString(secrets).Bytes()); err != nil {
panic(err)
}
// 向环境变量中添加变量及对应值
if err = os.Setenv("EXAMPLE_VERSION", "1.0.0"); err != nil {
panic(err)
}
if err = os.Setenv("EXAMPLE_ISSAFE", "false"); err != nil {
panic(err)
}
c := Config{}
// 从文件中读取配置参数
if err = LoadConfig(tf.Name(), "EXAMPLE", &c); err != nil {
panic(err)
}
fmt.Println("secrets file contains =", secrets)
// 获取环境变量参数及对应值
fmt.Println("EXAMPLE_VERSION =", os.Getenv("EXAMPLE_VERSION"))
fmt.Println("EXAMPLE_ISSAFE =", os.Getenv("EXAMPLE_ISSAFE"))
// c既保存了json配置文件的参数也保存了环境变量的参数 我们将其打印
fmt.Printf("Final Config: %#v\n", c)
}
结果:
secrets file contains = {
"secret": "so so secret"
}
EXAMPLE_VERSION = 1.0.0
EXAMPLE_ISSAFE = false
Final Config: main.Config{Version:"1.0.0", IsSafe:false, Secret:"so so secret"}