177 lines
4.6 KiB
Go
177 lines
4.6 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// Config 应用配置
|
|
type Config struct {
|
|
Server ServerConfig `json:"server"`
|
|
Monitor MonitorConfig `json:"monitor"`
|
|
DataPath string `json:"data_path"`
|
|
}
|
|
|
|
// ServerConfig 服务器配置
|
|
type ServerConfig struct {
|
|
Port string `json:"port"`
|
|
Host string `json:"host"`
|
|
}
|
|
|
|
// MonitorConfig 监控配置
|
|
type MonitorConfig struct {
|
|
Interval time.Duration `json:"interval"` // 检测间隔
|
|
Timeout time.Duration `json:"timeout"` // 请求超时时间
|
|
RetryCount int `json:"retry_count"` // 重试次数
|
|
HistoryDays int `json:"history_days"` // 保留历史天数
|
|
}
|
|
|
|
var (
|
|
cfg *Config
|
|
once sync.Once
|
|
)
|
|
|
|
// GetConfig 获取配置单例
|
|
func GetConfig() *Config {
|
|
once.Do(func() {
|
|
cfg = &Config{
|
|
Server: ServerConfig{
|
|
Port: getEnv("SERVER_PORT", "8080"),
|
|
Host: getEnv("SERVER_HOST", "0.0.0.0"),
|
|
},
|
|
Monitor: MonitorConfig{
|
|
Interval: parseDuration(getEnv("MONITOR_INTERVAL", "1h"), 1*time.Hour),
|
|
Timeout: parseDuration(getEnv("MONITOR_TIMEOUT", "10s"), 10*time.Second),
|
|
RetryCount: parseInt(getEnv("MONITOR_RETRY_COUNT", "3"), 3),
|
|
HistoryDays: parseInt(getEnv("MONITOR_HISTORY_DAYS", "90"), 90),
|
|
},
|
|
DataPath: getEnv("DATA_PATH", "./data"),
|
|
}
|
|
|
|
// 尝试从配置文件加载(会覆盖环境变量配置)
|
|
loadConfigFromFile()
|
|
})
|
|
return cfg
|
|
}
|
|
|
|
// getEnv 获取环境变量,如果不存在则返回默认值
|
|
func getEnv(key, defaultValue string) string {
|
|
if value := os.Getenv(key); value != "" {
|
|
return value
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
// parseInt 解析整数环境变量
|
|
func parseInt(value string, defaultValue int) int {
|
|
if value == "" {
|
|
return defaultValue
|
|
}
|
|
var result int
|
|
if _, err := fmt.Sscanf(value, "%d", &result); err != nil {
|
|
return defaultValue
|
|
}
|
|
return result
|
|
}
|
|
|
|
// parseDuration 解析时间间隔环境变量
|
|
func parseDuration(value string, defaultValue time.Duration) time.Duration {
|
|
if value == "" {
|
|
return defaultValue
|
|
}
|
|
if duration, err := time.ParseDuration(value); err == nil {
|
|
return duration
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
// loadConfigFromFile 从文件加载配置
|
|
func loadConfigFromFile() {
|
|
configFile := "./data/config.json"
|
|
if _, err := os.Stat(configFile); os.IsNotExist(err) {
|
|
return
|
|
}
|
|
|
|
data, err := os.ReadFile(configFile)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
var fileCfg struct {
|
|
Server ServerConfig `json:"server"`
|
|
Monitor struct {
|
|
IntervalMinutes int `json:"interval_minutes"`
|
|
TimeoutSeconds int `json:"timeout_seconds"`
|
|
RetryCount int `json:"retry_count"`
|
|
HistoryDays int `json:"history_days"`
|
|
} `json:"monitor"`
|
|
DataPath string `json:"data_path"`
|
|
}
|
|
|
|
if err := json.Unmarshal(data, &fileCfg); err != nil {
|
|
return
|
|
}
|
|
|
|
if fileCfg.Server.Port != "" {
|
|
cfg.Server.Port = fileCfg.Server.Port
|
|
}
|
|
if fileCfg.Server.Host != "" {
|
|
cfg.Server.Host = fileCfg.Server.Host
|
|
}
|
|
if fileCfg.Monitor.IntervalMinutes > 0 {
|
|
cfg.Monitor.Interval = time.Duration(fileCfg.Monitor.IntervalMinutes) * time.Minute
|
|
}
|
|
if fileCfg.Monitor.TimeoutSeconds > 0 {
|
|
cfg.Monitor.Timeout = time.Duration(fileCfg.Monitor.TimeoutSeconds) * time.Second
|
|
}
|
|
if fileCfg.Monitor.RetryCount > 0 {
|
|
cfg.Monitor.RetryCount = fileCfg.Monitor.RetryCount
|
|
}
|
|
if fileCfg.Monitor.HistoryDays > 0 {
|
|
cfg.Monitor.HistoryDays = fileCfg.Monitor.HistoryDays
|
|
}
|
|
if fileCfg.DataPath != "" {
|
|
cfg.DataPath = fileCfg.DataPath
|
|
}
|
|
}
|
|
|
|
// SaveConfig 保存配置到文件
|
|
func SaveConfig() error {
|
|
configFile := cfg.DataPath + "/config.json"
|
|
|
|
fileCfg := struct {
|
|
Server ServerConfig `json:"server"`
|
|
Monitor struct {
|
|
IntervalMinutes int `json:"interval_minutes"`
|
|
TimeoutSeconds int `json:"timeout_seconds"`
|
|
RetryCount int `json:"retry_count"`
|
|
HistoryDays int `json:"history_days"`
|
|
} `json:"monitor"`
|
|
DataPath string `json:"data_path"`
|
|
}{
|
|
Server: cfg.Server,
|
|
Monitor: struct {
|
|
IntervalMinutes int `json:"interval_minutes"`
|
|
TimeoutSeconds int `json:"timeout_seconds"`
|
|
RetryCount int `json:"retry_count"`
|
|
HistoryDays int `json:"history_days"`
|
|
}{
|
|
IntervalMinutes: int(cfg.Monitor.Interval.Minutes()),
|
|
TimeoutSeconds: int(cfg.Monitor.Timeout.Seconds()),
|
|
RetryCount: cfg.Monitor.RetryCount,
|
|
HistoryDays: cfg.Monitor.HistoryDays,
|
|
},
|
|
DataPath: cfg.DataPath,
|
|
}
|
|
|
|
data, err := json.MarshalIndent(fileCfg, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return os.WriteFile(configFile, data, 0644)
|
|
}
|