如何在Go中处理configuration
我是Go编程的新手,我想知道:Go程序的configuration参数的首选方法是什么(在其他上下文中,可能使用属性文件或ini文件)?
JSON格式对我很有帮助。 标准库提供了缩写数据结构的方法,所以它非常易读。
另请参阅golang-nuts线程 。
JSON的好处在于,parsing和人类可读/可编辑性相当简单,同时为列表和映射提供语义(这可以变得相当方便),而许多initypes的configurationparsing器则不是这种情况。
用法示例:
conf.json :
{ "Users": ["UserA","UserB"], "Groups": ["GroupA"] }
编程读取configuration
import ( "encoding/json" "os" "fmt" ) type Configuration struct { Users []string Groups []string } file, _ := os.Open("conf.json") decoder := json.NewDecoder(file) configuration := Configuration{} err := decoder.Decode(&configuration) if err != nil { fmt.Println("error:", err) } fmt.Println(configuration.Users) // output: [UserA, UserB]
另一种select是使用TOML ,这是Tom Preston-Werner创build的类似INI的格式。 我为它构build了一个 经过广泛testing 的Goparsing器 。 你可以像在这里提出的其他选项一样使用它。 例如,如果在something.toml
有这个TOML数据
Age = 198 Cats = [ "Cauchy", "Plato" ] Pi = 3.14 Perfection = [ 6, 28, 496, 8128 ] DOB = 1987-07-05T05:45:00Z
然后你可以用类似的东西把它加载到你的Go程序中
type Config struct { Age int Cats []string Pi float64 Perfection []int DOB time.Time } var conf Config if _, err := toml.DecodeFile("something.toml", &conf); err != nil { // handle error }
我通常使用JSON来获得更复杂的数据结构。 不利的一面是,你很容易得到一堆代码来告诉用户错误在哪里,各种各样的边缘情况,什么不是。
对于基本configuration(API密钥,端口号,…)我已经很好运气与gcfg包。 它基于gitconfiguration格式。
从文档:
示例configuration:
; Comment line [section] name = value # Another comment flag # implicit value for bool is true
去结构:
type Config struct { Section struct { Name string Flag bool } }
而代码需要阅读它:
var cfg Config err := gcfg.ReadFileInto(&cfg, "myconfig.gcfg")
它也支持切片值,所以你可以允许多次指定一个键和其他好的function。
Viper是一个golangconfigurationpipe理系统,与JSON,YAML和TOML一起工作。 它看起来很有趣。
只要用iniflags标准的去标志 。
标准去标志有以下好处:
- 成语。
- 使用方便。 标志可以很容易地添加和散布在您的项目使用的任意包。
- 标志对默认值和描述具有开箱即用的支持。
- 标志提供具有默认值和描述的标准“帮助”输出。
标志唯一的缺点标志有 – 当您的应用程序中使用的标志数量变得太大时,是pipe理问题。
Iniflags优雅地解决了这个问题:只修改你的主包中的两行,它神奇地获得从ini文件读取标志值的支持。 ini文件中的标志可以通过在命令行中传递新值来重写。
有关详细信息,另请参阅https://groups.google.com/forum/#!topic/golang-nuts/TByzyPgoAQE 。
我已经开始使用使用Ini文件的Gcfg 。 这很简单 – 如果你想要一些简单的东西,这是一个不错的select。
这里是我目前使用的加载代码,它具有默认设置,并允许覆盖我的一些configuration的命令行标志(未示出):
package util import ( "code.google.com/p/gcfg" ) type Config struct { Port int Verbose bool AccessLog string ErrorLog string DbDriver string DbConnection string DbTblPrefix string } type configFile struct { Server Config } const defaultConfig = ` [server] port = 8000 verbose = false accessLog = - errorLog = - dbDriver = mysql dbConnection = testuser:TestPasswd9@/test dbTblPrefix = ` func LoadConfiguration(cfgFile string, port int, verbose bool) Config { var err error var cfg configFile if cfgFile != "" { err = gcfg.ReadFileInto(&cfg, cfgFile) } else { err = gcfg.ReadStringInto(&cfg, defaultConfig) } PanicOnError(err) if port != 0 { cfg.Server.Port = port } if verbose { cfg.Server.Verbose = true } return cfg.Server }
看看gonfig
// load config, _ := gonfig.FromJson(myJsonFile) // read with defaults host, _ := config.GetString("service/host", "localhost") port, _ := config.GetInt("service/port", 80) test, _ := config.GetBool("service/testing", false) rate, _ := config.GetFloat("service/rate", 0.0) // parse section into target structure config.GetAs("service/template", &template)
我在golang写了一个简单的iniconfiguration库。
goroutine安全,易于使用
package cfg import ( "testing" ) func TestCfg(t *testing.T) { c := NewCfg("test.ini") if err := c.Load() ; err != nil { t.Error(err) } c.WriteInt("hello", 42) c.WriteString("hello1", "World") v, err := c.ReadInt("hello", 0) if err != nil || v != 42 { t.Error(err) } v1, err := c.ReadString("hello1", "") if err != nil || v1 != "World" { t.Error(err) } if err := c.Save(); err != nil { t.Error(err) } }
===================更新=======================
最近我需要一个支持段的INIparsing器,然后我写一个简单的包:
github.com/c4pt0r/cfg
你可以像使用“flag”包一样parsingINI:
package main import ( "log" "github.com/c4pt0r/ini" ) var conf = ini.NewConf("test.ini") var ( v1 = conf.String("section1", "field1", "v1") v2 = conf.Int("section1", "field2", 0) ) func main() { conf.Parse() log.Println(*v1, *v2) }
像这篇文章一样使用toml 读取configuration文件的Go方式
您可能还对go-libucl感兴趣 ,这是一组用于UCL的Go绑定(通用configuration语言)。 UCL有点像JSON,但对人类有更好的支持:它支持像SI乘法器(10k,40M等)的注释和人类可读的构造,并且具有less许样板(例如围绕键的引号)。 它实际上非常接近nginxconfiguration文件格式,如果你已经熟悉了。
我同意尼莫 ,我写了一个小工具,使它真的很容易。
bitbucket.org/gotamer/cfg是一个jsonconfiguration包
- 你在应用程序中将你的configuration项定义为一个结构体。
- 您的结构中的jsonconfiguration文件模板将在第一次运行时保存
- 您可以将运行时修改保存到configuration中
请参阅doc.go以获取示例
我试过JSON。 有效。 但我讨厌创build我可能设置的确切字段和types的结构。 对我来说这是一个痛苦。 我注意到这是我能find的所有configuration选项所使用的方法。 也许我对dynamic语言的背景使我对这种冗长的好处一无所知。 我做了一个新的简单的configuration文件格式,和一个更dynamic的ish库读出来。
https://github.com/chrisftw/ezconf
我对Go世界很新,所以可能不是Go的方式。 但它的工作原理,它非常快,使用起来非常简单。
优点
- 超级简单
- 代码less
缺点
- 无数组或地图types
- 非常平坦的文件格式
- 非标准的conf文件
- 有一个内置的小惯例,我现在如果一般在Go社区皱起了眉头。 (在config目录下查找configuration文件)