golang常用库之-kelseyhightower/envconfig | 读取和设置环境变量、根据环境变量填充指定的结构

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"}

猜你喜欢

转载自blog.csdn.net/inthat/article/details/127085620