गो [बंद] में कॉन्फ़िगरेशन कैसे संभालें


284

मैं गो प्रोग्रामिंग में नया हूं, और मैं सोच रहा हूं: गो कार्यक्रम के लिए कॉन्फ़िगरेशन मापदंडों को संभालने का पसंदीदा तरीका क्या है (जिस तरह का सामान अन्य संदर्भों में संपत्तियों की फाइलों या आईएनआई फाइलों का उपयोग कर सकता है)?


मैंने एक गोलंग-नट्स धागा भी शुरू किया जिसमें कुछ अतिरिक्त विचार हैं।
theglauber

2
मैं शेल स्क्रिप्ट और पर्यावरण चर का उपयोग करता हूं।
दायां गुना

3
मैंने एक संपूर्ण ब्लॉग पोस्ट समर्पित किया है जिसमें अनुप्रयोग कॉन्फ़िगरेशन का उपयोग किया गया है जहाँ मैंने समझाया कि दो सबसे लोकप्रिय प्रारूपों के लिए इसे कैसे करें: json और YAML। इसके उदाहरण तैयार हैं।
अपितु

बस रिकॉर्ड के लिए HashiCorp से HCL है जो टिप्पणियों का समर्थन करता है और JSON और UCL संगत है। github.com/hashicorp/hcl
केव शाहबाजियन

जवाबों:


244

JSON प्रारूप काफी अच्छी तरह से मेरे लिए काम किया। मानक लाइब्रेरी डेटा संरचना को इंडेंट लिखने के लिए तरीके प्रदान करती है, इसलिए यह काफी पठनीय है।

इस गोलंग-नट्स धागे को भी देखें ।

JSON के लाभ यह है कि सूचियों और मैपिंग (जो काफी काम का हो सकता है) के लिए शब्दार्थ प्रदान करते समय पार्स और मानव पठनीय / संपादन योग्य है, जो कि कई ini-type config पार्सर के साथ ऐसा नहीं है।

उदाहरण का उपयोग:

conf.json :

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

कॉन्फ़िगरेशन को पढ़ने के लिए कार्यक्रम

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]

6
ऐसा लगता है कि JSON वर्तमान विकल्पों में से सबसे कम बुरा है। मैंने गो-यम में देखा और यह एक शानदार प्रयास है, लेकिन मैंने प्रलेखन की कमी को एक संकेत के रूप में लिया कि मुझे कहीं और देखना चाहिए। Windows ini फ़ाइलों को संभालने के लिए goini एक सरल और आसान लाइब्रेरी लगती है । TOML नामक एक नया प्रारूप प्रस्तावित किया गया है, लेकिन इसमें समस्याएं भी हैं । इस बिंदु पर मैं JSON या ini से चिपका रहूंगा
Theglauber

6
YAML टिप्पणियों का समर्थन करता है, यदि आप कॉन्फ़िगर फ़ाइल में हर जगह नोट्स जोड़ना चाहते हैं।
इवान ब्लैक

42
इसे पढ़ने और उस मार्ग से नीचे जाने वालों के लिए, सावधान रहें: JSONs टिप्पणियों का अभाव इसे मानव उपयोग योग्य कॉन्फ़िगरेशन फ़ाइल (imo) के लिए अनुपयुक्त बनाता है। यह एक डाटा इंटरचेंज फॉर्मेट है - आपको कॉन्फिग फाइलों में मददगार / वर्णनात्मक टिप्पणियाँ लिखने की क्षमता खोने की संभावना हो सकती है ("यह सेटिंग सक्रिय क्यों हो रही है?", "यह क्या करता है?", "इसके लिए वैध मान क्या हैं?" ?" आदि)।
डेरियन मूडी

6
आह - मैंने कोशिश की कि अपने कोड में और अपरकेस अक्षर (निर्यात नहीं) के साथ संरचना विशेषताओं को परिभाषित करना भूल गया - इससे मुझे अपने जीवन का एक घंटा खर्च हुआ। हो सकता है कि अन्य लोग भी वही त्रुटि करें> चेतावनी दी जा सकती है; डी
जॉनगाल्ट

6
आपको शायद defer file.Close()खुली गलती की जाँच करने के बाद चाहिए
गेब्रियल

97

एक अन्य विकल्प TOML का उपयोग करना है , जो टॉम प्रेस्टन-वर्नर द्वारा निर्मित एक INI जैसा प्रारूप है। मैंने इसके लिए एक गो पार्सर का निर्माण किया है जिसका बड़े पैमाने पर परीक्षण किया गया है । आप इसे यहां प्रस्तावित अन्य विकल्पों की तरह उपयोग कर सकते हैं। उदाहरण के लिए, यदि आपके पास यह TOML डेटा हैsomething.toml

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

तब आप इसे अपने गो कार्यक्रम में कुछ इस तरह से लोड कर सकते हैं

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
}

18
मैं TOML को पसंद करता हूं क्योंकि यह मुझे नईलाइन पर या सेटिंग को कॉन्फ़िगर करने वाली एक पंक्ति के अंत में टिप्पणियां लिखने देता है। मैं JSON के साथ ऐसा नहीं कर सकता।
सर्गसेर

प्रत्येक कॉन्फिग अपडेट में कोड में अपडेट की आवश्यकता होती है जो बहुत कष्टप्रद है।
17'17 को शाम

4
कॉन्फ़िगर करने के लिए हर दृष्टिकोण करता है। आपके प्रोग्राम को नए कॉन्फ़िगरेशन के बारे में कैसे पता चलेगा?
बर्नटुशी 5

@ BurntSushi5 टॉमल फ़ाइल में अतिरिक्त फ़ील्ड हो सकता है जिसे कोड की परवाह नहीं है? मेरा मतलब है, क्या कोड के पुराने संस्करण के साथ कॉन्फिग फाइल का एक नया संस्करण इस्तेमाल किया जा सकता है? अप्रयुक्त कॉन्फ़िगरेशन विकल्पों को अनदेखा करना मेरे मामले में ठीक है।
user1952500

2
मुझें यह पसंद है। अच्छा कार्य। व्यक्तिगत रूप से मुझे लगता है कि एडिशन या ग्राहकों के लिए JSON की तुलना में TOML फ़ाइल को बदलना आसान है।
११

49

वाइपर एक गोलंग विन्यास प्रबंधन प्रणाली है जो JSON, YAML और TOML के साथ काम करती है। यह काफी दिलचस्प लग रहा है।


1
12factor अनुप्रयोगों के लिए विशेष रूप से व्यवहार्य 12factor.net
DerKnorr 19

गो में JSON कॉन्फ़िगरेशन के लिए gonfig का उपयोग करें। github.com/eduardbcom/gonfig
Eduard Bondarenko

1
वाइपर का उपयोग न करें, यह थ्रेड-सेफ नहीं है जिसने मुझे लगभग निकाल दिया।
igonejack

@igonejack कृपया एक उदाहरण प्रदान करें कि वाइपर ने आपको कहाँ से काट लिया?
इल

1
@ Dr.eel अलग-अलग गोरोइन में अलग-अलग viper.GetBool ("abc") और Viper.Set ("abc", false) आज़माएं।
06गोनजैक

44

मैं आमतौर पर JSON का उपयोग अधिक जटिल डेटा संरचनाओं के लिए करता हूं। नकारात्मक पक्ष यह है कि आप आसानी से उपयोगकर्ता को यह बताने के लिए कोड का एक गुच्छा के साथ समाप्त करते हैं कि त्रुटि कहां थी, विभिन्न किनारे के मामले और क्या नहीं।

आधार विन्यास (एपीआई कुंजी, पोर्ट नंबर, ...) के लिए मुझे gcfg पैकेज के साथ बहुत अच्छी किस्मत मिली है। यह git config फॉर्मेट पर आधारित है।

प्रलेखन से:

नमूना विन्यास:

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

गो संरचना:

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

और इसे पढ़ने के लिए आवश्यक कोड:

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

यह स्लाइस मानों का भी समर्थन करता है, इसलिए आप कई बार एक प्रमुख विशेषता और अन्य अच्छी विशेषताओं को निर्दिष्ट करने की अनुमति दे सकते हैं।


4
Gcfg के मूल लेखक ने इस परियोजना को बंद कर दिया और एक अन्य संबंधित एक sconf शुरू किया ।
iwat

39

बस iniflags के साथ मानक जाओ झंडे का उपयोग करें ।

मानक गो ध्वज के निम्नलिखित लाभ हैं:

  • मुहावरेदार।
  • प्रयोग करने में आसान। झंडे आसानी से जोड़े जा सकते हैं और मनमाने पैकेजों में बिखरे हुए हैं जो आपकी परियोजना का उपयोग करता है।
  • झंडे में डिफ़ॉल्ट मान और विवरण के लिए आउट-ऑफ-द-बॉक्स समर्थन है।
  • झंडे डिफ़ॉल्ट मान और विवरण के साथ मानक 'सहायता' आउटपुट प्रदान करते हैं।

एकमात्र दोष मानक गो ध्वज है - जब आपके ऐप में उपयोग किए जाने वाले झंडे की संख्या बहुत बड़ी हो जाती है तो प्रबंधन की समस्याएं होती हैं।

Iniflags सुरुचिपूर्ण ढंग से इस समस्या को हल करता है: बस अपने मुख्य पैकेज में दो पंक्तियों को संशोधित करें और यह ini फ़ाइल से ध्वज मानों को पढ़ने के लिए जादुई समर्थन प्राप्त करता है। Ini फ़ाइलों से फ़्लैग को कमांड-लाइन में नए मानों को पारित करके ओवरराइड किया जा सकता है।

विवरण के लिए https://groups.google.com/forum/# ​​.topic/golang-nuts/TByzyPgoAQE भी देखें ।


मैंने उस प्रोजेक्ट के लिए झंडे का उपयोग करना शुरू कर दिया है, जिस पर मैं काम कर रहा हूं (मेरी पहली स्क्रैच गोलंग परियोजना), लेकिन मैं सोच रहा हूं कि परीक्षण जैसी चीजों को कैसे संभालना है? उदाहरण के लिए, यह एक एपीआई क्लाइंट है, और मैं झंडे का उपयोग करना चाहूंगा, लेकिन ऐसा लगता है कि यह मेरे परीक्षण को जटिल बना देगा ( go testमुझे झंडे में पास नहीं होने देता) जबकि एक कॉन्फिग फाइल नहीं होगी।
जचिसन

परीक्षणों से झंडे स्थापित करना आसान है:*FlagName = value
स्टीवन सोरोका

9
बहुत उपयोगी होगा अगर एक विस्तृत उदाहरण कोड यहां काम कर रहे उदाहरण दिखा रहा है :)
शून्य_cool

एक अच्छा विचार नहीं है जब आपको अन्य भाषाओं में लिखे गए एप्लिकेशन के अन्य टुकड़ों के साथ कॉन्फ़िगर करने की आवश्यकता होती है।
किर्ज़िला

झंडे के बजाय pflags का उपयोग करने का सुझाव देगा। pflags posix-standard
Fjolnir Dvorak

12

मैंने 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: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
क्या यह वही नहीं है जो पहले ही उल्लेख किया जा चुका है?
नीमो

8

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)

यह एक अच्छा है, क्योंकि मुझे पूरी विन्यास संरचना को फिर से परिभाषित करने की आवश्यकता नहीं है
thanhpk



5

मैंने गोलंग में एक साधारण आईएनआई कॉन्फिगर लाइब्रेरी लिखी।

https://github.com/c4pt0r/cfg

goroutine- सुरक्षित, उपयोग में आसान

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

=================== अद्यतन =======================

हाल ही में मुझे अनुभाग समर्थन के साथ एक आईएनआई पार्सर की आवश्यकता है, और मैं एक साधारण पैकेज लिखता हूं:

github.com/c4pt0r/cfg

आप "ध्वज" पैकेज का उपयोग करके आईएनआई को पार्स कर सकते हैं:

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

आपको यूनिवर्सल-कॉन्फ़िगरेशन भाषा, यूसीएल के लिए गो बाइंडिंग का एक सेट, गो -लिब्युलु में भी रुचि हो सकती है । यूसीएल जेएसएन की तरह एक सा है, लेकिन मनुष्यों के लिए बेहतर समर्थन के साथ: यह टिप्पणियों और मानव-पठनीय निर्माणों जैसे एसआई गुणक (10k, 40M, आदि) का समर्थन करता है और इसमें थोड़ा कम बॉयलरप्लेट (जैसे, कुंजियों के आसपास उद्धरण) है। यदि आप पहले से ही परिचित हैं, तो यह वास्तव में nginx कॉन्फ़िगरेशन फ़ाइल स्वरूप के बहुत करीब है।


2

मैं नीमो से सहमत हूं और मैंने इसे वास्तविक रूप से आसान बनाने के लिए एक छोटा सा उपकरण लिखा है।

bitbucket.org/gotamer/cfg एक json कॉन्फ़िगरेशन पैकेज है

  • आप एक संरचना के रूप में अपने आवेदन में अपने विन्यास आइटम परिभाषित करते हैं।
  • आपकी संरचना से एक जोंस कॉन्फिग फाइल टेम्प्लेट को पहले रन पर सहेजा जाता है
  • आप कॉन्फ़िगरेशन में रनटाइम संशोधनों को सहेज सकते हैं

उदाहरण के लिए doc.go देखें


1

मैंने JSON की कोशिश की। इसने काम कर दिया। लेकिन मुझे सटीक फ़ील्ड्स और मेरे द्वारा सेट किए जा सकने वाले प्रकारों की संरचना बनाने से नफरत है। मेरे लिए वो दर्द था। मैंने देखा कि यह सभी विन्यास विकल्पों द्वारा उपयोग की जाने वाली विधि थी जिसे मैं पा सकता था। हो सकता है कि गतिशील भाषाओं में मेरा बैकग्राउंड मुझे इस तरह के क्रिया-कलापों के लाभों से अंधा बना दे। मैंने एक नया सरल कॉन्फिग फाइल फॉर्मेट बनाया, और इसे पढ़ने के लिए एक अधिक गतिशील-ईश लीब।

https://github.com/chrisftw/ezconf

मैं गो संसार के लिए बहुत नया हूं, इसलिए यह गो मार्ग नहीं हो सकता है। लेकिन यह काम करता है, यह बहुत जल्दी है, और उपयोग करने के लिए सुपर सरल है।

पेशेवरों

  • सुपर सिंपल है
  • कम कोड

विपक्ष

  • कोई अर्रे या मैप प्रकार नहीं
  • बहुत सपाट फ़ाइल स्वरूप
  • गैर-मानक conf फ़ाइलें
  • में थोड़ा सा कन्वेंशन बिल्ट-इन है, जिसे मैं अब गो समुदाय में सामान्य तौर पर फॉलो करता हूं। (विन्यास निर्देशिका में विन्यास फाइल के लिए लगता है)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.