327 votes

Comment gérer la configuration en Go

Je suis nouveau dans la programmation en Go, et je me demande : quelle est la meilleure façon de gérer les paramètres de configuration d'un programme Go (le genre de choses que l'on pourrait utiliser propriétés ou ini dans d'autres contextes) ?

1 votes

J'ai également lancé un fil de golang-nuts qui contient quelques idées supplémentaires.

3 votes

J'ai tendance à utiliser des scripts et des variables d'environnement.

4 votes

J'ai consacré un article de blog entier Persistance de la configuration de l'application en Go où j'ai expliqué comment le faire avec des exemples pour les deux formats les plus populaires : json et YAML. Les exemples sont prêts pour la production.

270voto

nemo Points 13983

El JSON Ce format a très bien fonctionné pour moi. La bibliothèque standard bibliothèque standard offre des méthodes pour écrire la structure de données en indentation, de sorte qu'elle est tout à fait lisible.

Voir aussi ce fil de discussion sur les golang-nuts .

Les avantages de JSON sont qu'il est assez simple à analyser et qu'il peut être lu et édité par l'homme. tout en offrant une sémantique pour les listes et les mappings (qui peut devenir très pratique), ce qui ce qui n'est pas le cas avec de nombreux analyseurs 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]

0 votes

Intéressant. C'est mieux que d'utiliser XML, à mon avis. JSON peut s'avérer être la meilleure option actuellement disponible. Merci pour le pointeur golang-nuts. J'ai été amusé une fois de plus par l'hostilité envers Yaml.

2 votes

@theglauber Yaml est assez bon pour les fichiers de configuration en termes de lisibilité, mais pas moins sujet à des erreurs (par exemple, tabulations vs espaces) et il semble assez difficile à analyser. C'est un peu comme XML, sauf qu'il n'offre même pas la lisibilité :). Cependant, si vous êtes intéressé par Yaml, vous pourriez vouloir jouer avec go-yaml .

8 votes

Il semble que JSON soit la moins mauvaise des alternatives actuelles. J'ai regardé dans go-yaml et c'est un effort courageux, mais j'ai pris le manque de documentation comme une indication que je devrais regarder ailleurs. goini semble être une bibliothèque simple et facile à utiliser pour gérer Windows. ini fichiers. Un nouveau format appelé TOML a été proposé, mais il a également a des problèmes . À ce stade, je m'en tiendrais à JSON ou à ini .

108voto

BurntSushi5 Points 1229

Une autre option consiste à utiliser TOML qui est un format de type INI créé par Tom Preston-Werner. I construit un analyseur Go pour celui-ci c'est-à-dire largement testé . Vous pouvez l'utiliser comme les autres options proposées ici. Par exemple, si vous avez ces données TOML dans le fichier 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
}

19 votes

J'aime TOML parce qu'il me permet d'écrire des commentaires soit sur les nouvelles lignes, soit à la fin d'une ligne pour configurer les paramètres. Je ne peux pas faire cela avec JSON.

0 votes

Chaque mise à jour de la configuration nécessite une mise à jour du code, ce qui est très ennuyeux.

4 votes

Toutes les approches de la configuration le font. Sinon, comment votre programme pourrait-il être au courant de la nouvelle configuration ?

50voto

Ask Bjørn Hansen Points 3509

J'utilise généralement JSON pour les 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, les différents cas limites et autres.

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

Dans la documentation :

Exemple de configuration :

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

Allez la structure :

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, ce qui permet de spécifier une clé plusieurs fois et d'autres fonctionnalités intéressantes de ce type.

5 votes

L'auteur original de gcfg interrompre le projet et en commencer un autre connexe sconf .

46voto

valyala Points 191

Il suffit d'utiliser la norme drapeaux de l'Union européenne con iniflags .

Les fanions standard présentent les avantages suivants :

  • Idiomatique.
  • Facile à utiliser. Les drapeaux peuvent être facilement ajoutés et dispersés dans les paquets arbitraires utilisés par votre projet.
  • Les drapeaux sont dotés d'un support prêt à l'emploi pour les valeurs par défaut et la description.
  • Les drapeaux fournissent une sortie d'aide standard avec les valeurs par défaut et la description.

Le seul inconvénient des drapeaux standard est qu'ils posent des problèmes de gestion lorsque le nombre de drapeaux utilisés dans votre application devient trop important.

Iniflags résout élégamment ce problème : il suffit de modifier deux lignes dans votre paquet principal pour qu'il prenne en charge, comme par magie, la lecture des valeurs des drapeaux depuis un fichier ini. Les drapeaux des fichiers ini peuvent être remplacés en passant de nouvelles valeurs dans la ligne de commande.

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

0 votes

J'ai commencé à utiliser flags pour un projet sur lequel je travaille (mon premier projet golang from-scratch), mais je me demande comment gérer des choses comme les tests ? Par exemple, il s'agit d'un client api, et je voudrais utiliser des drapeaux, mais il semble que cela compliquerait trop mes tests ( go test ne me laisse pas passer les drapeaux) alors qu'un fichier de configuration ne le ferait pas.

0 votes

Il est facile de définir des drapeaux à partir de tests : *FlagName = value

12 votes

Serait très utile s'il y avait un exemple détaillé de code ici montrant un exemple fonctionnel :)

13voto

Rick-777 Points 1905

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 des paramètres par défaut et permet des drapeaux de ligne de commande (non montrés) qui remplacent certaines de mes configurations :

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 votes

N'est-ce pas exactement ce que Ask a déjà mentionné ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X