kiss server monitoring tool with email alerts
go
monitoring
1package main
2
3import (
4 "fmt"
5 "os"
6 "time"
7
8 "gopkg.in/yaml.v3"
9)
10
11// Config is a struct that holds the configuration for the monitoring service.
12type Config struct {
13 AlertThresholds Thresholds `yaml:"alert_thresholds"`
14 Email Email `yaml:"email"`
15}
16
17type Thresholds struct {
18 CPU ThresholdConfig `yaml:"cpu"`
19 Memory ThresholdConfig `yaml:"memory"`
20 Disk ThresholdConfig `yaml:"disk"`
21 HTTP HTTP `yaml:"http"`
22}
23
24type ThresholdConfig struct {
25 Threshold float64 `yaml:"threshold"`
26 Duration time.Duration `yaml:"duration,omitempty"`
27 Cooldown time.Duration `yaml:"cooldown"`
28}
29
30type HTTP struct {
31 URL string `yaml:"url"`
32 Timeout time.Duration `yaml:"timeout"`
33 SampleRate int `yaml:"sample_rate"`
34 FailureThreshold float64 `yaml:"failure_threshold"`
35 CheckInterval time.Duration `yaml:"check_interval"`
36 Cooldown time.Duration `yaml:"cooldown"`
37}
38
39type Email struct {
40 SMTPServer string `yaml:"smtp_server"`
41 From string `yaml:"from"`
42 To string `yaml:"to"`
43 Username string `yaml:"username"`
44 Password string `yaml:"password"`
45}
46
47func (c *Config) Save(path string) error {
48 out, err := yaml.Marshal(c)
49 if err != nil {
50 return fmt.Errorf("failed to marshal config: %w", err)
51 }
52
53 if err := os.WriteFile(path, out, 0644); err != nil {
54 return fmt.Errorf("error generating sample config: %w", err)
55 }
56
57 return nil
58}
59
60// defaultConfig returns a default configuration for the monitoring service.
61func defaultConfig() *Config {
62 return &Config{
63 AlertThresholds: Thresholds{
64 CPU: ThresholdConfig{
65 Threshold: 90,
66 Duration: 5 * time.Minute,
67 Cooldown: 30 * time.Minute,
68 },
69 Memory: ThresholdConfig{
70 Threshold: 80,
71 Cooldown: 30 * time.Minute,
72 },
73 Disk: ThresholdConfig{
74 Threshold: 90,
75 Cooldown: 4 * time.Hour,
76 },
77 HTTP: HTTP{
78 URL: "http://localhost:8080/health",
79 Timeout: 5 * time.Second,
80 SampleRate: 10,
81 FailureThreshold: 20,
82 CheckInterval: 1 * time.Minute,
83 Cooldown: 15 * time.Minute,
84 },
85 },
86 Email: Email{
87 SMTPServer: "smtp.example.com",
88 From: "alerts@example.com",
89 To: "admin@example.com",
90 Username: "alertuser",
91 Password: "alertpassword",
92 },
93 }
94}
95
96// loadConfig loads a configuration from a file.
97func loadConfig(path string) (*Config, error) {
98 data, err := os.ReadFile(path)
99 if err != nil {
100 return nil, fmt.Errorf("error reading config file: %w", err)
101 }
102
103 var cfg Config
104 if err := yaml.Unmarshal(data, &cfg); err != nil {
105 return nil, fmt.Errorf("error unmarshaling config: %w", err)
106 }
107
108 return &cfg, nil
109}