Как обрабатывать конфигурацию в Go

Я новичок в программировании Go, и мне интересно: какой предпочтительный способ обработки параметров конфигурации для программы Go (какой материал можно использовать в файлах свойств или ini файлах для других контекстов)?

Ответ 1

Формат JSON работал у меня довольно хорошо. стандартная библиотека предлагает методы для записи структуры данных с отступом, поэтому вполне читаемым.

См. также этот поток golang-nuts.

Преимущества JSON заключаются в том, что он довольно прост в анализе и доступен для чтения/редактирования предлагая семантику для списков и сопоставлений (что может стать весьма удобным), что это не так со многими синтаксическими анализаторами ini-типа.

Пример использования:

conf.json

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

Программа для чтения конфигурации

import (
    "encoding/json"
    "os"
    "fmt"
)

type Configuration struct {
    Users    []string
    Groups   []string
}

file, _ := os.Open("conf.json")
decoder := json.NewDecoder(file)
configuration := Configuration{}
err := decoder.Decode(&configuration)
if err != nil {
  fmt.Println("error:", err)
}
fmt.Println(configuration.Users) // output: [UserA, UserB]

Ответ 2

Другой вариант - использовать TOML, который является INI-подобным форматом, созданным Томом Престоном-Вернером. я построил для него парсинг Go, который был широко протестирован. Вы можете использовать его, как и другие варианты, предлагаемые здесь. Например, если у вас есть данные TOML в something.toml

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

Затем вы можете загрузить его в свою программу Go с чем-то вроде

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
}

Ответ 3

Я обычно использую JSON для более сложных структур данных. Недостатком является то, что вы легко можете получить кучу кода, чтобы сообщить пользователю, где была ошибка, различные граничные случаи, а что нет.

Для базовой конфигурации (ключи api, номера портов,...) Мне очень повезло с пакетом gcfg. Он основан на конфигурационном формате git.

Из документации:

Пример конфигурации:

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

Go struct:

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

И код, необходимый для его чтения:

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

Он также поддерживает значения среза, поэтому вы можете разрешить указание ключа несколько раз и другие приятные функции.

Ответ 4

Viper - это система управления конфигурацией golang, которая работает с JSON, YAML и TOML. Это выглядит довольно интересно.

Ответ 5

Просто используйте стандартные флаги go с iniflags.

Стандартные флаги go имеют следующие преимущества:

  • Идиоматические.
  • Прост в использовании. Флаги могут быть легко добавлены и разбросаны по произвольным пакетам, которые использует ваш проект.
  • Флаги имеют встроенную поддержку значений и описания по умолчанию.
  • Флаги предоставляют стандартный вывод справки со значениями по умолчанию и описанием.

Единственные недостатки стандартного отклонения - это проблемы управления, когда количество флагов, используемых в вашем приложении, становится слишком большим.

Iniflags элегантно решает эту проблему: просто измените две строки в своем основном пакете, и она волшебным образом получает поддержку для чтения значений флага из ini файла. Флаги из ini файлов можно переопределить, передав новые значения в командной строке.

Подробнее см. https://groups.google.com/forum/#!topic/golang-nuts/TByzyPgoAQE.

Ответ 6

Я начал использовать Gcfg, который использует Ini-подобные файлы. Это просто - если вам нужно что-то простое, это хороший выбор.

Здесь код загрузки, который я использую в настоящее время, который имеет настройки по умолчанию и позволяет флаги командной строки (не показаны) переопределять некоторые из моих конфигураций:

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:[email protected]/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
}

Ответ 7

посмотрите 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)

Ответ 9

Я написал простую ini-конфигурационную библиотеку в golang.

https://github.com/c4pt0r/cfg

goroutine-safe, простой в использовании

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

=================== Update =======================

Недавно мне нужен парсер INI с поддержкой раздела, и я пишу простой пакет:

github.com/c4pt0r/cfg

u может анализировать INI как использование пакета "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)
}

Ответ 11

Вас также может заинтересовать go-libucl, набор привязок Go для UCL, язык универсальной конфигурации. UCL немного похож на JSON, но с лучшей поддержкой для людей: он поддерживает комментарии и читаемые человеком конструкции, такие как умножители SI (10k, 40M и т.д.) И имеет немного меньший набор шаблонов (например, цитаты вокруг клавиш). Это действительно очень близко к формату файла конфигурации nginx, если вы уже знакомы с этим.

Ответ 12

Я согласен с nemo, и я написал небольшой инструмент, чтобы все было очень легко.

bitbucket.org/gotamer/cfg - это пакет конфигурации json

  • Вы определяете свои элементы конфигурации в своем приложении как структуру.
  • Шаблон конфигурационного файла json из вашей структуры сохраняется при первом запуске
  • Вы можете сохранить изменения среды выполнения в конфигурации

См. doc.go для примера

Ответ 13

Я попробовал JSON. Это сработало. Но мне не нравится создавать структуру точных полей и типов, которые я могу установить. Для меня это была боль. Я заметил, что это был метод, используемый всеми параметрами конфигурации, которые я мог найти. Возможно, мой опыт в динамических языках делает меня слепым к преимуществам такой многословности. Я сделал новый простой формат файла конфигурации и более динамично-ист-lib для его чтения.

https://github.com/chrisftw/ezconf

Я новичок в мире Go, так что это может быть не Go Go. Но он работает, он довольно быстр и очень прост в использовании.

Pros

  • Супер простой
  • Меньше кода

Против

  • Нет массивов или типов карт
  • Очень плоский формат файла
  • Нестандартные файлы conf
  • У вас есть небольшая условная встроенная функция, которую я сейчас, если вообще нахмурился в сообществе Go. (Ищет файл конфигурации в каталоге конфигурации)