65 lines
1.4 KiB
Go
65 lines
1.4 KiB
Go
package main
|
||
|
||
import (
|
||
"bufio"
|
||
"os"
|
||
"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"]
|
||
|
||
// 优先使用 MemAvailable(Linux 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
|
||
}
|
||
return MemoryMetrics{
|
||
TotalBytes: total,
|
||
UsedBytes: used,
|
||
FreeBytes: free,
|
||
UsedPercent: round(usedPercent, 2),
|
||
}, nil
|
||
}
|