IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> 【Go】viper读取Go项目中的配置文件 -> 正文阅读

[开发工具]【Go】viper读取Go项目中的配置文件

引言

Viper是Go应用程序的完整配置解决方案,包括 12-Factor 应用程序。它设计用于在应用程序中工作,可以处理所有类型的配置需求和格式。它支持:

  • 设置默认值
  • 读取JSON、TOML、YAML、HCL、envfile和Java properties属性配置文件
  • 实时查看和重读配置文件(可选)
  • 从环境变量中读取
  • 从远程配置系统(etcd或Consor)读取数据,并观察变化
  • 从命令行标志读取
  • 从缓冲区读取
  • 设置显式值

Github地址:https://github.com/spf13/viper

基本用法

  • 本文以读取toml格式的配置文件为例子
  • 配置文件定义如下(config.toml)
[app]
port = 9000
init_models = false
loglevel = "debug"
logfile = "/tmp/app/log.log"
static_dir = "/tmp/app/static"
gateway = "localhost"

[secret]
jwt = "a-example-jwt-key"
package main

import (
	"fmt"
	"github.com/spf13/viper"
	"io/ioutil"
	"log"
	"os"
	"reflect"
	"strings"
)

//配置文件结构体,配置文件上的内容需要一一对应,可多不可少
type Configure struct {
	App struct {
		InitModels bool   `json:"init_models" remark:"是否初始化数据库模型" must:"false"`
		Port       int64  `json:"port" remark:"http端口"`
		Loglevel   string `json:"loglevel" remark:"日志级别"`
		Logfile    string `json:"logfile" remark:"日志文件"`
		StaticDir  string `json:"static_dir" remark:"静态文件目录"`
		Gateway    string `json:"gateway" remark:"网关服务器" must:"false"`
	}

	Secret struct {
		JWT string `json:"jwt" remark:"jwt密钥"`
	}
}

// 初始化viper
func initViper() {
	viper.SetConfigName("config") //指定配置文件的文件名称(不需要指定配置文件的扩展名)
	viper.AddConfigPath(".")      // 设置配置文件和可执行二进制文件在用一个目录
	viper.AutomaticEnv()          //自动从环境变量读取匹配的参数

	//读取-c输入的路径参数,初始化配置文件,如: ./main -c config.yaml
	if len(os.Args) >= 3 {
		if os.Args[1] == "-c" {
			cfgFile := os.Args[2]
			viper.SetConfigFile(cfgFile)
		}
	}

	// 根据以上配置读取加载配置文件
	err := viper.ReadInConfig()
	if err != nil {
		log.Fatal(err)
	}

	//使用配置文件
	file := viper.GetViper().ConfigFileUsed()
	configData, err := ioutil.ReadFile(file)
	if err != nil {
		log.Fatal(err)
	}
	//获取配置文件文本
	configText := strings.ReplaceAll(string(configData), "&", "|||")
	//构造Reader
	r := strings.NewReader(configText)

	err = viper.ReadConfig(r)
	if err != nil {
		log.Fatalf("初始化配置文件失败:%v", err)
	}
}

var Conf = &Configure{}

func main() {
	//初始化viper
	initViper()

	//reflect反射,将配置文件中的配置项通过viper导入Conf中
	confValue := reflect.ValueOf(Conf).Elem()
	confType := reflect.TypeOf(*Conf) //获取Configure中所有type

	for i := 0; i < confType.NumField(); i++ {
		section := confType.Field(i) //获取Configure中第i个type 例如i=0是为App
		sectionValue := confValue.Field(i)

		//读取节类型信息
		for j := 0; j < section.Type.NumField(); j++ {
			key := section.Type.Field(j)
			keyValue := sectionValue.Field(j)

			//获取当前部分配置的小写名称
			sec := strings.ToLower(section.Name) //配置文件节名
			remark := key.Tag.Get("remark")      //配置备注
			must := key.Tag.Get("must")          //配置备注
			tag := key.Tag.Get("json")           //配置键节名
			if tag == "" {
				err := fmt.Errorf("can not found a tag name `json` in struct of [%s].%s", sec, tag)
				log.Fatal(err)
				os.Exit(-1)
			}

			//绑定环境变量,会优先使用环境变量的值
			log.Printf("绑定环境变量 ENV_%s_%s ==> %s.%s", strings.ToUpper(sec), strings.ToUpper(tag), sec, tag)
			envKey := fmt.Sprintf("ENV_%s_%s", strings.ToUpper(sec), strings.ToUpper(tag))
			// 如果系统的环境变量中有名为envKey的环境变量则用系统的环境变量的值去覆盖配置中对应的配置项的值
			_ = viper.BindEnv(sec+"."+tag, envKey)
			fmt.Printf("获取的环境变量为:%v\n",os.Getenv(envKey))

			//根据类型识别配置字段
			switch key.Type.Kind() {
			case reflect.String:
				value := viper.GetString(sec + "." + tag)
				if value == "" && must != "false" {
					err := fmt.Errorf("get a blank value of must item [%s].%s %s", sec, tag, remark)
					log.Fatal(err)
					os.Exit(-1)
				}
				keyValue.SetString(value)

			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
				value := viper.GetInt64(sec + "." + tag)
				if value == 0 && must != "false" {
					err := fmt.Errorf("get a zero value of must item [%s].%s %s", sec, tag, remark)
					log.Fatal(err)
					os.Exit(-1)
				}
				keyValue.SetInt(value)

			case reflect.Bool:
				value := viper.GetBool(sec + "." + tag)
				keyValue.SetBool(value)

			case reflect.Slice:
				value := viper.GetStringSlice(sec + "." + tag)
				val := reflect.ValueOf(&value)
				keyValue.Set(val.Elem())

			default:
				log.Fatalf("unsupported config struct key type %T", key.Type.Kind())
			}
		}
	}
	log.Printf("The Result:%v\n",Conf)
}

  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2022-03-03 16:35:43  更:2022-03-03 16:37:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:21:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码