• 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"}
    
  • 相关阅读:
    windows安装docker
    一个合格的高级开发,首先应该写的一手好注释。
    Lazarus网络编程
    【Web】CSS学习笔记之浮动*
    Linux内核性能剖析的方法学和主要工具
    学习笔记-配置备份静态路由及优先级
    Spring Boot框架下实现Excel服务端导入导出
    SingleStore数据库,离开 HTAP,人工智能是不切实际的
    工作中整理的常用的Linux命令
    基于SSM滑雪场预约管理系统设计与实现
  • 原文地址:https://blog.csdn.net/inthat/article/details/127085620