package config import ( "fmt" "os" "reflect" "sync" "time" "github.com/BurntSushi/toml" "github.com/fsnotify/fsnotify" "github.com/sirupsen/logrus" ) var ( config map[string]interface{} mu sync.RWMutex ) // loadConfig 加载配置文件 func loadConfig() error { // mu.Lock() // defer mu.Unlock() _, err := toml.DecodeFile("config.toml", &config) if err != nil { logrus.Errorf("Failed to decode config file: %v", err) } return err } // GetConfig 获取配置 func GetConfig() map[string]interface{} { // mu.RLock() if err := loadConfig(); err != nil { fmt.Printf("加载配置文件失败: %v\n", err) os.Exit(1) } return config } // ReloadConfig 重新加载配置文件 func ReloadConfig() error { mu.Lock() defer mu.Unlock() if err := loadConfig(); err != nil { logrus.Errorf("failed to reload config: %v", err) return err } logrus.Infof("Config reloaded successfully:%v", config) return nil } // GetConfigValue 获取配置值 func GetConfigValue(key string) interface{} { mu.RLock() defer mu.RUnlock() return config[key] } // ModifyConfig 修改配置并写回文件 func ModifyConfig(key string, value interface{}) error { mu.Lock() defer mu.Unlock() config[key] = value file, err := os.Create("config.toml") if err != nil { return err } defer file.Close() encoder := toml.NewEncoder(file) return encoder.Encode(config) } // PrintConfig 递归打印配置内容 func PrintConfig(m map[string]interface{}, indent string) { for key, value := range m { switch v := value.(type) { case map[string]interface{}: fmt.Printf("%s%s (type: %s):\n", indent, key, reflect.TypeOf(v)) PrintConfig(v, indent+" ") case []interface{}: fmt.Printf("%s%s:\n", indent, key) for i, item := range v { switch itemValue := item.(type) { case map[string]interface{}: fmt.Printf("%s [%d] (type: %s):\n", indent, i, reflect.TypeOf(itemValue)) PrintConfig(itemValue, indent+" ") default: fmt.Printf("%s [%d] (type: %s): %v\n", indent, i, reflect.TypeOf(itemValue), item) } } default: fmt.Printf("%s%s (type: %s): %v\n", indent, key, reflect.TypeOf(value), value) } } } // 监听配置文件变化 func WatchConfig(filepath string) { watcher, err := fsnotify.NewWatcher() if err != nil { logrus.Fatalf("Failed to create watcher: %v", err) } defer watcher.Close() err = watcher.Add(filepath) if err != nil { logrus.Fatalf("Failed to add file to watcher: %v", err) } var debounceTimer *time.Timer for { select { case event, ok := <-watcher.Events: if !ok { return } if event.Op&(fsnotify.Write|fsnotify.Rename) != 0 { if debounceTimer != nil { debounceTimer.Stop() } debounceTimer = time.AfterFunc(500*time.Millisecond, func() { logrus.Info("Config file changed, reloading...") go func() { if err := ReloadConfig(); err != nil { logrus.Errorf("Failed to reload config: %v", err) } }() }) } case err, ok := <-watcher.Errors: if !ok { return } logrus.Errorf("Watcher error: %v", err) } } } // 启动监听配置文件的协程 func StartWatching(filepath string) { go WatchConfig(filepath) }