162 lines
3.9 KiB
Go
162 lines
3.9 KiB
Go
package storage
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"time"
|
|
|
|
"mengyaping-backend/config"
|
|
)
|
|
|
|
const (
|
|
kvKeyServer = "cfg_server"
|
|
kvKeyMonitor = "cfg_monitor"
|
|
kvKeyDataPath = "cfg_data_path"
|
|
kvKeyDatabase = "cfg_database"
|
|
)
|
|
|
|
type monitorKVPayload struct {
|
|
IntervalMinutes int `json:"interval_minutes"`
|
|
TimeoutSeconds int `json:"timeout_seconds"`
|
|
RetryCount int `json:"retry_count"`
|
|
HistoryDays int `json:"history_days"`
|
|
}
|
|
|
|
func (s *Storage) getKVRaw(key string) string {
|
|
var row MonitorKV
|
|
s.db.Where("cfg_key = ?", key).Limit(1).Find(&row)
|
|
if row.CfgKey == "" {
|
|
return ""
|
|
}
|
|
return row.CfgValue
|
|
}
|
|
|
|
func (s *Storage) setKVRaw(key, val string) error {
|
|
var row MonitorKV
|
|
s.db.Where("cfg_key = ?", key).Limit(1).Find(&row)
|
|
if row.CfgKey == "" {
|
|
return s.db.Create(&MonitorKV{CfgKey: key, CfgValue: val}).Error
|
|
}
|
|
row.CfgValue = val
|
|
return s.db.Save(&row).Error
|
|
}
|
|
|
|
// loadAndSyncAppConfig 从 monitor_kv 覆盖内存配置,再写回全量(补全缺省键、统一格式)
|
|
func (s *Storage) loadAndSyncAppConfig() {
|
|
cfg := config.GetConfig()
|
|
|
|
if v := s.getKVRaw(kvKeyServer); v != "" {
|
|
var sc config.ServerConfig
|
|
if err := json.Unmarshal([]byte(v), &sc); err != nil {
|
|
log.Printf("解析 %s: %v", kvKeyServer, err)
|
|
} else {
|
|
if sc.Port != "" {
|
|
cfg.Server.Port = sc.Port
|
|
}
|
|
if sc.Host != "" {
|
|
cfg.Server.Host = sc.Host
|
|
}
|
|
}
|
|
}
|
|
|
|
if v := s.getKVRaw(kvKeyMonitor); v != "" {
|
|
var m monitorKVPayload
|
|
if err := json.Unmarshal([]byte(v), &m); err != nil {
|
|
log.Printf("解析 %s: %v", kvKeyMonitor, err)
|
|
} else {
|
|
if m.IntervalMinutes > 0 {
|
|
snapped := config.SnapMonitorIntervalMinutes(m.IntervalMinutes)
|
|
cfg.Monitor.Interval = time.Duration(snapped) * time.Minute
|
|
}
|
|
if m.TimeoutSeconds > 0 {
|
|
cfg.Monitor.Timeout = time.Duration(m.TimeoutSeconds) * time.Second
|
|
}
|
|
if m.RetryCount > 0 {
|
|
cfg.Monitor.RetryCount = m.RetryCount
|
|
}
|
|
if m.HistoryDays > 0 {
|
|
cfg.Monitor.HistoryDays = m.HistoryDays
|
|
}
|
|
}
|
|
}
|
|
|
|
if v := s.getKVRaw(kvKeyDataPath); v != "" {
|
|
cfg.DataPath = v
|
|
}
|
|
|
|
if v := s.getKVRaw(kvKeyDatabase); v != "" {
|
|
var dc config.DatabaseConfig
|
|
if err := json.Unmarshal([]byte(v), &dc); err != nil {
|
|
log.Printf("解析 %s: %v", kvKeyDatabase, err)
|
|
} else {
|
|
if dc.Host != "" {
|
|
cfg.Database.Host = dc.Host
|
|
}
|
|
if dc.Port != "" {
|
|
cfg.Database.Port = dc.Port
|
|
}
|
|
if dc.User != "" {
|
|
cfg.Database.User = dc.User
|
|
}
|
|
if dc.Password != "" {
|
|
cfg.Database.Password = dc.Password
|
|
}
|
|
if dc.Database != "" {
|
|
cfg.Database.Database = dc.Database
|
|
}
|
|
}
|
|
}
|
|
|
|
if err := s.PersistAppConfig(); err != nil {
|
|
log.Printf("同步应用配置到 monitor_kv: %v", err)
|
|
}
|
|
}
|
|
|
|
// PersistAppConfig 将当前内存中的 server/monitor/data_path/database 写入 monitor_kv
|
|
func (s *Storage) PersistAppConfig() error {
|
|
cfg := config.GetConfig()
|
|
|
|
b, err := json.Marshal(cfg.Server)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := s.setKVRaw(kvKeyServer, string(b)); err != nil {
|
|
return err
|
|
}
|
|
|
|
m := monitorKVPayload{
|
|
IntervalMinutes: config.SnapMonitorIntervalMinutes(int(cfg.Monitor.Interval / time.Minute)),
|
|
TimeoutSeconds: int(cfg.Monitor.Timeout.Seconds()),
|
|
RetryCount: cfg.Monitor.RetryCount,
|
|
HistoryDays: cfg.Monitor.HistoryDays,
|
|
}
|
|
b, err = json.Marshal(m)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := s.setKVRaw(kvKeyMonitor, string(b)); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := s.setKVRaw(kvKeyDataPath, cfg.DataPath); err != nil {
|
|
return err
|
|
}
|
|
|
|
b, err = json.Marshal(cfg.Database)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return s.setKVRaw(kvKeyDatabase, string(b))
|
|
}
|
|
|
|
// SetMonitorIntervalMinutes 更新检测周期并写入 monitor_kv
|
|
func (s *Storage) SetMonitorIntervalMinutes(minutes int) error {
|
|
if !config.IsAllowedMonitorInterval(minutes) {
|
|
return fmt.Errorf("interval_minutes 必须是预设值之一: %v", config.AllowedMonitorIntervalMinutes)
|
|
}
|
|
cfg := config.GetConfig()
|
|
cfg.Monitor.Interval = time.Duration(minutes) * time.Minute
|
|
return s.PersistAppConfig()
|
|
}
|