Files
mengyamonitor/mengyamonitor-backend/systeminfo_linux.go
2025-12-14 15:25:31 +08:00

114 lines
2.4 KiB
Go

//go:build linux
// +build linux
package main
import (
"bufio"
"os"
"strings"
"syscall"
)
func readStorage() ([]StorageMetrics, error) {
// For simplicity, report root mount. Can be extended to iterate mounts.
var stat syscall.Statfs_t
if err := syscall.Statfs("/", &stat); err != nil {
return nil, err
}
total := stat.Blocks * uint64(stat.Bsize)
free := stat.Bfree * uint64(stat.Bsize)
used := total - free
usedPercent := 0.0
if total > 0 {
usedPercent = (float64(used) / float64(total)) * 100
}
return []StorageMetrics{{
Mount: "/",
TotalBytes: total,
UsedBytes: used,
FreeBytes: free,
UsedPercent: round(usedPercent, 2),
}}, nil
}
// readAllStorage 读取所有挂载的存储设备
func readAllStorage() ([]StorageMetrics, error) {
storages := []StorageMetrics{}
// 读取 /proc/mounts 获取所有挂载点
f, err := os.Open("/proc/mounts")
if err != nil {
return readStorage() // 降级到只读根目录
}
defer f.Close()
scanner := bufio.NewScanner(f)
seen := make(map[string]bool)
for scanner.Scan() {
line := scanner.Text()
fields := strings.Fields(line)
if len(fields) < 3 {
continue
}
device := fields[0]
mountPoint := fields[1]
fsType := fields[2]
// 跳过虚拟文件系统
if strings.HasPrefix(device, "/dev/") == false {
continue
}
// 跳过特殊文件系统类型
skipTypes := map[string]bool{
"tmpfs": true, "devtmpfs": true, "squashfs": true,
"overlay": true, "aufs": true, "proc": true,
"sysfs": true, "devpts": true, "cgroup": true,
}
if skipTypes[fsType] {
continue
}
// 避免重复挂载点
if seen[mountPoint] {
continue
}
seen[mountPoint] = true
// 获取该挂载点的统计信息
var stat syscall.Statfs_t
if err := syscall.Statfs(mountPoint, &stat); err != nil {
continue
}
total := stat.Blocks * uint64(stat.Bsize)
free := stat.Bfree * uint64(stat.Bsize)
used := total - free
usedPercent := 0.0
if total > 0 {
usedPercent = (float64(used) / float64(total)) * 100
}
// 只添加有容量的存储
if total > 0 {
storages = append(storages, StorageMetrics{
Mount: mountPoint,
TotalBytes: total,
UsedBytes: used,
FreeBytes: free,
UsedPercent: round(usedPercent, 2),
})
}
}
// 如果没有找到任何存储,至少返回根目录
if len(storages) == 0 {
return readStorage()
}
return storages, nil
}