The gcfg component uses an interface-based design, with the default implementation based on the file system. Supported data file formats include: JSON/XML/YAML(YML)/TOML/INI/PROPERTIES. Developers can flexibly choose their familiar configuration file format for configuration management.

Configuration File

Default Configuration File

We recommend using a singleton way to obtain the configuration object. The singleton object will automatically search configuration files according to the file suffix toml/yaml/yml/json/ini/xml/properties. By default, it will automatically search and cache configuration files like config.toml/yaml/yml/json/ini/xml/properties. When a configuration file is modified externally, it will automatically refresh the cache.

If you want to customize the file format, you can modify the default configuration file name through the SetFileName method (e.g., default.yaml, default.json, default.xml, etc.). For example, we can read the database database configuration item from the default.yaml file in the following way.

  1. // Set the default configuration file to default.yaml
  2. g.Cfg().GetAdapter().(*gcfg.AdapterFile).SetFileName("default.yaml")
  3. // Subsequent reads will fetch the content from default.yaml
  4. g.Cfg().Get(ctx, "database")

Default File Modification

Configuration - File - 图1tip

The file can be a specific file name or a complete absolute file path.

We can modify the default file name in multiple ways:

  1. Modify through the configuration management method SetFileName.
  2. Modify the command line startup parameter - gf.gcfg.file.
  3. Modify the specified environment variable - GF_GCFG_FILE.

If our executable file is main, we can modify the configuration manager’s configuration file directory (on Linux) in the following way:

  1. Through Singleton Pattern
  1. g.Cfg().GetAdapter().(*gcfg.AdapterFile).SetFileName("default.yaml")
  1. Through Command Line Startup Parameter
  1. ./main --gf.gcfg.file=config.prod.toml
  1. Through Environment Variable (commonly used in containers)

    • Modify the environment variable at startup:

      1. GF_GCFG_FILE=config.prod.toml; ./main
    • Use the genv module to modify environment variables:

      1. genv.Set("GF_GCFG_FILE", "config.prod.toml")

Configuration Directory

Directory Configuration Method

The gcfg configuration manager supports a very flexible multi-directory automatic search function. You can modify the directory management directory to a unique directory address using SetPath. Meanwhile, we recommend adding multiple search directories through the AddPath method. The configuration manager will automatically search in the order of the added directories by priority. It will stop when a matching file path is found. If no configuration file is found in all search directories, it will return a failure.

Default Directory Configuration

When the gcfg configuration manager initializes, it automatically adds the following configuration file search directories:

  1. The current working directory and its config, manifest/config directories: For example, when the current working directory is /home/www, it will add:
    1. /home/www
    2. /home/www/config
    3. /home/www/manifest/config
  2. The directory where the current executable file is located and its config, manifest/config directories: For example, when the binary file is located at /tmp, it will add:
    1. /tmp
    2. /tmp/config
    3. /tmp/manifest/config
  3. The directory where the current main source code package is located and its config, manifest/config directories (valid for source code development environment only): For example, when the main package is located at /home/john/workspace/gf-app, it will add:
    1. /home/john/workspace/gf-app
    2. /home/john/workspace/gf-app/config
    3. /home/john/workspace/gf-app/manifest/config

Default Directory Modification

Configuration - File - 图2warning

Note that the parameter modified here must be a directory, not a file path.

We can modify the configuration file search directory of the configuration manager in the following way. The configuration management object will only perform configuration file searches in the specified directory:

  1. Manually modify it through the configuration manager’s SetPath method;
  2. Modify the command line startup parameter - gf.gcfg.path;
  3. Modify the specified environment variable - GF_GCFG_PATH;

If our executable file is main, we can modify the configuration manager’s configuration file directory (under Linux) in the following way:

  1. Through Singleton Pattern
  1. g.Cfg().GetAdapter().(*gcfg.AdapterFile).SetPath("/opt/config")
  1. Through Command Line Startup Parameter
  1. ./main --gf.gcfg.path=/opt/config/
  1. Through Environment Variable (commonly used in containers)

    • Modify the environment variable at startup:

      1. GF_GCFG_PATH=/opt/config/; ./main
    • Use the genv module to modify environment variables:

      1. genv.Set("GF_GCFG_PATH", "/opt/config")

Content Configuration

The gcfg package also supports direct content configuration rather than reading configuration files, which is commonly used for dynamically modifying configuration content internally in programs. Implement global configuration through the package configuration methods below:

  1. func (c *AdapterFile) SetContent(content string, file ...string)
  2. func (c *AdapterFile) GetContent(file ...string) string
  3. func (c *AdapterFile) RemoveContent(file ...string)
  4. func (c *AdapterFile) ClearContent()

It is important to note that this configuration takes effect globally and has a higher priority than reading from configuration files. Therefore, if we configure the content of config.toml through SetContent("v = 1", "config.toml") and a config.toml file also exists, only the content configured by SetContent will be used, and the file content will be ignored.

Hierarchical Access

With the default file system interface implementation, the gcfg component supports accessing configuration data by hierarchy. Hierarchical access is specified by the English . by default, where the pattern parameter is consistent with the pattern parameter of General Codec. For example, the following configuration (config.yaml):

  1. server:
  2. address: ":8199"
  3. serverRoot: "resource/public"
  4. database:
  5. default:
  6. link: "mysql:root:12345678@tcp(127.0.0.1:3306)/focus"
  7. debug: true

For example, hierarchical reading of the above configuration file content:

  1. // :8199
  2. g.Cfg().Get(ctx, "server.address")
  3. // true
  4. g.Cfg().Get(ctx, "database.default.debug")

Precautions

As everyone knows, in Golang, types like map/slice are actually “reference types” (also called “pointer types”). Therefore, when you modify a key-value pair/index item of this type, it will also modify the corresponding underlying data. From the perspective of efficiency, when some gcfg retrieval methods return data types as map/slice, they do not perform a value copy. Therefore, when you modify the returned data, it will also modify the corresponding underlying data of gcfg.

For example:

Configuration file:

  1. // config.json:
  2. `{"map":{"key":"value"}, "slice":[59,90]}`

Example code:

  1. var ctx = gctx.New()
  2. m := g.Cfg().MustGet(ctx, "map").Map()
  3. fmt.Println(m)
  4. // Change the key-value pair.
  5. m["key"] = "john"
  6. // It changes the underlying key-value pair.
  7. fmt.Println(g.Cfg().MustGet(ctx, "map").Map())
  8. s := g.Cfg().MustGet(ctx, "slice").Slice()
  9. fmt.Println(s)
  10. // Change the value of specified index.
  11. s[0] = 100
  12. // It changes the underlying slice.
  13. fmt.Println(g.Cfg().MustGet(ctx, "slice").Slice())
  14. // output:
  15. // map[key:value]
  16. // map[key:john]
  17. // [59 90]
  18. // [100 90]

Detecting Updates

The configuration manager uses a caching mechanism. When a configuration file is read for the first time, it is cached in memory. The next read will directly fetch it from the cache to improve performance. Meanwhile, the configuration manager provides an auto-detect update mechanism. When the configuration file is modified externally, the configuration manager can immediately refresh the cached content of the configuration file.