mirror of
https://github.com/lollipopkit/server_box_monitor.git
synced 2025-01-08 11:47:36 +08:00
new & opt.
- new: add time for msg - new: `rate` for push - opt.: interval
This commit is contained in:
parent
5913686cec
commit
61947378d9
@ -1,10 +1,13 @@
|
||||
{
|
||||
"version": 1,
|
||||
"version": 2,
|
||||
// Interval of checking
|
||||
// Valid formats: 1s 1m 1h
|
||||
// Default: 30s
|
||||
// Values less than 10s will be ignored
|
||||
"interval": "1m",
|
||||
// Rate limiter for msg push
|
||||
// eg: 3/1m (3 times every minute), 1/10s (1 time every 10 seconds)
|
||||
"rate": "1/10s",
|
||||
// Check rules
|
||||
//
|
||||
// Type:
|
||||
@ -75,7 +78,7 @@
|
||||
// body_regex: regex to match the response body
|
||||
// code: response code to match
|
||||
//
|
||||
// {{key}} and {{value}} will be replaced with the key and value of the check
|
||||
// {{kvs}} will be replaced with the key and value of the check
|
||||
"pushes": [
|
||||
{
|
||||
// This is a example for QQ Group message
|
||||
@ -97,7 +100,7 @@
|
||||
"action": "send_group_msg",
|
||||
"params": {
|
||||
"group_id": 123456789,
|
||||
"message": "ServerBox Notification\n{{key}}: {{value}}"
|
||||
"message": "ServerBox Notification\n{{kvs}}"
|
||||
}
|
||||
},
|
||||
// Check push is successful or not:
|
||||
@ -116,7 +119,7 @@
|
||||
// You can get it from settings page of ServerBox iOS app
|
||||
"token": "YOUR_TOKEN",
|
||||
"title": "Server Notification",
|
||||
"content": "{{key}}: {{value}}",
|
||||
"content": "{{kvs}}",
|
||||
"body_regex": ".*",
|
||||
"code": 200
|
||||
}
|
||||
@ -128,7 +131,7 @@
|
||||
// Details please refer to https://sct.ftqq.com/
|
||||
"sckey": "YOUR_SCKEY",
|
||||
"title": "Server Notification",
|
||||
"desp": "{{key}}: {{value}}",
|
||||
"desp": "{{kvs}}",
|
||||
"body_regex": ".*",
|
||||
"code": 200
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
{
|
||||
"version": 1,
|
||||
"version": 2,
|
||||
// 时间间隔,用于推送
|
||||
// 有效格式: 1s 1m 1h
|
||||
// 默认: 30s
|
||||
// 小于 10s 的值将被忽略
|
||||
"interval": "30s",
|
||||
// 推送速率限制
|
||||
// 示例: 3/1m (每分钟三次), 1/10s (10秒一次)
|
||||
"rate": "1/10s",
|
||||
// 监测规则
|
||||
// 可用类型(type): cpu, mem, net, disk, temp (温度), swap
|
||||
//
|
||||
|
2
go.mod
2
go.mod
@ -4,7 +4,7 @@ go 1.20
|
||||
|
||||
require (
|
||||
github.com/labstack/echo/v4 v4.11.0
|
||||
github.com/lollipopkit/gommon v0.3.3
|
||||
github.com/lollipopkit/gommon v0.3.7
|
||||
github.com/urfave/cli/v2 v2.25.7
|
||||
)
|
||||
|
||||
|
4
go.sum
4
go.sum
@ -9,8 +9,8 @@ github.com/labstack/echo/v4 v4.11.0 h1:4Dmi59tmrnFzOchz4EXuGjJhUfcEkU28iDKsiZVOQ
|
||||
github.com/labstack/echo/v4 v4.11.0/go.mod h1:YuYRTSM3CHs2ybfrL8Px48bO6BAnYIN4l8wSTMP6BDQ=
|
||||
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
|
||||
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/lollipopkit/gommon v0.3.3 h1:LL6jvoyj0bNZUFgVBRNCyJ+aNR3AVRSxFwPtZHn+BQ0=
|
||||
github.com/lollipopkit/gommon v0.3.3/go.mod h1:DEnIxhHmPQjDSkKFDxwX6oFxMjlHd87G+Dt7U4ZUyRs=
|
||||
github.com/lollipopkit/gommon v0.3.7 h1:kROUlge2+/zp6jKzVNLVZ0jVoxqcx6mqhlPhPLlHMWo=
|
||||
github.com/lollipopkit/gommon v0.3.7/go.mod h1:DEnIxhHmPQjDSkKFDxwX6oFxMjlHd87G+Dt7U4ZUyRs=
|
||||
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
|
5
main.go
5
main.go
@ -1,9 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/lollipopkit/gommon/log"
|
||||
"github.com/lollipopkit/server_box_monitor/cmd"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cmd.Run()
|
||||
|
||||
log.Setup(log.Config{
|
||||
PrintTime: true,
|
||||
})
|
||||
}
|
||||
|
@ -3,15 +3,20 @@ package model
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/lollipopkit/gommon/log"
|
||||
"github.com/lollipopkit/gommon/util"
|
||||
os_ "github.com/lollipopkit/gommon/os"
|
||||
"github.com/lollipopkit/gommon/rate"
|
||||
"github.com/lollipopkit/server_box_monitor/res"
|
||||
)
|
||||
|
||||
var (
|
||||
Config = &AppConfig{}
|
||||
Config = new(AppConfig)
|
||||
CheckInterval time.Duration
|
||||
RateLimiter *rate.RateLimiter[string]
|
||||
)
|
||||
|
||||
type AppConfig struct {
|
||||
@ -20,12 +25,15 @@ type AppConfig struct {
|
||||
// Valid time units are "s".
|
||||
// Values bigger than 10 seconds are not allowed.
|
||||
Interval string `json:"interval"`
|
||||
Rate string `json:"rate"`
|
||||
Rules []Rule `json:"rules"`
|
||||
Pushes []Push `json:"pushes"`
|
||||
}
|
||||
|
||||
func ReadAppConfig() error {
|
||||
if !util.Exist(res.AppConfigPath) {
|
||||
defer initInterval()
|
||||
defer initRateLimiter()
|
||||
if !os_.Exist(res.AppConfigPath) {
|
||||
configBytes, err := json.MarshalIndent(DefaultappConfig, "", "\t")
|
||||
if err != nil {
|
||||
log.Err("[CONFIG] marshal default app config failed: %v", err)
|
||||
@ -54,25 +62,41 @@ func ReadAppConfig() error {
|
||||
return err
|
||||
}
|
||||
|
||||
func GetInterval() time.Duration {
|
||||
ac := DefaultappConfig
|
||||
if Config != nil {
|
||||
ac = Config
|
||||
}
|
||||
d, err := time.ParseDuration(ac.Interval)
|
||||
func initInterval() {
|
||||
d, err := time.ParseDuration(Config.Interval)
|
||||
if err == nil {
|
||||
if d > res.DefaultInterval {
|
||||
log.Warn("[CONFIG] interval is too long, use default interval")
|
||||
return res.DefaultInterval
|
||||
if d > res.MaxInterval || d < time.Second {
|
||||
log.Warn("[CONFIG] use default interval")
|
||||
CheckInterval = res.DefaultInterval
|
||||
return
|
||||
}
|
||||
return d
|
||||
CheckInterval = d
|
||||
return
|
||||
}
|
||||
log.Warn("[CONFIG] parse interval failed: %v", err)
|
||||
return res.DefaultInterval
|
||||
CheckInterval = res.DefaultInterval
|
||||
}
|
||||
|
||||
func GetIntervalInSeconds() float64 {
|
||||
return GetInterval().Seconds()
|
||||
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 (
|
||||
@ -116,8 +140,9 @@ var (
|
||||
defaultServerChanIfaceBytes, _ = json.Marshal(defaultServerChanIface)
|
||||
|
||||
DefaultappConfig = &AppConfig{
|
||||
Version: 1,
|
||||
Interval: "30s",
|
||||
Version: 2,
|
||||
Interval: "7s",
|
||||
Rate: "1/1m",
|
||||
Rules: []Rule{
|
||||
{
|
||||
MonitorType: MonitorTypeCPU,
|
||||
@ -136,16 +161,6 @@ var (
|
||||
Name: "QQ Group",
|
||||
Iface: defaultWebhookIfaceBytes,
|
||||
},
|
||||
{
|
||||
Type: PushTypeIOS,
|
||||
Name: "My iPhone",
|
||||
Iface: defaultIOSIfaceBytes,
|
||||
},
|
||||
{
|
||||
Type: PushTypeServerChan,
|
||||
Name: "ServerChan",
|
||||
Iface: defaultServerChanIfaceBytes,
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
@ -6,8 +6,9 @@ import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/lollipopkit/gommon/util"
|
||||
"github.com/lollipopkit/gommon/http"
|
||||
)
|
||||
|
||||
type Push struct {
|
||||
@ -54,19 +55,25 @@ func (p *Push) Push(args []*PushPair) error {
|
||||
// {{key}} {{value}}
|
||||
type PushFormat string
|
||||
type PushPair struct {
|
||||
Key string
|
||||
Value string
|
||||
key string
|
||||
value string
|
||||
time string
|
||||
}
|
||||
func NewPushPair(key, value string) *PushPair {
|
||||
return &PushPair{
|
||||
key: key,
|
||||
value: value,
|
||||
time: time.Now().Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
}
|
||||
|
||||
func (pf PushFormat) Format(args []*PushPair) string {
|
||||
ss := []string{}
|
||||
for _, arg := range args {
|
||||
s := string(pf)
|
||||
s = strings.ReplaceAll(s, "{{key}}", arg.Key)
|
||||
s = strings.ReplaceAll(s, "{{value}}", arg.Value)
|
||||
ss = append(ss, s)
|
||||
kv := fmt.Sprintf("%s\n%s: %s", arg.time, arg.key, arg.value)
|
||||
ss = append(ss, kv)
|
||||
}
|
||||
return strings.Join(ss, "\n")
|
||||
return strings.ReplaceAll(string(pf), "{{kvs}}", strings.Join(ss, "\n"))
|
||||
}
|
||||
|
||||
type PushType string
|
||||
@ -83,25 +90,24 @@ type PushIface interface {
|
||||
|
||||
type PushIfaceIOS struct {
|
||||
Token string `json:"token"`
|
||||
Title PushFormat `json:"title"`
|
||||
Title string `json:"title"`
|
||||
Content PushFormat `json:"content"`
|
||||
BodyRegex string `json:"body_regex"`
|
||||
Code int `json:"code"`
|
||||
}
|
||||
|
||||
func (p PushIfaceIOS) push(args []*PushPair) error {
|
||||
title := p.Title.Format(args)
|
||||
content := p.Content.Format(args)
|
||||
body := map[string]string{
|
||||
"token": p.Token,
|
||||
"title": title,
|
||||
"title": p.Title,
|
||||
"content": content,
|
||||
}
|
||||
bodyBytes, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp, code, err := util.HttpDo(
|
||||
resp, code, err := http.Do(
|
||||
"POST",
|
||||
"https://push.lolli.tech/v1/ios",
|
||||
bodyBytes,
|
||||
@ -137,9 +143,10 @@ type PushIfaceWebhook struct {
|
||||
|
||||
func (p PushIfaceWebhook) push(args []*PushPair) error {
|
||||
body := PushFormat(p.Body).Format(args)
|
||||
println(body)
|
||||
switch p.Method {
|
||||
case "GET", "POST":
|
||||
resp, code, err := util.HttpDo(p.Method, p.Url, body, p.Headers)
|
||||
resp, code, err := http.Do(p.Method, p.Url, body, p.Headers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -162,17 +169,16 @@ func (p PushIfaceWebhook) push(args []*PushPair) error {
|
||||
|
||||
type PushIfaceServerChan struct {
|
||||
SCKey string `json:"sckey"`
|
||||
Title PushFormat `json:"title"`
|
||||
Title string `json:"title"`
|
||||
Desp PushFormat `json:"desp"`
|
||||
BodyRegex string `json:"body_regex"`
|
||||
Code int `json:"code"`
|
||||
}
|
||||
|
||||
func (p PushIfaceServerChan) push(args []*PushPair) error {
|
||||
title := p.Title.Format(args)
|
||||
desp := p.Desp.Format(args)
|
||||
url := fmt.Sprintf("https://sctapi.ftqq.com/%s.send?title=%s&desp=%s", p.SCKey, title, desp)
|
||||
resp, code, err := util.HttpDo("GET", url, nil, nil)
|
||||
url := fmt.Sprintf("https://sctapi.ftqq.com/%s.send?title=%s&desp=%s", p.SCKey, p.Title, desp)
|
||||
resp, code, err := http.Do("GET", url, nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -96,10 +96,10 @@ func (r *Rule) shouldNotifyCPU(ss []oneCpuStatus, t *Threshold) (bool, *PushPair
|
||||
if idx > 0 {
|
||||
key = fmt.Sprintf("cpu%d", idx-1)
|
||||
}
|
||||
return ok, &PushPair{
|
||||
Key: key,
|
||||
Value: fmt.Sprintf("%.2f%%", usedPercent),
|
||||
}, nil
|
||||
return ok, NewPushPair(
|
||||
key,
|
||||
fmt.Sprintf("%.2f%%", usedPercent),
|
||||
), nil
|
||||
default:
|
||||
return false, nil, errors.Join(ErrInvalidRule, fmt.Errorf("invalid threshold type for cpu: %s", t.ThresholdType.Name()))
|
||||
}
|
||||
@ -131,19 +131,19 @@ func (r *Rule) shouldNotifyMemory(s *memStatus, t *Threshold) (bool, *PushPair,
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return ok, &PushPair{
|
||||
Key: r.Matcher + "of Memory",
|
||||
Value: size.String(),
|
||||
}, nil
|
||||
return ok, NewPushPair(
|
||||
"Mem " + r.Matcher,
|
||||
size.String(),
|
||||
), nil
|
||||
case ThresholdTypePercent:
|
||||
ok, err := t.True(percent)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return ok, &PushPair{
|
||||
Key: r.Matcher + "of Memory",
|
||||
Value: fmt.Sprintf("%.2f%%", percent*100),
|
||||
}, nil
|
||||
return ok, NewPushPair(
|
||||
"Mem " + r.Matcher,
|
||||
fmt.Sprintf("%.2f%%", percent*100),
|
||||
), nil
|
||||
default:
|
||||
return false, nil, errors.Join(ErrInvalidRule, fmt.Errorf("invalid threshold type for memory: %s", t.ThresholdType.Name()))
|
||||
}
|
||||
@ -172,19 +172,19 @@ func (r *Rule) shouldNotifySwap(s *swapStatus, t *Threshold) (bool, *PushPair, e
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return ok, &PushPair{
|
||||
Key: r.Matcher + "of Swap",
|
||||
Value: size.String(),
|
||||
}, nil
|
||||
return ok, NewPushPair(
|
||||
"Swap " + r.Matcher,
|
||||
size.String(),
|
||||
), nil
|
||||
case ThresholdTypePercent:
|
||||
ok, err := t.True(percent)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return ok, &PushPair{
|
||||
Key: r.Matcher + "of Swap",
|
||||
Value: fmt.Sprintf("%.2f%%", percent*100),
|
||||
}, nil
|
||||
return ok, NewPushPair(
|
||||
"Swap " + r.Matcher,
|
||||
fmt.Sprintf("%.2f%%", percent*100),
|
||||
), nil
|
||||
default:
|
||||
return false, nil, errors.Join(ErrInvalidRule, fmt.Errorf("invalid threshold type for swap: %s", t.ThresholdType.Name()))
|
||||
}
|
||||
@ -213,19 +213,19 @@ func (r *Rule) shouldNotifyDisk(s []diskStatus, t *Threshold) (bool, *PushPair,
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return ok, &PushPair{
|
||||
Key: r.Matcher,
|
||||
Value: disk.Used.String(),
|
||||
}, nil
|
||||
return ok, NewPushPair(
|
||||
r.Matcher,
|
||||
disk.Used.String(),
|
||||
), nil
|
||||
case ThresholdTypePercent:
|
||||
ok, err := t.True(disk.UsedPercent)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return ok, &PushPair{
|
||||
Key: r.Matcher,
|
||||
Value: fmt.Sprintf("%.2f%%", disk.UsedPercent),
|
||||
}, nil
|
||||
return ok, NewPushPair(
|
||||
r.Matcher,
|
||||
fmt.Sprintf("%.2f%%", disk.UsedPercent),
|
||||
), nil
|
||||
default:
|
||||
return false, nil, errors.Join(ErrInvalidRule, fmt.Errorf("invalid threshold type for disk: %s", t.ThresholdType.Name()))
|
||||
}
|
||||
@ -278,10 +278,10 @@ func (r *Rule) shouldNotifyNetwork(s []networkStatus, t *Threshold) (bool, *Push
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return ok, &PushPair{
|
||||
Key: r.Matcher,
|
||||
Value: speed.String()+"/s",
|
||||
}, nil
|
||||
return ok, NewPushPair(
|
||||
r.Matcher,
|
||||
speed.String() + "/s",
|
||||
), nil
|
||||
case ThresholdTypeSize:
|
||||
size := Size(0)
|
||||
if in {
|
||||
@ -294,10 +294,10 @@ func (r *Rule) shouldNotifyNetwork(s []networkStatus, t *Threshold) (bool, *Push
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return ok, &PushPair{
|
||||
Key: r.Matcher,
|
||||
Value: size.String(),
|
||||
}, nil
|
||||
return ok, NewPushPair(
|
||||
r.Matcher,
|
||||
size.String(),
|
||||
), nil
|
||||
default:
|
||||
return false, nil, errors.Join(ErrInvalidRule, fmt.Errorf("invalid threshold type for network: %s", t.ThresholdType.Name()))
|
||||
}
|
||||
@ -328,10 +328,10 @@ func (r *Rule) shouldNotifyTemperature(s []temperatureStatus, t *Threshold) (boo
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return ok, &PushPair{
|
||||
Key: r.Matcher,
|
||||
Value: fmt.Sprintf("%.2f°C", temp.Value),
|
||||
}, nil
|
||||
return ok, NewPushPair(
|
||||
r.Matcher,
|
||||
fmt.Sprintf("%.2f°C", temp.Value),
|
||||
), nil
|
||||
default:
|
||||
return false, nil, errors.Join(ErrInvalidRule, fmt.Errorf("invalid threshold type for temperature: %s", t.ThresholdType.Name()))
|
||||
}
|
||||
|
@ -21,4 +21,4 @@ func _parseSize(s string, expect model.Size, t *testing.T) {
|
||||
if size != expect {
|
||||
t.Errorf("expect %s, got %s", expect, size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/lollipopkit/gommon/log"
|
||||
"github.com/lollipopkit/gommon/util"
|
||||
os_ "github.com/lollipopkit/gommon/os"
|
||||
"github.com/lollipopkit/server_box_monitor/res"
|
||||
)
|
||||
|
||||
@ -96,14 +96,14 @@ func (ns *networkStatus) TransmitSpeed() (Size, error) {
|
||||
return 0, ErrNotReady
|
||||
}
|
||||
diff := float64(ns.TimeSequence.New.Transmit - ns.TimeSequence.Old.Transmit)
|
||||
return Size(diff / GetIntervalInSeconds()), nil
|
||||
return Size(diff / CheckInterval.Seconds()), nil
|
||||
}
|
||||
func (ns *networkStatus) ReceiveSpeed() (Size, error) {
|
||||
if ns.TimeSequence.New == nil || ns.TimeSequence.Old == nil {
|
||||
return 0, ErrNotReady
|
||||
}
|
||||
diff := float64(ns.TimeSequence.New.Receive - ns.TimeSequence.Old.Receive)
|
||||
return Size(diff / GetIntervalInSeconds()), nil
|
||||
return Size(diff / CheckInterval.Seconds()), nil
|
||||
}
|
||||
|
||||
type AllNetworkStatus []networkStatus
|
||||
@ -132,7 +132,7 @@ func (nss AllNetworkStatus) ReceiveSpeed() (Size, error) {
|
||||
}
|
||||
|
||||
func RefreshStatus() error {
|
||||
output, _ := util.Execute("bash", res.ServerBoxShellPath)
|
||||
output, _ := os_.Execute("bash", res.ServerBoxShellPath)
|
||||
err := os.WriteFile(filepath.Join(res.ServerBoxDirPath, "shell_output.log"), []byte(output), 0644)
|
||||
if err != nil {
|
||||
log.Warn("[STATUS] write shell output log failed: %s", err)
|
||||
|
@ -84,7 +84,7 @@ func ParseToThreshold(s string) (*Threshold, error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return &Threshold{
|
||||
ThresholdType: thresholdType,
|
||||
Value: value,
|
||||
|
@ -7,7 +7,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/lollipopkit/gommon/log"
|
||||
"github.com/lollipopkit/gommon/util"
|
||||
os_ "github.com/lollipopkit/gommon/os"
|
||||
"github.com/lollipopkit/gommon/rate"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -27,14 +28,17 @@ var (
|
||||
|
||||
AppConfigFileName = "config.json"
|
||||
AppConfigPath = filepath.Join(ServerBoxDirPath, AppConfigFileName)
|
||||
|
||||
DefaultRateLimiter = rate.NewLimiter[string](time.Second * 10, 1)
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultInterval = time.Second * 7
|
||||
MaxInterval = time.Second * 10
|
||||
)
|
||||
|
||||
func init() {
|
||||
if !util.Exist(ServerBoxDirPath) {
|
||||
if !os_.Exist(ServerBoxDirPath) {
|
||||
err := os.MkdirAll(ServerBoxDirPath, 0755)
|
||||
if err != nil {
|
||||
log.Err("[INIT] Create dir error: %v", err)
|
||||
|
@ -46,7 +46,7 @@ func runCheck() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for range time.NewTicker(model.GetInterval()).C {
|
||||
for range time.NewTicker(model.CheckInterval).C {
|
||||
err = model.RefreshStatus()
|
||||
status := model.Status
|
||||
if err != nil {
|
||||
@ -77,11 +77,17 @@ func runCheck() {
|
||||
|
||||
pushPairsLock.RLock()
|
||||
for _, push := range model.Config.Pushes {
|
||||
if !model.RateLimiter.Check(push.Name) {
|
||||
log.Warn("[PUSH] %s rate limit reached", push.Name)
|
||||
continue
|
||||
}
|
||||
err := push.Push(pushPairs)
|
||||
if err != nil {
|
||||
log.Warn("[PUSH] %s error: %v", push.Name, err)
|
||||
continue
|
||||
}
|
||||
// 仅推送成功才计数
|
||||
model.RateLimiter.Acquire(push.Name)
|
||||
log.Suc("[PUSH] %s success", push.Name)
|
||||
}
|
||||
pushPairsLock.RUnlock()
|
||||
@ -104,5 +110,5 @@ func runWeb() {
|
||||
|
||||
e.GET("/status", web.Status)
|
||||
|
||||
e.Logger.Fatal(e.Start(":3770"))
|
||||
e.Logger.Fatal(e.Start("0.0.0.0:3770"))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user