Cómo manejar la configuración en Go [cerrado]


Soy nuevo en Go programming, y me pregunto: ¿cuál es la forma preferida de manejar los parámetros de configuración para un programa Go (el tipo de cosas que uno podría usar properties files o ini files para, en otros contextos)?

 237
go
Author: theglauber, 2013-05-09

13 answers

El formato JSON me funcionó bastante bien. El biblioteca estándar ofrece métodos para escribir la estructura de datos con sangría, por lo que es bastante legible.

Ver también este hilo golang-nuts.

Los beneficios de JSON son que es bastante simple de analizar y legible/editable por humanos mientras que ofrece semántica para listas y asignaciones (que puede llegar a ser muy útil), que no es el caso con muchos analizadores de configuración de tipo ini.

Ejemplo uso:

Conf.json :

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

Programa para leer la configuración

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]
 218
Author: nemo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-06 15:53:53

Otra opción es usar TOML, que es un formato similar a INI creado por Tom Preston-Werner. Yo construí un analizador de Go para él que es ampliamente probado. Puede usarlo como otras opciones propuestas aquí. Por ejemplo, si tiene estos datos TOML en something.toml

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

Luego puede cargarlo en su programa Go con algo como

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
}
 80
Author: BurntSushi5,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-04 04:29:32

Normalmente uso JSON para estructuras de datos más complicadas. La desventaja es que fácilmente terminas con un montón de código para decirle al usuario dónde estaba el error, varios casos extremos y qué no.

Para la configuración base (claves api, números de puerto,...) He tenido muy buena suerte con el paquete gcfg. Se basa en el formato git config.

De la documentación:

Configuración de muestra:

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

Estructura go:

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

Y el código necesario para leer it:

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

También admite valores de corte, por lo que puede permitir especificar una clave varias veces y otras características agradables como esa.

 42
Author: Ask Bjørn Hansen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-13 14:09:39

Viper es un sistema de gestión de configuración de golang que funciona con JSON, YAML y TOML. Parece bastante interesante.

 38
Author: Micah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-26 13:53:40

Simplemente use banderas estándar gocon iniflags.

Las banderas go estándar tienen los siguientes beneficios:

  • Idiomático.
  • Fácil de usar. Las banderas se pueden agregar y dispersar fácilmente en paquetes arbitrarios que utiliza su proyecto.
  • Las banderas tienen soporte listo para usar para los valores predeterminados y la descripción.
  • Los indicadores proporcionan una salida estándar de 'ayuda' con valores y descripción predeterminados.

El único inconveniente que tienen las banderas de go estándar-es problemas de administración cuando el número de indicadores utilizados en la aplicación se vuelve demasiado grande.

Iniflags resuelve elegantemente este problema: simplemente modifique dos líneas en su paquete principal y mágicamente gana soporte para leer los valores de flag del archivo ini. Las banderas de los archivos ini se pueden anular pasando nuevos valores en la línea de comandos.

Véase también https://groups.google.com/forum/#! topic / golang-nuts / TByzyPgoAQE para más detalles.

 37
Author: valyala,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-15 09:32:47

He comenzado a usar Gcfg que usa archivos similares a Ini. Es simple, si quieres algo simple, esta es una buena opción.

Aquí está el código de carga que estoy usando actualmente, que tiene configuraciones predeterminadas y permite banderas de línea de comandos (no mostradas) que anulan algunas de mis configuraciones:

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
}
 11
Author: Rick-777,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-10 09:02:43

Echa un vistazo a 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)
 6
Author: Christian Westman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-16 06:06:22

Https://github.com/spf13/viper y https://github.com/zpatrick/go-config son unas bibliotecas bastante buenas para los archivos de configuración.

 5
Author: surfeurX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-16 21:38:56

Escribí una sencilla biblioteca de configuración ini en golang.

Https://github.com/c4pt0r/cfg

Goroutine-seguro, fácil de usar

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

===================Actualización=======================

Recientemente necesito un analizador INI con soporte de sección, y escribo un paquete simple:

github.com/c4pt0r/cfg

U puede analizar INI como usando el paquete "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)
}
 4
Author: c4pt0r,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-05 17:07:15
 4
Author: herodot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-29 10:00:10

También te puede interesar go-libucl, un conjunto de enlaces Go para UCL, el Lenguaje de Configuración Universal. UCL es un poco como JSON, pero con mejor soporte para humanos: soporta comentarios y construcciones legibles como multiplicadores SI (10k, 40M, etc.).) y tiene un poco menos repetitivo (por ejemplo, comillas alrededor de las teclas). En realidad, está bastante cerca del formato de archivo de configuración nginx, si ya está familiarizado con eso.

 3
Author: trombonehero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-05 03:03:13

Estoy de acuerdo con nemo y escribí una pequeña herramienta para que todo sea realmente fácil.

Bitbucket.org/gotamer/cfg es un paquete de configuración json

  • Usted define sus elementos de configuración en su aplicación como una estructura.
  • Una plantilla de archivo de configuración json de su estructura se guarda en la primera ejecución
  • Puede guardar modificaciones de tiempo de ejecución en la configuración

Véase el doc.ir para un ejemplo

 2
Author: RoboTamer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:02:46

Probé JSON. Funcionó. Pero odio tener que crear la estructura de los campos y tipos exactos que podría estar configurando. Para mí eso era un dolor. Me di cuenta de que era el método utilizado por todas las opciones de configuración que pude encontrar. Tal vez mi experiencia en lenguajes dinámicos me hace ciego a los beneficios de tal verbosidad. Hice un nuevo formato de archivo de configuración simple, y una lib más dinámica para leerlo.

Https://github.com/chrisftw/ezconf

Soy bastante nuevo en el mundo Go, así que podría no ser el camino Go. Pero funciona, es bastante rápido y súper fácil de usar.

Pros

  • Super simple
  • Menos código

Cons

  • No hay matrices ni tipos de mapas
  • Formato de archivo muy plano
  • Archivos conf no estándar
  • Tiene una pequeña convención incorporada, que ahora si mal visto en general en la comunidad Go. (Busca el archivo de configuración en el directorio de configuración)
 1
Author: chrisftw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-27 16:12:21