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.
// Set the default configuration file to default.yaml
g.Cfg().GetAdapter().(*gcfg.AdapterFile).SetFileName("default.yaml")
// Subsequent reads will fetch the content from default.yaml
g.Cfg().Get(ctx, "database")
Default File Modification
The file can be a specific file name or a complete absolute file path.
We can modify the default file name in multiple ways:
- Modify through the configuration management method
SetFileName
. - Modify the command line startup parameter -
gf.gcfg.file
. - 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:
- Through Singleton Pattern
g.Cfg().GetAdapter().(*gcfg.AdapterFile).SetFileName("default.yaml")
- Through Command Line Startup Parameter
./main --gf.gcfg.file=config.prod.toml
- Through Environment Variable (commonly used in containers)
-
Modify the environment variable at startup:
GF_GCFG_FILE=config.prod.toml; ./main
-
Use the
genv
module to modify environment variables: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:
- The current working directory and its
config
,manifest/config
directories: For example, when the current working directory is/home/www
, it will add:/home/www
/home/www/config
/home/www/manifest/config
- 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:/tmp
/tmp/config
/tmp/manifest/config
- The directory where the current
main
source code package is located and itsconfig
,manifest/config
directories (valid for source code development environment only): For example, when themain
package is located at/home/john/workspace/gf-app
, it will add:/home/john/workspace/gf-app
/home/john/workspace/gf-app/config
/home/john/workspace/gf-app/manifest/config
Default Directory Modification
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:
- Manually modify it through the configuration manager's
SetPath
method; - Modify the command line startup parameter -
gf.gcfg.path
; - 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:
- Through Singleton Pattern
g.Cfg().GetAdapter().(*gcfg.AdapterFile).SetPath("/opt/config")
- Through Command Line Startup Parameter
./main --gf.gcfg.path=/opt/config/
- Through Environment Variable (commonly used in containers)
-
Modify the environment variable at startup:
GF_GCFG_PATH=/opt/config/; ./main
-
Use the
genv
module to modify environment variables: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:
func (c *AdapterFile) SetContent(content string, file ...string)
func (c *AdapterFile) GetContent(file ...string) string
func (c *AdapterFile) RemoveContent(file ...string)
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
):
server:
address: ":8199"
serverRoot: "resource/public"
database:
default:
link: "mysql:root:12345678@tcp(127.0.0.1:3306)/focus"
debug: true
For example, hierarchical reading of the above configuration file content:
// :8199
g.Cfg().Get(ctx, "server.address")
// true
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:
// config.json:
`{"map":{"key":"value"}, "slice":[59,90]}`
Example code:
var ctx = gctx.New()
m := g.Cfg().MustGet(ctx, "map").Map()
fmt.Println(m)
// Change the key-value pair.
m["key"] = "john"
// It changes the underlying key-value pair.
fmt.Println(g.Cfg().MustGet(ctx, "map").Map())
s := g.Cfg().MustGet(ctx, "slice").Slice()
fmt.Println(s)
// Change the value of specified index.
s[0] = 100
// It changes the underlying slice.
fmt.Println(g.Cfg().MustGet(ctx, "slice").Slice())
// output:
// map[key:value]
// map[key:john]
// [59 90]
// [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.