如何在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库。

https://github.com/c4pt0r/cfg

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文件)