Configure Module

Configure module is the core module which provides an abstraction layer for different configuration sources or formats.

You can find the examples here

Currently, Beego support all major configure formats, including INI(by default), XML, JSON, YAML and remote configure center etcd.

Config API

  1. // Configer defines how to get and set value from configuration raw data.
  2. type Configer interface {
  3. // support section::key type in given key when using ini type.
  4. Set(key, val string) error
  5. // support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
  6. String(key string) (string, error)
  7. // get string slice
  8. Strings(key string) ([]string, error)
  9. Int(key string) (int, error)
  10. Int64(key string) (int64, error)
  11. Bool(key string) (bool, error)
  12. Float(key string) (float64, error)
  13. // support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
  14. DefaultString(key string, defaultVal string) string
  15. // get string slice
  16. DefaultStrings(key string, defaultVal []string) []string
  17. DefaultInt(key string, defaultVal int) int
  18. DefaultInt64(key string, defaultVal int64) int64
  19. DefaultBool(key string, defaultVal bool) bool
  20. DefaultFloat(key string, defaultVal float64) float64
  21. // DIY return the original value
  22. DIY(key string) (interface{}, error)
  23. GetSection(section string) (map[string]string, error)
  24. Unmarshaler(prefix string, obj interface{}, opt ...DecodeOption) error
  25. Sub(key string) (Configer, error)
  26. OnChange(key string, fn func(value string))
  27. SaveConfigFile(filename string) error
  28. }

Notices:

  1. All Default* methods will return the default value if the key is not exist or got any error;
  2. DIY returns the value directly without any conversion;
  3. GetSection returns all configuration of the specific section, and it depends on the implementation details;
  4. Unmarshaler tries to use the configuration value to initiate the objprefix is similar to section
  5. Sub is similar to GetSection which tries to return all configuration of the specific section。The difference is that GetSection returns the values as map but Sub returns the values as Config instance;
  6. OnChange subscribes the change the configuration. But most of the implementations which is based on file system do not support this methods. In general we prefer to use this for configure center like etcd;
  7. SaveConfigFile writes all configuration into file(s);
  8. Some implementations support the key like a.b.c while some DO NOT. Besides, some implementations choose the . as separator while some choose other characters. This is a historical problem and we can not make them consistent if we keep backward compatible。

Web module re-encapsulate the configuration module, more details refer Web Module Configuration

Initiate

There are two major ways to use the configuration module:

  • Uses package functions config.XXXX which relies on the global instance
  • Initiates Configer instances

Global instance

Beego will try to parse the file conf/app.conf so that you can use the package functions:

  1. import (
  2. "github.com/beego/beego/v2/core/config"
  3. "github.com/beego/beego/v2/core/logs"
  4. )
  5. func main() {
  6. val, _ := config.String("name")
  7. logs.Info("auto load config name is", val)
  8. }

Or you can initiate the global instance manually to specify the source:

  1. config.InitGlobalInstance("etcd", "etcd address")

Initiates Configer instances

If you do not want to use the global instance, you can initiate the Configer instances manually:

  1. func main() {
  2. cfg, err := config.NewConfig("ini", "my_config.ini")
  3. if err != nil {
  4. logs.Error(err)
  5. }
  6. val, _ := cfg.String("appname")
  7. logs.Info("auto load config name is", val)
  8. }

Environment variable

The format for this is ${ENVIRONMENTVARIABLE} within the configuration file which is equivalent to value = os.Getenv('ENVIRONMENTVARIABLE'). Beego will only check for environment variables if the value begins with ${ and ends with }.

Additionally, a default value can be configured for the case that there is no environment variable set or the environment variable is empty. This is accomplished by using the format ${ENVVAR||defaultvalue}:

  1. runmode = "${ProRunMode||dev}"
  2. httpport = "${ProPort||9090}"

Implementations

Note that all relative file paths, are calculated from your working directory! Second, except for the default INI implementation, all other implementations need to be introduced using anonymous introduction of the corresponding package.

INI

INI is the default implementation for configuring modules. It also supports loading multiple configuration files using the include syntax。

app.ini:

  1. appname = beepkg
  2. httpaddr = "127.0.0.1"
  3. httpport = 9090
  4. include "app2.ini"

app2.ini:

  1. runmode ="dev"
  2. autorender = false
  3. recoverpanic = false
  4. viewspath = "myview"
  5. [dev]
  6. httpport = 8080
  7. [prod]
  8. httpport = 8088
  9. [test]
  10. httpport = 8888
  1. func main() {
  2. cfg, err := config.NewConfig("ini", "app.ini")
  3. if err != nil {
  4. logs.Error(err)
  5. }
  6. val, _ := cfg.String("appname")
  7. logs.Info("auto load config name is", val)
  8. }

JSON

  1. import (
  2. "github.com/beego/beego/v2/core/config"
  3. // DO NOT FORGET THIS
  4. _ "github.com/beego/beego/v2/core/config/json"
  5. "github.com/beego/beego/v2/core/logs"
  6. )
  7. var (
  8. ConfigFile = "./app.json"
  9. )
  10. func main() {
  11. err := config.InitGlobalInstance("json", ConfigFile)
  12. if err != nil {
  13. logs.Critical("An error occurred:", err)
  14. panic(err)
  15. }
  16. val, _ := config.String("name")
  17. logs.Info("load config name is", val)
  18. }

YAML

  1. import (
  2. "github.com/beego/beego/v2/core/config"
  3. // never forget this
  4. _ "github.com/beego/beego/v2/core/config/yaml"
  5. "github.com/beego/beego/v2/core/logs"
  6. )
  7. var (
  8. ConfigFile = "./app.yaml"
  9. )
  10. func main() {
  11. err := config.InitGlobalInstance("yaml", ConfigFile)
  12. if err != nil {
  13. logs.Critical("An error occurred:", err)
  14. panic(err)
  15. }
  16. val, _ := config.String("name")
  17. logs.Info("load config name is", val)
  18. }

XML

  1. import (
  2. "github.com/beego/beego/v2/core/config"
  3. // never forget this
  4. _ "github.com/beego/beego/v2/core/config/xml"
  5. "github.com/beego/beego/v2/core/logs"
  6. )
  7. var (
  8. ConfigFile = "./app.xml"
  9. )
  10. func main() {
  11. err := config.InitGlobalInstance("xml", ConfigFile)
  12. if err != nil {
  13. logs.Critical("An error occurred:", err)
  14. panic(err)
  15. }
  16. val, _ := config.String("name")
  17. logs.Info("load config name is", val)
  18. }

Note that all configuration items should be placed within the root config

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <config>
  3. <name>beego</name>
  4. </config>

TOML

  1. import (
  2. "github.com/beego/beego/v2/core/config"
  3. // never forget this
  4. _ "github.com/beego/beego/v2/core/config/toml"
  5. "github.com/beego/beego/v2/core/logs"
  6. )
  7. var (
  8. ConfigFile = "./app.toml"
  9. )
  10. func main() {
  11. err := config.InitGlobalInstance("toml", ConfigFile)
  12. if err != nil {
  13. logs.Critical("An error occurred:", err)
  14. panic(err)
  15. }
  16. val, _ := config.String("name")
  17. logs.Info("load config name is", val)
  18. }

Etcd

  1. import (
  2. "github.com/beego/beego/v2/core/config"
  3. // never forget this
  4. _ "github.com/beego/beego/v2/core/config/toml"
  5. "github.com/beego/beego/v2/core/logs"
  6. )
  7. func main() {
  8. err := config.InitGlobalInstance("etcd", "your_config")
  9. if err != nil {
  10. logs.Critical("An error occurred:", err)
  11. panic(err)
  12. }
  13. val, _ := config.String("name")
  14. logs.Info("load config name is", val)
  15. }

where your_config is a JSON configuration that corresponds to:

  1. type Config struct {
  2. // Endpoints is a list of URLs.
  3. Endpoints []string `json:"endpoints"`
  4. // AutoSyncInterval is the interval to update endpoints with its latest members.
  5. // 0 disables auto-sync. By default auto-sync is disabled.
  6. AutoSyncInterval time.Duration `json:"auto-sync-interval"`
  7. // DialTimeout is the timeout for failing to establish a connection.
  8. DialTimeout time.Duration `json:"dial-timeout"`
  9. // DialKeepAliveTime is the time after which client pings the server to see if
  10. // transport is alive.
  11. DialKeepAliveTime time.Duration `json:"dial-keep-alive-time"`
  12. // DialKeepAliveTimeout is the time that the client waits for a response for the
  13. // keep-alive probe. If the response is not received in this time, the connection is closed.
  14. DialKeepAliveTimeout time.Duration `json:"dial-keep-alive-timeout"`
  15. // MaxCallSendMsgSize is the client-side request send limit in bytes.
  16. // If 0, it defaults to 2.0 MiB (2 * 1024 * 1024).
  17. // Make sure that "MaxCallSendMsgSize" < server-side default send/recv limit.
  18. // ("--max-request-bytes" flag to etcd or "embed.Config.MaxRequestBytes").
  19. MaxCallSendMsgSize int
  20. // MaxCallRecvMsgSize is the client-side response receive limit.
  21. // If 0, it defaults to "math.MaxInt32", because range response can
  22. // easily exceed request send limits.
  23. // Make sure that "MaxCallRecvMsgSize" >= server-side default send/recv limit.
  24. // ("--max-request-bytes" flag to etcd or "embed.Config.MaxRequestBytes").
  25. MaxCallRecvMsgSize int
  26. // TLS holds the client secure credentials, if any.
  27. TLS *tls.Config
  28. // Username is a user name for authentication.
  29. Username string `json:"username"`
  30. // Password is a password for authentication.
  31. Password string `json:"password"`
  32. // RejectOldCluster when set will refuse to create a client against an outdated cluster.
  33. RejectOldCluster bool `json:"reject-old-cluster"`
  34. // DialOptions is a list of dial options for the grpc client (e.g., for interceptors).
  35. // For example, pass "grpc.WithBlock()" to block until the underlying connection is up.
  36. // Without this, Dial returns immediately and connecting the server happens in background.
  37. DialOptions []grpc.DialOption
  38. // Context is the default client context; it can be used to cancel grpc dial out and
  39. // other operations that do not have an explicit context.
  40. Context context.Context
  41. // Logger sets client-side logger.
  42. // If nil, fallback to building LogConfig.
  43. Logger *zap.Logger
  44. // LogConfig configures client-side logger.
  45. // If nil, use the default logger.
  46. // TODO: configure gRPC logger
  47. LogConfig *zap.Config
  48. // PermitWithoutStream when set will allow client to send keepalive pings to server without any active streams(RPCs).
  49. PermitWithoutStream bool `json:"permit-without-stream"`
  50. // TODO: support custom balancer picker
  51. }