feat(config): 增加配置文件热重载功能并优化日志输出
This commit is contained in:
parent
1a146d4bfb
commit
d944a913eb
4 changed files with 90 additions and 21 deletions
|
@ -5,35 +5,55 @@ import (
|
|||
"os"
|
||||
"reflect"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var (
|
||||
config map[string]interface{}
|
||||
mu sync.RWMutex
|
||||
once sync.Once
|
||||
)
|
||||
|
||||
// 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 获取配置,使用 sync.Once 确保只加载一次
|
||||
// GetConfig 获取配置
|
||||
func GetConfig() map[string]interface{} {
|
||||
once.Do(func() {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if err := loadConfig(); err != nil {
|
||||
fmt.Printf("加载配置文件失败: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
})
|
||||
// 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()
|
||||
|
@ -41,13 +61,6 @@ func GetConfigValue(key string) interface{} {
|
|||
return config[key]
|
||||
}
|
||||
|
||||
// ReloadConfig 重新加载配置文件
|
||||
func ReloadConfig() error {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
return loadConfig()
|
||||
}
|
||||
|
||||
// ModifyConfig 修改配置并写回文件
|
||||
func ModifyConfig(key string, value interface{}) error {
|
||||
mu.Lock()
|
||||
|
@ -88,3 +101,52 @@ func PrintConfig(m map[string]interface{}, indent string) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 监听配置文件变化
|
||||
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)
|
||||
}
|
||||
|
|
1
go.mod
1
go.mod
|
@ -57,6 +57,7 @@ require (
|
|||
require (
|
||||
github.com/PuerkitoBio/goquery v1.9.2
|
||||
github.com/andybalholm/brotli v1.1.0
|
||||
github.com/fsnotify/fsnotify v1.8.0
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
github.com/imroc/req/v3 v3.44.0
|
||||
|
|
2
go.sum
2
go.sum
|
@ -26,6 +26,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
|
||||
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
|
|
12
main.go
12
main.go
|
@ -123,10 +123,9 @@ func main() {
|
|||
logrus.Fatalf("Failed to initialize app: %v", err)
|
||||
}
|
||||
cfg := config.GetConfig()
|
||||
APIURL, ok := cfg["APIURL"].(string)
|
||||
if !ok {
|
||||
logrus.Fatalf("加载配置失败!")
|
||||
}
|
||||
|
||||
// 启动文件监听
|
||||
config.StartWatching("config.toml")
|
||||
// config.PrintConfig(cfg, "")
|
||||
|
||||
// 在 App 初始化后统一使用 app.Logger
|
||||
|
@ -134,6 +133,11 @@ func main() {
|
|||
app.Logger.Fatalf("Failed to initialize database: %v", err)
|
||||
}
|
||||
|
||||
APIURL, ok := cfg["APIURL"].(string)
|
||||
|
||||
if !ok {
|
||||
logrus.Fatalf("加载配置失败!")
|
||||
}
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
r := gin.Default()
|
||||
r.POST("/", func(c *gin.Context) {
|
||||
|
|
Loading…
Reference in a new issue