server_box_monitor/model/config.go

187 lines
4.4 KiB
Go
Raw Permalink Normal View History

2023-03-16 18:37:02 +08:00
package model
import (
2023-07-25 14:21:39 +08:00
"bytes"
2023-03-16 18:37:02 +08:00
"encoding/json"
"os"
"strconv"
"strings"
2023-03-16 18:37:02 +08:00
"time"
2023-07-15 18:01:29 +08:00
"github.com/lollipopkit/gommon/log"
"github.com/lollipopkit/gommon/rate"
"github.com/lollipopkit/gommon/sys"
2023-03-27 12:37:22 +08:00
"github.com/lollipopkit/server_box_monitor/res"
2023-03-16 18:37:02 +08:00
)
2023-03-17 14:32:59 +08:00
var (
Config = new(AppConfig)
CheckInterval time.Duration
RateLimiter *rate.RateLimiter[string]
2023-03-17 14:32:59 +08:00
)
2023-03-16 18:37:02 +08:00
type AppConfig struct {
2023-03-17 23:43:22 +08:00
Version int `json:"version"`
// Such as "7s".
// Valid time units are "s".
// Values bigger than 10 seconds are not allowed.
2023-03-17 23:43:22 +08:00
Interval string `json:"interval"`
Rate string `json:"rate"`
Name string `json:"name"`
2023-03-17 12:30:10 +08:00
Rules []Rule `json:"rules"`
Pushes []Push `json:"pushes"`
2023-03-17 14:32:59 +08:00
}
2023-07-25 14:21:39 +08:00
func InitConfig() error {
buf := new(bytes.Buffer)
enc := json.NewEncoder(buf)
enc.SetEscapeHTML(false)
enc.SetIndent("", "\t")
err := enc.Encode(DefaultAppConfig)
if err != nil {
log.Err("[CONFIG] marshal default app config failed: %v", err)
return err
}
err = os.WriteFile(res.AppConfigPath, buf.Bytes(), 0644)
if err != nil {
log.Err("[CONFIG] write default app config failed: %v", err)
return err
}
Config = DefaultAppConfig
return nil
}
2023-03-17 14:32:59 +08:00
func ReadAppConfig() error {
defer initInterval()
defer initRateLimiter()
if !sys.Exist(res.AppConfigPath) {
2023-07-25 14:21:39 +08:00
return InitConfig()
2023-03-16 18:37:02 +08:00
}
2023-03-17 12:30:10 +08:00
2023-03-16 18:37:02 +08:00
configBytes, err := os.ReadFile(res.AppConfigPath)
if err != nil {
2023-07-15 18:01:29 +08:00
log.Err("[CONFIG] read app config failed: %v", err)
2023-03-17 14:32:59 +08:00
return err
2023-03-16 18:37:02 +08:00
}
2023-03-17 14:32:59 +08:00
err = json.Unmarshal(configBytes, Config)
2023-03-16 20:44:56 +08:00
if err != nil {
2023-07-15 18:01:29 +08:00
log.Err("[CONFIG] unmarshal app config failed: %v", err)
2023-07-16 17:31:51 +08:00
} else if Config.Version < DefaultAppConfig.Version {
log.Warn("[CONFIG] app config version is too old, new config will be generated")
// Backup old config
err = os.WriteFile(res.AppConfigPath+".bak", configBytes, 0644)
if err != nil {
log.Err("[CONFIG] backup old config failed: %v", err)
return err
}
// Generate new config
2023-07-16 17:31:51 +08:00
configBytes, err := json.MarshalIndent(DefaultAppConfig, "", "\t")
if err != nil {
panic(err)
}
err = os.WriteFile(res.AppConfigPath, configBytes, 0644)
if err != nil {
panic(err)
}
log.Info("[CONFIG] new config generated, edit it and restart the program")
os.Exit(0)
2023-03-16 20:44:56 +08:00
}
2023-03-17 14:32:59 +08:00
return err
2023-03-16 18:37:02 +08:00
}
func initInterval() {
d, err := time.ParseDuration(Config.Interval)
2023-03-16 18:37:02 +08:00
if err == nil {
if d > res.MaxInterval || d < time.Second {
log.Warn("[CONFIG] use default interval")
CheckInterval = res.DefaultInterval
return
2023-03-17 20:54:51 +08:00
}
CheckInterval = d
return
2023-03-16 18:37:02 +08:00
}
log.Warn("[CONFIG] parse interval failed: %v", err)
CheckInterval = res.DefaultInterval
2023-03-17 12:30:10 +08:00
}
2023-03-17 19:17:52 +08:00
func initRateLimiter() {
splited := strings.Split(Config.Rate, "/")
if len(splited) != 2 {
log.Warn("[CONFIG] parse rate failed")
RateLimiter = res.DefaultRateLimiter
return
}
times, err := strconv.Atoi(splited[0])
if err != nil {
log.Warn("[CONFIG] parse rate failed: %v", err)
RateLimiter = res.DefaultRateLimiter
return
}
duration, err := time.ParseDuration(splited[1])
if err != nil {
log.Warn("[CONFIG] parse rate failed: %v", err)
RateLimiter = res.DefaultRateLimiter
return
}
RateLimiter = rate.NewLimiter[string](duration, times)
2023-03-18 17:27:48 +08:00
}
2023-03-17 19:17:52 +08:00
var (
2023-05-02 22:24:38 +08:00
defaultWebhookBody = map[string]interface{}{
2023-03-17 19:17:52 +08:00
"action": "send_group_msg",
"params": map[string]interface{}{
"group_id": 123456789,
"message": res.PushFormatNameLocator +
"\n" +
res.PushFormatMsgLocator,
2023-03-17 19:17:52 +08:00
},
}
2023-05-02 22:24:38 +08:00
defaultWekhookBodyBytes, _ = json.Marshal(defaultWebhookBody)
2023-03-18 12:29:32 +08:00
defaultWebhookIface = PushIfaceWebhook{
2023-03-27 12:37:22 +08:00
Url: "http://localhost:5700",
2023-03-17 19:17:52 +08:00
Headers: map[string]string{
"Content-Type": "application/json",
2023-03-17 20:54:51 +08:00
"Authorization": "Bearer YOUR_SECRET",
2023-03-17 19:17:52 +08:00
},
2023-07-15 18:01:29 +08:00
Method: "POST",
Body: defaultWekhookBodyBytes,
2023-05-03 12:35:41 +08:00
BodyRegex: ".*",
Code: 200,
2023-03-17 19:17:52 +08:00
}
defaultWebhookIfaceBytes, _ = json.Marshal(defaultWebhookIface)
2024-03-13 14:19:28 +08:00
defaultIosIface = PushIfaceIOS{
Token: "",
Title: res.PushFormatNameLocator,
Content: res.PushFormatMsgLocator,
BodyRegex: ".*",
Code: 200,
}
defaultIosIfaceBytes, _ = json.Marshal(defaultIosIface)
2023-03-17 19:17:52 +08:00
2023-07-16 17:31:51 +08:00
DefaultAppConfig = &AppConfig{
2023-07-25 14:21:39 +08:00
Version: res.ConfVersion,
Interval: res.DefaultIntervalStr,
Rate: res.DefaultRateStr,
Name: res.DefaultSeverName,
2023-03-17 19:17:52 +08:00
Rules: []Rule{
{
MonitorType: MonitorTypeCPU,
2023-07-25 14:21:39 +08:00
Threshold: `>=77%`,
Matcher: "cpu",
2023-03-17 19:17:52 +08:00
},
},
Pushes: []Push{
{
2023-07-15 18:01:29 +08:00
Type: PushTypeWebhook,
Name: "QQ Group",
Iface: defaultWebhookIfaceBytes,
2023-03-17 19:17:52 +08:00
},
2024-03-13 14:19:28 +08:00
{
Type: PushTypeIOS,
Name: "My iPhone",
Iface: defaultIosIfaceBytes,
},
2023-03-17 19:17:52 +08:00
},
}
2023-03-17 23:43:22 +08:00
)