it-swarm.com.de

So gehen Sie mit der Konfiguration in Go um

Ich bin neu in der Go-Programmierung und frage mich, wie man Konfigurationsparameter für ein Go-Programm am besten handhabt (die Art der Dinge, die man verwenden könnte Eigenschaften Dateien oder ini Dateien für, in anderen Kontexten)?

273
theglauber

Das Format JSON hat bei mir ganz gut funktioniert. Die Standardbibliothek bietet Methoden zum Schreiben der eingerückten Datenstruktur, sodass sie gut lesbar ist.

Siehe auch dieses Golang-Nuts-Gewinde .

Die Vorteile von JSON sind, dass es recht einfach zu analysieren und von Menschen lesbar/bearbeitbar ist, während Semantik für Listen und Zuordnungen angeboten wird (was sehr praktisch sein kann), was bei vielen Konfigurationsparsern vom Typ ini nicht der Fall ist.

Anwendungsbeispiel:

conf.json :

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

Programm zum Auslesen der Konfiguration

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]
236
nemo

Eine andere Option ist die Verwendung von TOML , einem INI-ähnlichen Format, das von Tom Preston-Werner erstellt wurde. Ich habe einen Go-Parser dafür gebaut das ist ausgiebig getestet . Sie können es wie andere hier vorgeschlagene Optionen verwenden. Wenn Sie zum Beispiel diese TOML-Daten in something.toml Haben

Age = 198
Cats = [ "Cauchy", "Plato" ]
Pi = 3.14
Perfection = [ 6, 28, 496, 8128 ]
DOB = 1987-07-05T05:45:00Z

Dann kannst du es mit so etwas wie in dein Go-Programm laden

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
}
92
BurntSushi5

Viper ist ein Golang-Konfigurationsverwaltungssystem, das mit JSON, YAML und TOML zusammenarbeitet. Es sieht ziemlich interessant aus.

46
Micah

Normalerweise verwende ich JSON für kompliziertere Datenstrukturen. Der Nachteil ist, dass Sie leicht mit einer Reihe von Code enden, um dem Benutzer mitzuteilen, wo der Fehler war, verschiedene Edge-Fälle und was nicht.

Für die Basiskonfiguration (API-Schlüssel, Portnummern, ...) hatte ich sehr viel Glück mit dem gcfg -Paket. Es basiert auf dem git config Format.

Aus der Dokumentation:

Beispielkonfiguration:

; Comment line
[section]
name = value # Another comment
flag # implicit value for bool is true

Go struct:

type Config struct {
    Section struct {
            Name string
            Flag bool
    }
}

Und der Code, der zum Lesen benötigt wird:

var cfg Config
err := gcfg.ReadFileInto(&cfg, "myconfig.gcfg")

Es werden auch Slice-Werte unterstützt, sodass Sie einen Schlüssel mehrmals angeben können, und andere Nice-Funktionen wie diese.

44

Verwenden Sie einfach standard go flags mit iniflags .

Standard-Go-Flags bieten folgende Vorteile:

  • Idiomatisch.
  • Einfach zu verwenden. Flags können einfach hinzugefügt und auf beliebige Pakete verteilt werden, die in Ihrem Projekt verwendet werden.
  • Flags bieten eine sofort einsatzbereite Unterstützung für Standardwerte und -beschreibungen.
  • Flags bieten eine standardmäßige Hilfeausgabe mit Standardwerten und -beschreibungen.

Der einzige Nachteil, den standardmäßige Go-Flags haben, sind Verwaltungsprobleme, wenn die Anzahl der in Ihrer App verwendeten Flags zu groß wird.

Iniflags löst dieses Problem auf elegante Weise: Ändern Sie einfach zwei Zeilen in Ihrem Hauptpaket, und das Lesen von Flag-Werten aus der ini-Datei wird auf magische Weise unterstützt. Flags aus INI-Dateien können überschrieben werden, indem neue Werte in der Befehlszeile übergeben werden.

Siehe auch https://groups.google.com/forum/#!topic/golang-nuts/TByzyPgoAQE für Details.

39
valyala

Ich habe begonnen, Gcfg zu verwenden, das Ini-ähnliche Dateien verwendet. Es ist einfach - wenn Sie etwas Einfaches wollen, ist dies eine gute Wahl.

Hier ist der Ladecode, den ich derzeit verwende. Er hat Standardeinstellungen und erlaubt Befehlszeilen-Flags (nicht gezeigt), die einige meiner Einstellungen überschreiben:

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:[email protected]/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
}
12
Rick-777

werfen Sie einen Blick auf 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)
8

https://github.com/spf13/viper und https://github.com/zpatrick/go-config sind ziemlich gute Bibliotheken für Konfigurationsdateien.

7
surfeurX

Verwenden Sie toml wie in diesem Artikel Lesen von Konfigurationsdateien auf die Go-Weise

6
herodot

Ich habe eine einfache ini-Konfigurationsbibliothek in Golang geschrieben.

https://github.com/c4pt0r/cfg

goroutine-sicher, einfach zu bedienen

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

=================== Update ======================

Vor kurzem benötige ich einen INI Parser mit Section-Unterstützung und schreibe ein einfaches Paket:

github.com/c4pt0r/cfg

sie können INI wie "flag" -Paket parsen:

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

Vielleicht interessieren Sie sich auch für go-libucl , eine Reihe von Go-Bindungen für UCL, die universelle Konfigurationssprache. UCL ähnelt JSON, bietet jedoch eine bessere Unterstützung für den Menschen: Es unterstützt Kommentare und für den Menschen lesbare Konstrukte wie SI-Multiplikatoren (10k, 40M usw.) und hat etwas weniger Boilerplate (z. B. Anführungszeichen um Schlüssel). Es kommt dem Format der Nginx-Konfigurationsdatei ziemlich nahe, wenn Sie damit bereits vertraut sind.

4
trombonehero

Ich bin mit nemo einverstanden und habe ein kleines Tool geschrieben, um alles wirklich einfach zu machen.

bitbucket.org/gotamer/cfg ist ein json-Konfigurationspaket

  • Sie definieren Ihre Konfigurationselemente in Ihrer Anwendung als Struktur.
  • Eine JSON-Konfigurationsdateivorlage aus Ihrer Struktur wird beim ersten Start gespeichert
  • Sie können Laufzeitänderungen an der Konfiguration speichern

Ein Beispiel finden Sie in doc.go

2
RoboTamer

Ich habe JSON ausprobiert. Es funktionierte. Aber ich hasse es, die Struktur der exakten Felder und Typen erstellen zu müssen, die ich einstellen könnte. Für mich war das ein Schmerz. Mir ist aufgefallen, dass dies die Methode ist, die von allen Konfigurationsoptionen verwendet wird, die ich finden kann. Vielleicht macht mich mein Hintergrund in dynamischen Sprachen blind für die Vorteile einer solchen Ausführlichkeit. Ich habe ein neues einfaches Konfigurationsdateiformat und eine dynamischere Bibliothek zum Auslesen erstellt.

https://github.com/chrisftw/ezconf

Ich bin ziemlich neu in der Go-Welt, es könnte also nicht der Go-Weg sein. Aber es funktioniert, es ist ziemlich schnell und super einfach zu bedienen.

Vorteile

  • Super einfach
  • Weniger Code

Nachteile

  • Keine Arrays oder Map-Typen
  • Sehr flaches Dateiformat
  • Nicht-Standard-Conf-Dateien
  • Hat eine kleine Konvention eingebaut, die ich jetzt, wenn überhaupt, in Go-Community verpönt habe. (Sucht nach Konfigurationsdatei im Konfigurationsverzeichnis)
1
chrisftw