-
Notifications
You must be signed in to change notification settings - Fork 0
Example ENG
ConfigManager - is the default means of communication between you and the mkconf
module. It will help you create, read, update and start tracking your config. If you don't like its implementation, you can create your own. The example will use ConfigManager.
To add a configuration, the AddConfig function is used, which accepts a configuration name, a path to the configuration file, a file extension, and a pointer to the configuration structure.
cm := mkconf.NewConfigManager()
configPath := "C:\\My saved files\\testConfig" configName := "config"
cm.AddConfig(configName, configPath, ".json", &cf1)
&cf1
is a pointer to your configuration structure:
type MyConfig struct {
Key string `json:"key"`
Value int `json:"value"`
}
These methods start change tracking and begin change monitoring for a configuration named config. You can receive only the change notification, only the change history, or both.
cm.StartAllLogChanges()
cm.StartChangeMonitoring("config", cf1)
To use them, you need to define callback functions:
changeCallback := func(configName string) {
myCallbacks1(cm, configName, &cf1)
}
trackingCallback := func(configName string) {
myCallbacks2(cm, configName)
}
cm.ChangeCallbackFunc(configName, changeCallback)
cm.TrackingCallbackFunc(configName, trackingCallback)
My callback functions look like this:
func myCallbacks1(cm *mkconf.ConfigManager, configName string, cf1 *MyConfig) {
fmt.Printf("Reload config '%v'.\n", configName)
cm.LoadConfig(configName)
cf, err := cm.GetConfig(configName)
if err != nil {
fmt.Printf("Error while reading config: %v\n", err)
return
}
*cf1 = *cf.(*MyConfig)
fmt.Printf("Key : %v\n", cf1.Key)
fmt.Printf("Value : %v\n", cf1.Value)
}
func myCallbacks2(cm *mkconf.ConfigManager, configName string) {
ff := cm.GetChangesForConfig(configName)
for i, v := range ff {
fmt.Printf("Changes №%v %v:\n", i+1, v.Timestamp.Format("02.01.2006 15:04:05.000"))
fmt.Printf("%v: old value: %v new value:%v \n", v.FieldName, v.OldValue, v.NewValue)
}
cm.ClearChangeLogs(configName)
fmt.Println()
fmt.Println()
fmt.Println()
fmt.Println()
}
These are demo functions that show the changes. You can use any kind you want.
cm.ClearChangeLogs(configName)
is optional. By default, the entire list of changes is stored and it is not deleted. If you need to keep it - you can choose not to clear it.
This step starts asynchronous tracking of configuration changes. If an error occurs, it will be sent to the errChan error channel.
errChan := make(chan error)
go func() {
err := cm.WatchForChanges()
if err != nil {
errChan <- err
}
}()
cm.WatchForChanges()
automatically receives signals from channels about changes to the file and updates the change logs. It runs a callback that you have set up in advance. If it has NOT been installed, you will get an error.
Reload config 'config'.
Key : da
Value : 9
Changes №1 18.04.2024 10:02:16.981:
key: old value: net new value:da
Reload config 'config'.
Key : ili net
Value : 15
Changes №1 18.04.2024 10:02:26.091:
key: old value: da new value:ili net
Changes №2 18.04.2024 10:02:26.091:
value: old value: 9 new value:15
Here we define the configuration structures MyConfig, MyConfig2 and MyConfig3. For each configuration an instance of the corresponding structure is created. After that, a slice of itf interfaces is created, to which pointers to the previously created configuration instances are added.
cf1 := MyConfig{}
cf2 := MyConfig2{}
cf3 := MyConfig3{}
configPath := "C:\\My saved files\\testConfig"
configNames := []string{"config.json", "config2.json", "config3.xml"}
var itf []interface{}
itf = append(itf, &cf1, &cf2, &cf3)
cm := mkconf.NewConfigManager()
Configurations from the specified path with the specified file names are loaded here. Each configuration is associated with the corresponding interface from the itf slice.
errors := cm.LoadConfigsFromPath(configPath, configNames, itf)
for _, err := range errors {
if err != nil {
fmt.Printf("error: %v", err)
}
}
Callback functions can also be set for each config separately, or for all of them at once. This function assigns one callback for all configurations. The changeCallback function will be called when any of the configurations is changed.
changeCallback := func(configName string) {
myCallbacksAll1(cm, configName, itf)
}
cm.ChangeCallbackFuncAll(changeCallback)
cm.StartAllChangeMonitoring()
func myCallbacksAll1(cm *mkconf.ConfigManager, configName string, cfs []interface{}) {
fmt.Printf("Reload config '%v'.\n", configName)
cm.LoadConfig(configName)
cf, err := cm.GetConfig(configName)
if err != nil {
fmt.Printf("Error while reading config: %v\n", err)
return
}
switch v := cf.(type) {
case *MyConfig:
fmt.Printf("Key : %v\n", v.Key)
fmt.Printf("Value : %v\n", v.Value)
cfs[0] = v
case *MyConfig2:
fmt.Printf("Key : %v\n", v.Key)
fmt.Printf("Value : %v\n", v.Value)
cfs[1] = v
case *MyConfig3:
fmt.Printf("Database : %v\n", v.Database)
fmt.Printf("Logging : %v\n", v.Logging)
fmt.Printf("ServerInfo : %v\n", v.ServerInfo)
cfs[2] = v
default:
fmt.Printf("hz cho za tip")
}
}
This is a test generic callback. This is an example for outputting and updating the modified config.
The following configs are used in the example:
type MyConfig struct {
Key string `json:"key"`
Value int `json:"value"`
}
type MyConfig2 struct {
Key string `yaml:"key"`
Value string `yaml:"value"`
}
type MyConfig3 struct {
XMLName xml.Name `xml:"config"`
ServerInfo ServerInfo `xml:"server_info"`
Database Database `xml:"database"`
Logging Logging `xml:"logging"`
}
type ServerInfo struct {
Host string `xml:"host"`
Port int `xml:"port"`
}
type Database struct {
DatabaseName string `xml:"database_name"`
User string `xml:"user"`
Password string `xml:"password"`
}
type Logging struct {
Level string `xml:"level"`
Output string `xml:"output"`
}
This step starts asynchronous tracking of configuration changes. If an error occurs, it will be sent to the errChan error channel.
errChan := make(chan error)
go func() {
err := cm.WatchForChanges()
if err != nil {
errChan <- err
}
}()
cm.WatchForChanges()
automatically receives signals from channels about changes to the file and updates the change logs. It runs a callback that you have set up in advance. If it has NOT been installed, you will get an error.
Reload config 'config'.
Key : a)))
Value : 15
Reload config 'config2'.
Key : hi.
Value : !!!
Reload config 'config3'.
Database : {my_database admin secretpassword}
Logging : {info logs/app.log}
ServerInfo : {example.ua.com 8080}