mirror of
https://github.com/lollipopkit/server_box_monitor.git
synced 2025-01-08 11:47:36 +08:00
187 lines
4.4 KiB
Go
187 lines
4.4 KiB
Go
package model
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/lollipopkit/gommon/log"
|
|
"github.com/lollipopkit/gommon/rate"
|
|
"github.com/lollipopkit/gommon/sys"
|
|
"github.com/lollipopkit/server_box_monitor/res"
|
|
)
|
|
|
|
var (
|
|
Config = new(AppConfig)
|
|
CheckInterval time.Duration
|
|
RateLimiter *rate.RateLimiter[string]
|
|
)
|
|
|
|
type AppConfig struct {
|
|
Version int `json:"version"`
|
|
// Such as "7s".
|
|
// Valid time units are "s".
|
|
// Values bigger than 10 seconds are not allowed.
|
|
Interval string `json:"interval"`
|
|
Rate string `json:"rate"`
|
|
Name string `json:"name"`
|
|
Rules []Rule `json:"rules"`
|
|
Pushes []Push `json:"pushes"`
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
func ReadAppConfig() error {
|
|
defer initInterval()
|
|
defer initRateLimiter()
|
|
if !sys.Exist(res.AppConfigPath) {
|
|
return InitConfig()
|
|
}
|
|
|
|
configBytes, err := os.ReadFile(res.AppConfigPath)
|
|
if err != nil {
|
|
log.Err("[CONFIG] read app config failed: %v", err)
|
|
return err
|
|
}
|
|
err = json.Unmarshal(configBytes, Config)
|
|
if err != nil {
|
|
log.Err("[CONFIG] unmarshal app config failed: %v", err)
|
|
} 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
|
|
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)
|
|
}
|
|
return err
|
|
}
|
|
|
|
func initInterval() {
|
|
d, err := time.ParseDuration(Config.Interval)
|
|
if err == nil {
|
|
if d > res.MaxInterval || d < time.Second {
|
|
log.Warn("[CONFIG] use default interval")
|
|
CheckInterval = res.DefaultInterval
|
|
return
|
|
}
|
|
CheckInterval = d
|
|
return
|
|
}
|
|
log.Warn("[CONFIG] parse interval failed: %v", err)
|
|
CheckInterval = res.DefaultInterval
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
var (
|
|
defaultWebhookBody = map[string]interface{}{
|
|
"action": "send_group_msg",
|
|
"params": map[string]interface{}{
|
|
"group_id": 123456789,
|
|
"message": res.PushFormatNameLocator +
|
|
"\n" +
|
|
res.PushFormatMsgLocator,
|
|
},
|
|
}
|
|
defaultWekhookBodyBytes, _ = json.Marshal(defaultWebhookBody)
|
|
defaultWebhookIface = PushIfaceWebhook{
|
|
Url: "http://localhost:5700",
|
|
Headers: map[string]string{
|
|
"Content-Type": "application/json",
|
|
"Authorization": "Bearer YOUR_SECRET",
|
|
},
|
|
Method: "POST",
|
|
Body: defaultWekhookBodyBytes,
|
|
BodyRegex: ".*",
|
|
Code: 200,
|
|
}
|
|
defaultWebhookIfaceBytes, _ = json.Marshal(defaultWebhookIface)
|
|
defaultIosIface = PushIfaceIOS{
|
|
Token: "",
|
|
Title: res.PushFormatNameLocator,
|
|
Content: res.PushFormatMsgLocator,
|
|
BodyRegex: ".*",
|
|
Code: 200,
|
|
}
|
|
defaultIosIfaceBytes, _ = json.Marshal(defaultIosIface)
|
|
|
|
DefaultAppConfig = &AppConfig{
|
|
Version: res.ConfVersion,
|
|
Interval: res.DefaultIntervalStr,
|
|
Rate: res.DefaultRateStr,
|
|
Name: res.DefaultSeverName,
|
|
Rules: []Rule{
|
|
{
|
|
MonitorType: MonitorTypeCPU,
|
|
Threshold: `>=77%`,
|
|
Matcher: "cpu",
|
|
},
|
|
},
|
|
Pushes: []Push{
|
|
{
|
|
Type: PushTypeWebhook,
|
|
Name: "QQ Group",
|
|
Iface: defaultWebhookIfaceBytes,
|
|
},
|
|
{
|
|
Type: PushTypeIOS,
|
|
Name: "My iPhone",
|
|
Iface: defaultIosIfaceBytes,
|
|
},
|
|
},
|
|
}
|
|
)
|