package config import ( "fmt" "os" "time" "gopkg.in/yaml.v3" ) type Config struct { ServerName string `yaml:"server_name"` DiscordWebhookURL string `yaml:"discord_webhook_url"` NotifyRoleID string `yaml:"notify_role_id"` SampleInterval time.Duration `yaml:"sample_interval"` SummaryInterval time.Duration `yaml:"summary_interval"` RequestTimeout time.Duration `yaml:"request_timeout"` Thresholds Thresholds `yaml:"thresholds"` Sites []Site `yaml:"sites"` } type Thresholds struct { DiskUsedPercentWarning float64 `yaml:"disk_used_percent_warning"` DiskUsedPercentCritical float64 `yaml:"disk_used_percent_critical"` FreeGBWarning float64 `yaml:"free_gb_warning"` FreeGBCritical float64 `yaml:"free_gb_critical"` InodeUsedPercentWarning float64 `yaml:"inode_used_percent_warning"` InodeUsedPercentCritical float64 `yaml:"inode_used_percent_critical"` MemoryUsedPercentWarning float64 `yaml:"memory_used_percent_warning"` MemoryUsedPercentCritical float64 `yaml:"memory_used_percent_critical"` SwapUsedPercentWarning float64 `yaml:"swap_used_percent_warning"` SwapUsedPercentCritical float64 `yaml:"swap_used_percent_critical"` CPUAvg15mWarning float64 `yaml:"cpu_avg_15m_warning"` CPUAvg15mCritical float64 `yaml:"cpu_avg_15m_critical"` CPUAvg12hWarning float64 `yaml:"cpu_avg_12h_warning"` CPUAvg12hCritical float64 `yaml:"cpu_avg_12h_critical"` LoadPerCoreWarning float64 `yaml:"load_per_core_warning"` LoadPerCoreCritical float64 `yaml:"load_per_core_critical"` ProcessCountWarning int `yaml:"process_count_warning"` ProcessCountCritical int `yaml:"process_count_critical"` } type Site struct { Name string `yaml:"name"` URL string `yaml:"url"` ExpectedStatus int `yaml:"expected_status"` Timeout time.Duration `yaml:"timeout"` } func Load(path string) (Config, error) { data, err := os.ReadFile(path) if err != nil { return Config{}, err } var cfg Config if err := yaml.Unmarshal(data, &cfg); err != nil { return Config{}, err } applyDefaults(&cfg) if err := cfg.Validate(); err != nil { return Config{}, err } return cfg, nil } func applyDefaults(cfg *Config) { if cfg.SampleInterval == 0 { cfg.SampleInterval = time.Minute } if cfg.SummaryInterval == 0 { cfg.SummaryInterval = 6 * time.Hour } if cfg.RequestTimeout == 0 { cfg.RequestTimeout = 10 * time.Second } for index := range cfg.Sites { if cfg.Sites[index].ExpectedStatus == 0 { cfg.Sites[index].ExpectedStatus = 200 } if cfg.Sites[index].Timeout == 0 { cfg.Sites[index].Timeout = cfg.RequestTimeout } } if cfg.Thresholds.ProcessCountWarning == 0 { cfg.Thresholds.ProcessCountWarning = 350 } if cfg.Thresholds.ProcessCountCritical == 0 { cfg.Thresholds.ProcessCountCritical = 500 } } func (cfg Config) Validate() error { if cfg.ServerName == "" { return fmt.Errorf("server_name is required") } if cfg.DiscordWebhookURL == "" { return fmt.Errorf("discord_webhook_url is required") } if cfg.SampleInterval <= 0 { return fmt.Errorf("sample_interval must be > 0") } if cfg.SummaryInterval <= 0 { return fmt.Errorf("summary_interval must be > 0") } for _, site := range cfg.Sites { if site.Name == "" { return fmt.Errorf("site name is required") } if site.URL == "" { return fmt.Errorf("site URL is required for %s", site.Name) } } return nil }