Files
cellbot/internal/config/config.go
xiaolan ac0dfb64c9 feat: 初始化多机器人服务端项目框架
基于Go语言构建多机器人服务端框架,包含配置管理、事件总线、依赖注入等核心模块
添加项目基础结构、README、gitignore和初始代码实现
2026-01-04 21:19:17 +08:00

144 lines
3.0 KiB
Go

package config
import (
"fmt"
"sync"
"github.com/BurntSushi/toml"
"github.com/fsnotify/fsnotify"
"go.uber.org/zap"
)
// Config 应用配置结构
type Config struct {
Server ServerConfig `toml:"server"`
Log LogConfig `toml:"log"`
Protocol ProtocolConfig `toml:"protocol"`
}
// ServerConfig 服务器配置
type ServerConfig struct {
Host string `toml:"host"`
Port int `toml:"port"`
}
// LogConfig 日志配置
type LogConfig struct {
Level string `toml:"level"`
Output string `toml:"output"`
MaxSize int `toml:"max_size"`
MaxBackups int `toml:"max_backups"`
MaxAge int `toml:"max_age"`
}
// ProtocolConfig 协议配置
type ProtocolConfig struct {
Name string `toml:"name"`
Version string `toml:"version"`
Options map[string]string `toml:"options"`
}
// ConfigManager 配置管理器
type ConfigManager struct {
configPath string
config *Config
logger *zap.Logger
mu sync.RWMutex
callbacks []func(*Config)
}
// NewConfigManager 创建配置管理器
func NewConfigManager(configPath string, logger *zap.Logger) *ConfigManager {
return &ConfigManager{
configPath: configPath,
logger: logger,
callbacks: make([]func(*Config), 0),
}
}
// Load 加载配置文件
func (cm *ConfigManager) Load() error {
cm.mu.Lock()
defer cm.mu.Unlock()
var cfg Config
if _, err := toml.DecodeFile(cm.configPath, &cfg); err != nil {
return fmt.Errorf("failed to decode config: %w", err)
}
cm.config = &cfg
cm.logger.Info("Config loaded successfully",
zap.String("path", cm.configPath),
zap.String("server", fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port)),
)
// 触发回调
for _, cb := range cm.callbacks {
cb(cm.config)
}
return nil
}
// Get 获取当前配置
func (cm *ConfigManager) Get() *Config {
cm.mu.RLock()
defer cm.mu.RUnlock()
return cm.config
}
// Reload 重新加载配置
func (cm *ConfigManager) Reload() error {
return cm.Load()
}
// RegisterCallback 注册配置变更回调
func (cm *ConfigManager) RegisterCallback(callback func(*Config)) {
cm.mu.Lock()
defer cm.mu.Unlock()
cm.callbacks = append(cm.callbacks, callback)
}
// Watch 监听配置文件变化
func (cm *ConfigManager) Watch() error {
watcher, err := fsnotify.NewWatcher()
if err != nil {
return fmt.Errorf("failed to create watcher: %w", err)
}
if err := watcher.Add(cm.configPath); err != nil {
return fmt.Errorf("failed to watch config file: %w", err)
}
go func() {
for {
select {
case event, ok := <-watcher.Events:
if !ok {
return
}
if event.Op&fsnotify.Write == fsnotify.Write {
cm.logger.Info("Config file changed, reloading...",
zap.String("file", event.Name))
if err := cm.Reload(); err != nil {
cm.logger.Error("Failed to reload config",
zap.Error(err))
}
}
case err, ok := <-watcher.Errors:
if !ok {
return
}
cm.logger.Error("Watcher error", zap.Error(err))
}
}
}()
return nil
}
// Close 关闭配置管理器
func (cm *ConfigManager) Close() error {
return nil
}