read management golang conf go configuration-files

management - Cómo manejar la configuración en Go



properties golang (13)

Comencé 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 marcas de línea de comando (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 }

Soy nuevo en la programación de Go, 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 para las que se pueden usar archivos de propiedades o archivos ini , en otros contextos)?


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

Véase también este hilo de golang-nuts .

Los beneficios de JSON son que es bastante simple de analizar y legible / editable por humanos, a la vez que ofrece semánticas para listas y asignaciones (que pueden ser bastante útiles), lo que no es el caso de muchos analizadores de configuración de tipo ini.

Ejemplo de 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]


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

https://github.com/c4pt0r/cfg

Goroutine-Safe, 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) } }

=================== Actualizar =======================

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

github.com/c4pt0r/cfg

Puedes analizar el INI como usar 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) }


Estoy de acuerdo con y escribí una pequeña herramienta para que todo fuera 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 a la configuración

Ver doc.go para un ejemplo


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

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

Luego puedes cargarlo en tu 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 }


Probé con JSON. Funcionó. Pero odio tener que crear la estructura de los campos y tipos exactos que podría estar configurando. Para mí eso fue un dolor. Noté que era el método usado 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 biblioteca más dinámica para leerlo.

https://github.com/chrisftw/ezconf

Soy bastante nuevo en el mundo Go, por lo que podría no ser el camino Go. Pero funciona, es bastante rápido y muy fácil de usar.

Pros

  • Super simple
  • Menos codigo

Contras

  • No hay matrices o tipos de mapas
  • Formato de archivo muy plano.
  • Archivos conf no estándar
  • Tiene una pequeña convención incorporada, la cual ahora estoy mal visto en general en la comunidad Go. (Busca el archivo de configuración en el directorio de configuración)

Sólo usa banderas de go estándar con iniflags .

Las banderas 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 usa su proyecto.
  • Los indicadores tienen compatibilidad inmediata con los valores y la descripción predeterminados.
  • Los indicadores proporcionan una salida de ''ayuda'' estándar con valores y descripción predeterminados.

El único inconveniente que tienen las banderas go go - es problemas de administración cuando el número de banderas utilizadas en su aplicación es demasiado grande.

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

Consulte también https://groups.google.com/forum/#!topic/golang-nuts/TByzyPgoAQE para obtener más información.


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 un mejor soporte para humanos: admite comentarios y construcciones legibles para el ser humano como los multiplicadores SI (10k, 40M, etc.) y tiene un poco menos de repetición (por ejemplo, citas alrededor de las teclas). En realidad, está bastante cerca del formato de archivo de configuración nginx, si ya está familiarizado con eso.



Usualmente 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 estuvo el error, varios casos de borde y qué no.

Para la configuración básica (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

Ir estructura:

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

Y el código necesario para leerlo:

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

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


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



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