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)?
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]
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
}
Viper est un système de gestion de la configuration golang fonctionnant avec JSON, YAML et TOML. Cela semble assez intéressant.
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.
Utilisez simplement le standard go flags avec iniflags .
Les drapeaux standard ont les avantages suivants:
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.
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
}
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)
https://github.com/spf13/viper et https://github.com/zpatrick/go-config sont de très bonnes bibliothèques pour les fichiers de configuration.
Utilisez toml comme cet article Lire les fichiers de configuration à la manière de Go
J'ai écrit une simple bibliothèque de configuration ini en golang.
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)
}
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.
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
Voir doc.go pour un exemple
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.