web-dev-qa-db-fra.com

Comment gérer la configuration dans Go

Je suis nouveau en programmation Go et je me demande quel est le moyen privilégié de gérer les paramètres de configuration d’un programme Go (le genre de choses que l’on pourrait utiliser , propriétés fichiers ou ini fichiers pour, dans d'autres contextes)?

273
theglauber

Le format JSON a très bien fonctionné pour moi. La bibliothèque standard offre des méthodes pour écrire la structure de données en retrait, ce qui la rend assez lisible.

Voir aussi ce fil de golang-nuts .

Les avantages de JSON sont qu’il est assez simple d’analyser et d’être lisible/éditable par l’homme tout en offrant une sémantique pour les listes et les mappages (ce qui peut s’avérer très pratique), ce qui n’est pas le cas de nombreux analyseurs syntaxiques de configuration de type ini.

Exemple d'utilisation:

conf.json :

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

Programme pour lire la configuration

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

Une autre option consiste à utiliser TOML , un format de type INI créé par Tom Preston-Werner. Je construit un analyseur Go pour cela c'est testé de manière approfondie . Vous pouvez l'utiliser comme les autres options proposées ici. Par exemple, si vous avez ces données TOML dans something.toml

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

Ensuite, vous pouvez le charger dans votre programme Go avec quelque chose comme

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 est un système de gestion de la configuration golang fonctionnant avec JSON, YAML et TOML. Cela semble assez intéressant.

46
Micah

J'utilise habituellement JSON pour des structures de données plus complexes. L'inconvénient est que vous vous retrouvez facilement avec un tas de code pour indiquer à l'utilisateur où se trouvait l'erreur, différents cas Edge et ce qui ne l'est pas.

Pour la configuration de base (clés d'api, numéros de port, ...), j'ai eu beaucoup de chance avec le paquet gcfg . Il est basé sur le format de configuration git.

De la documentation:

Exemple de configuration:

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

Allez struct:

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

Et le code nécessaire pour le lire:

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

Il prend également en charge les valeurs de tranche, de sorte que vous pouvez autoriser la spécification d'une clé plusieurs fois et d'autres fonctionnalités de Nice comme celle-ci.

44

Utilisez simplement le standard go flags avec iniflags .

Les drapeaux standard ont les avantages suivants:

  • Idiomatique.
  • Facile à utiliser. Les drapeaux peuvent être facilement ajoutés et dispersés dans des packages arbitraires utilisés par votre projet.
  • Les drapeaux prennent immédiatement en charge les valeurs et la description par défaut.
  • Les drapeaux fournissent une sortie standard d'aide avec les valeurs et la description par défaut.

Le seul inconvénient standard des indicateurs de navigation est - des problèmes de gestion lorsque le nombre d'indicateurs utilisés dans votre application devient trop important.

Iniflags résout élégamment ce problème: il suffit de modifier deux lignes de votre paquet principal pour obtenir, comme par magie, la prise en charge de la lecture des valeurs d'indicateur à partir d'un fichier ini. Les indicateurs de fichiers ini peuvent être remplacés en transmettant de nouvelles valeurs en ligne de commande.

Voir aussi https://groups.google.com/forum/#!topic/golang-nuts/TByzyPgoAQE pour plus de détails.

39
valyala

J'ai commencé à utiliser Gcfg qui utilise des fichiers de type Ini. C'est simple - si vous voulez quelque chose de simple, c'est un bon choix.

Voici le code de chargement que j'utilise actuellement, qui a les paramètres par défaut et permet les drapeaux de ligne de commande (non affichés) qui surchargent une partie de ma 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
}
12
Rick-777

regardez 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
Christian Westman

https://github.com/spf13/viper et https://github.com/zpatrick/go-config sont de très bonnes bibliothèques pour les fichiers de configuration.

7
surfeurX
6
herodot

J'ai écrit une simple bibliothèque de configuration ini en golang.

https://github.com/c4pt0r/cfg

goroutine-safe, facile à utiliser

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

=================== Mise à jour ======================

Récemment, j’ai besoin d’un analyseur INI avec un support de section, et j’écris un paquet simple:

github.com/c4pt0r/cfg

vous pouvez analyser INI comme si vous utilisiez le paquet "flag":

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

Vous pourriez également être intéressé par go-libucl , un ensemble de liaisons Go pour UCL, Universal Configuration Language. UCL est un peu comme JSON, mais avec un meilleur support pour les humains: il supporte les commentaires et les constructions lisibles comme les multiplicateurs SI (10k, 40M, etc.) et a un peu moins de passe-partout (par exemple, des guillemets autour des clés). En fait, c'est assez proche du format de fichier de configuration nginx, si vous êtes déjà familiarisé avec cela.

4
trombonehero

Je suis d'accord avec nemo et j'ai écrit un petit outil pour le rendre vraiment facile.

bitbucket.org/gotamer/cfg est un package de configuration json

  • Vous définissez vos éléments de configuration dans votre application en tant que structure.
  • Un modèle de fichier json config de votre structure est enregistré lors de la première exécution.
  • Vous pouvez enregistrer les modifications d'exécution à la config

Voir doc.go pour un exemple

2
RoboTamer

J'ai essayé JSON. Ça a marché. Mais je déteste avoir à créer la structure des champs et des types exacts que je pourrais définir. Pour moi, c'était pénible. J'ai remarqué que c'était la méthode utilisée par toutes les options de configuration que je pouvais trouver. Peut-être que mon expérience des langages dynamiques me rend aveugle aux avantages d'une telle verbosité. J'ai créé un nouveau format de fichier de configuration simple et une librairie plus dynamique pour le lire.

https://github.com/chrisftw/ezconf

Je suis assez nouveau dans le monde du Go, ce n'est donc peut-être pas le cas. Mais cela fonctionne, c'est assez rapide et super simple à utiliser.

Avantages

  • Super simple
  • Moins de code

Les inconvénients

  • Aucun tableau ou type de carte
  • Format de fichier très plat
  • Fichiers conf non standard
  • Est-ce qu'il y a une petite convention intégrée, que je suis maintenant si mal vu en général dans la communauté Go. (Recherche le fichier de configuration dans le répertoire config)
1
chrisftw