-
Notifications
You must be signed in to change notification settings - Fork 49
/
memorycheck.go
104 lines (90 loc) · 2.69 KB
/
memorycheck.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package main
import (
"bytes"
"fmt"
"log"
"os/exec"
"runtime"
"strconv"
"strings"
"time"
"github.com/hoshinonyaruko/palworld-go/config"
)
type MemoryCheckTask struct {
Config config.Config
Ticker *time.Ticker
BackupTask *BackupTask
}
func NewMemoryCheckTask(config config.Config, BackupTask *BackupTask) *MemoryCheckTask {
var ticker *time.Ticker
if config.MemoryCheckInterval > 0 {
ticker = time.NewTicker(time.Duration(config.MemoryCheckInterval) * time.Second)
}
return &MemoryCheckTask{
Config: config,
Ticker: ticker,
BackupTask: BackupTask,
}
}
func (task *MemoryCheckTask) Schedule() {
if task.Ticker == nil {
// 如果 Ticker 为 nil,不需要进行定时检查
return
}
for range task.Ticker.C {
task.checkMemory()
}
}
func (task *MemoryCheckTask) checkMemory() {
var cmd *exec.Cmd
threshold := task.Config.MemoryUsageThreshold
if runtime.GOOS == "windows" {
cmd = exec.Command("wmic", "OS", "get", "FreePhysicalMemory", "/Value")
} else {
cmd = exec.Command("sh", "-c", "free | awk 'NR==2{print $3/$2 * 100.0}'")
}
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
log.Printf("Failed to execute memory check command: %v", err)
return
}
memoryUsage, err := task.parseMemoryUsage(out.String(), runtime.GOOS)
if err != nil {
log.Printf("Failed to parse memory usage: %v", err)
return
}
log.Printf("Now Memory usage is %v%%.", memoryUsage)
if memoryUsage > threshold {
log.Printf("Memory usage is above %v%%. Running clean command.", threshold)
// 初始化RCON客户端
address := task.Config.Address + ":" + strconv.Itoa(task.Config.WorldSettings.RconPort)
rconClient := NewRconClient(address, task.Config.WorldSettings.AdminPassword, task.BackupTask, &task.Config)
if rconClient == nil {
log.Println("RCON客户端初始化失败,无法处理内存使用情况,请按教程正确开启rcon和设置服务端admin密码")
return
}
HandleMemoryUsage(threshold, rconClient, task.Config)
defer rconClient.Close()
} else {
log.Printf("Memory usage is below %v%%. No action required.", threshold)
}
}
func (task *MemoryCheckTask) parseMemoryUsage(output, os string) (float64, error) {
if os == "windows" {
lines := strings.Fields(output)
if len(lines) < 1 {
return 0, fmt.Errorf("unexpected output format")
}
freeMemoryKB, err := strconv.ParseFloat(strings.TrimPrefix(lines[0], "FreePhysicalMemory="), 64)
if err != nil {
return 0, err
}
log.Printf("now FreePhysicalMemoryKB: %v", freeMemoryKB)
totalMemoryKB := task.Config.TotalMemoryGB * 1024 * 1024
return 100.0 * (1 - freeMemoryKB/float64(totalMemoryKB)), nil
} else {
return strconv.ParseFloat(strings.TrimSpace(output), 64)
}
}