chore: sync local updates

This commit is contained in:
2026-05-16 19:03:34 +08:00
parent 9c086c3301
commit 80cf54a201
89 changed files with 10622 additions and 2443 deletions

View File

@@ -0,0 +1,127 @@
package main
import (
"bufio"
"os"
"sort"
"strconv"
"strings"
)
// readMemory 读取内存信息
func readMemory() (MemoryMetrics, error) {
totals := map[string]uint64{}
f, err := os.Open("/proc/meminfo")
if err != nil {
return MemoryMetrics{}, err
}
defer f.Close()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
parts := strings.Split(line, ":")
if len(parts) < 2 {
continue
}
key := strings.TrimSpace(parts[0])
fields := strings.Fields(strings.TrimSpace(parts[1]))
if len(fields) == 0 {
continue
}
value, err := strconv.ParseUint(fields[0], 10, 64)
if err != nil {
continue
}
totals[key] = value * 1024 // kB to bytes
}
total := totals["MemTotal"]
// 优先使用 MemAvailableLinux 3.14+),如果没有则计算
var free uint64
if available, ok := totals["MemAvailable"]; ok && available > 0 {
free = available
} else {
// 回退到 MemFree + Buffers + Cached适用于较老的系统
free = totals["MemFree"]
if buffers, ok := totals["Buffers"]; ok {
free += buffers
}
if cached, ok := totals["Cached"]; ok {
free += cached
}
}
used := total - free
usedPercent := 0.0
if total > 0 {
usedPercent = (float64(used) / float64(total)) * 100
}
swapTotal := totals["SwapTotal"]
swapFree := totals["SwapFree"]
swapUsed := uint64(0)
if swapTotal >= swapFree {
swapUsed = swapTotal - swapFree
}
swapUsedPct := 0.0
if swapTotal > 0 {
swapUsedPct = (float64(swapUsed) / float64(swapTotal)) * 100
}
swapType := summarizeSwapTypes(swapTotal)
return MemoryMetrics{
TotalBytes: total,
UsedBytes: used,
FreeBytes: free,
UsedPercent: round(usedPercent, 2),
SwapTotalBytes: swapTotal,
SwapUsedBytes: swapUsed,
SwapFreeBytes: swapFree,
SwapUsedPercent: round(swapUsedPct, 2),
SwapType: swapType,
}, nil
}
// summarizeSwapTypes 根据 /proc/swaps 汇总交换区类型file / partition / zram 等);无 swap 时为「无」
func summarizeSwapTypes(swapTotalFromMeminfo uint64) string {
if swapTotalFromMeminfo == 0 {
return "无"
}
f, err := os.Open("/proc/swaps")
if err != nil {
return "未知"
}
defer f.Close()
scanner := bufio.NewScanner(f)
lineNum := 0
seen := map[string]struct{}{}
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
lineNum++
if lineNum == 1 || line == "" {
continue
}
fields := strings.Fields(line)
if len(fields) < 2 {
continue
}
filename := fields[0]
typ := fields[1]
if strings.Contains(strings.ToLower(filename), "zram") {
typ = "zram"
}
seen[typ] = struct{}{}
}
if len(seen) == 0 {
if swapTotalFromMeminfo > 0 {
return "未知"
}
return "无"
}
list := make([]string, 0, len(seen))
for t := range seen {
list = append(list, t)
}
sort.Strings(list)
return strings.Join(list, " + ")
}