Goでの構成の処理方法[終了]


284

私はGoプログラミングの初心者ですが、疑問に思っています。Goプログラムの構成パラメーターを処理するための好ましい方法は何ですか(他のコンテキストでは、プロパティファイルやiniファイルを使用するようなものです)。


また、いくつかの追加のアイデアがあるgolang-nutsスレッドを開始しました。
theglauber 2013年

2
シェルスクリプトと環境変数を使用する傾向があります。
15

3
私は、ブログの投稿「Persisting Application Configuration In Go」全体を取り上げて、jsonとYAMLという2つの最も一般的な形式の例を使用して、その方法を説明しました。例は生産準備が整っています。
upitau

参考までに、コメントをサポートし、JSONおよびUCL互換のHashiCorpのHCLがあります。github.com/hashicorp/hcl
Kaveh Shahbazian 2017

回答:


244

JSONのフォーマットは非常によく私のために働きました。標準ライブラリは、インデントされたデータ構造を書き込むメソッドを提供するため、非常に読みやすくなっています。

このgolang-nutsスレッドも参照してください。

JSONの利点は、リストとマッピングのセマンティクスを提供しながら(かなり便利になる可能性があります)、解析と人間による読み取り/編集がかなり簡単であることです。これは、多くのiniタイプの構成パーサーには当てはまりません。

使用例:

conf.json

{
    "Users": ["UserA","UserB"],
    "Groups": ["GroupA"]
}

設定を読み取るプログラム

import (
    "encoding/json"
    "os"
    "fmt"
)

type Configuration struct {
    Users    []string
    Groups   []string
}

file, _ := os.Open("conf.json")
defer file.Close()
decoder := json.NewDecoder(file)
configuration := Configuration{}
err := decoder.Decode(&configuration)
if err != nil {
  fmt.Println("error:", err)
}
fmt.Println(configuration.Users) // output: [UserA, UserB]

6
JSONは現在の選択肢の中で最も悪いものではないようです。私はgo-yamlを調べましたが、それは勇敢な取り組みですが、ドキュメントの不足を別の場所で見る必要があることを示すものとしてとらえました。goiniは、Windowsのiniファイルを処理するためのシンプルで簡単なライブラリのようです。TOMLと呼ばれる新しい形式が提案されていますが、問題あります。この時点では、JSONまたはiniを使用します。
theglauber 2013年

6
YAMLはコメントをサポートします(設定ファイルのどこにでもメモを追加したい場合)。
Ivan Black

42
これを読んでその道を進む人には注意してください:JSONのコメントがないと、JSONは人間が使用できる構成ファイル(imo)には適さなくなります。これはデータ交換形式です-構成ファイルに役立つ/説明的なコメントを書き込む機能を失うと、保守性が損なわれる可能性があります(「この設定がアクティブになっている理由」、「何をするのか」、「有効な値は何か」 ?」など)。
Darian Moody

6
ああ-私は自分のコードでそれを試してみましたが、構造属性を大文字で定義するのを忘れていました(エクスポートされませんでした)-これは私の人生の1時間を費やしました。多分他の人が同じエラーを犯す>警告される; D
JohnGalt

6
おそらくdefer file.Close()、open errをチェックした後
Gabriel

97

もう1つのオプションは、Tom Preston-Wernerによって作成されたINIのような形式であるTOMLを使用することです。私はそれのために行くパーサに構築されて広範囲にテストを。ここで提案されている他のオプションと同様に使用できます。たとえば、このTOMLデータがある場合something.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
}

18
TOMLが好きなのは、改行または行の構成設定の最後にコメントを記述できるためです。JSONではそれができません。
sergserg 2014年

構成の更新ごとに、非常に煩わしいコードの更新が必要です。
hywak

4
設定へのあらゆるアプローチが行います。プログラムは他にどのように新しい構成を認識しますか?
BurntSushi5

@ BurntSushi5コードが気にしない余分なフィールドをTomlファイルに含めることができますか?つまり、新しいバージョンの構成ファイルを古いバージョンのコードで使用できますか?私の場合、未使用の構成オプションを無視してもかまいません。
user1952500 2018年

2
私はそれが好きです。よくできました。個人的には、JSONよりも管理者や顧客がTOMLファイルを変更する方が簡単だと思います。
blndev 2018年

49

Viperは、JSON、YAML、およびTOMLで動作するgolang構成管理システムです。かなり面白いですね。


1
12factorアプリケーションで特に実行可能12factor.net
DerKnorr

GoでJSON構成にgonfigを使用します。github.com/eduardbcom/gonfig
エデュアルドボンダレンコ

1
Viperは使用しないでください。スレッドセーフではなく、ほとんどの場合発火しました。
igonejack

@igonejackバイパーがあなたを噛んだ場所の例を教えてください。
Dr.eel

1
@ Dr.eel別のviルーチンで別のviper.GetBool( "abc")とViper.Set( "abc"、false)を試してください。
igonejack

44

私は通常、より複雑なデータ構造にJSONを使用します。欠点は、エラーの場所、さまざまなエッジケース、およびそうでないものをユーザーに知らせるためのコードの束が簡単に作成されることです。

基本構成(APIキー、ポート番号など)については、gcfgパッケージで非常にうまくいきました。git config形式に基づいています。

ドキュメントから:

サンプル構成:

; 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")

また、スライス値もサポートしているため、キーを複数回指定したり、その他の便利な機能を指定したりできます。


4
gcfgの最初の作成者はプロジェクトを中止し、関連する別のsconfを開始しました
iwat

39

iniflagsで標準のgoフラグを使用するだけです

標準のgoフラグには次の利点があります。

  • 慣用的。
  • 使いやすい。フラグは簡単に追加でき、プロジェクトが使用する任意のパッケージに分散できます。
  • フラグは、デフォルト値と説明をすぐにサポートします。
  • フラグは、デフォルト値と説明を含む標準の「ヘルプ」出力を提供します。

標準のgoフラグの唯一の欠点は、アプリで使用されるフラグの数が多すぎる場合の管理の問題です。

Iniflagsはこの問題をエレガントに解決します。メインパッケージの2行を変更するだけで、魔法のようにiniファイルからフラグ値を読み取ることができます。iniファイルのフラグは、コマンドラインで新しい値を渡すことで上書きできます。

詳細については、https://groups.google.com/forum/#!topic / golang-nuts / TByzyPgoAQEご覧ください。


自分が取り組んでいるプロジェクト(最初から最初から最初のgolangプロジェクト)にフラグを使用し始めましたが、テストなどを処理する方法を知りたいですか?たとえば、これはapiクライアントであり、フラグを使用したいのgo testですが、構成ファイルではできませんが、テストが複雑になりすぎる(フラグを渡さない)ようです。
zachaysan 2015年

テストからのフラグを設定することは簡単です:*FlagName = value
スティーブンSoroka

9
ここに実際の例を示す詳細なサンプルコードがある場合、非常に役立ちます:)
zero_cool

別の言語で記述された他のアプリケーションと構成を共有する必要がある場合は、良い考えではありません。
キルジラ2016年

フラグの代わりにpflagsを使用することをお勧めします。pflagsはposix標準を使用しています
Fjolnir Dvorak '30

12

Iniライクなファイルを使用するGcfgを使い始めました。それは単純です-単純なものが必要な場合、これは良い選択です。

これは私が現在使用しているロードコードです。デフォルトの設定があり、一部の構成をオーバーライドするコマンドラインフラグ(図示せず)を許可します。

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
}

2
これは、Askがすでに述べたとおりではありませんか?
nemo

8

ゴンフィグを見てください

// 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)

goで構成構造全体を再定義する必要がないため、これは適切です
thanhpk



5

golangで簡単なini構成ライブラリを作成しました。

https://github.com/c4pt0r/cfg

ゴロチン安全、使いやすい

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

===================更新=======================

最近、セクションをサポートするINIパーサーが必要になり、単純なパッケージを作成します。

github.com/c4pt0r/cfg

uは、「フラグ」パッケージを使用するようにINIを解析できます。

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

4

ユニバーサル構成言語であるUCLのGoバインディングのセットであるgo-libuclにも興味があるかもしれません。UCLはJSONに少し似ていますが、人間に対するサポートが強化されています。コメントと、SI乗数(10k、40Mなど)などの人間が読める構造をサポートし、ボイラープレート(たとえば、キーの周りの引用符)が少し少なくなっています。慣れていれば、実際はnginx構成ファイルの形式にかなり近いです。


2

私はネモに同意し、それをすべて本当に簡単にするための小さなツールを書きました。

bitbucket.org/gotamer/cfgはjson構成パッケージです

  • アプリケーションの構成アイテムを構造体として定義します。
  • 構造体のjson構成ファイルテンプレートは、最初の実行時に保存されます
  • ランタイムの変更を構成に保存できます

例については、doc.goを参照してください


1

JSONを試しました。出来た。しかし、私は設定している可能性のある正確なフィールドとタイプの構造体を作成する必要がありません。私にとってそれは苦痛でした。私が見つけたすべての構成オプションで使用されている方法に気づきました。たぶん、動的言語の私のバックグラウンドは、そのような冗長性の利点を私に盲目にさせます。新しいシンプルな構成ファイル形式を作成し、それを読み取るための動的なライブラリを作成しました。

https://github.com/chrisftw/ezconf

私は囲碁の世界ではかなり新しいので、囲碁のやり方ではないかもしれません。しかし、それは機能し、それはかなり速く、使用するのは非常に簡単です。

長所

  • 超シンプル
  • 少ないコード

短所

  • 配列またはマップタイプなし
  • 非常にフラットなファイル形式
  • 非標準のconfファイル
  • 小さな規約が組み込まれていますが、Goコミュニティで一般的に嫌われている場合は、これを使用します。(configディレクトリでconfigファイルを探します)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.