feat(monitor): 自 go-hua 迁入系统资源监控

- Start 后台每秒采集(CPU/内存/磁盘/网络/进程/连接/主机), GetInfo 取快照
- 基于 gopsutil, 附测试、examples/monitor 例程与包 README
This commit is contained in:
2026-09-20 12:29:37 +08:00
parent 138c929bd4
commit 30a0889ffa
11 changed files with 963 additions and 0 deletions
+117
View File
@@ -0,0 +1,117 @@
package monitor
import (
"fmt"
"github.com/shirou/gopsutil/v3/disk"
"path/filepath"
"runtime"
"strconv"
)
// DiskInfo 磁盘分区信息(空间占用 + IO 统计)
type DiskInfo struct {
Device string `json:"device"`
MountPoint string `json:"mountPoint"`
FsType string `json:"fsType"`
Path string `json:"path"`
Total uint64 `json:"total"`
Free uint64 `json:"free"`
Used uint64 `json:"used"`
UsedPercent float64 `json:"usedPercent"`
UsedVolume string `json:"usedVolume"`
ReadCount uint64 `json:"readCount"`
WriteCount uint64 `json:"writeCount"`
ReadBytes uint64 `json:"readBytes"`
WriteBytes uint64 `json:"writeBytes"`
ReadTime uint64 `json:"readTime"`
WriteTime uint64 `json:"writeTime"`
TotalReadCount uint64 `json:"totalReadCount"`
TotalWriteCount uint64 `json:"totalWriteCount"`
TotalReadBytes uint64 `json:"totalReadBytes"`
TotalWriteBytes uint64 `json:"totalWriteBytes"`
TotalReadTime uint64 `json:"totalReadTime"`
TotalWriteTime uint64 `json:"totalWriteTime"`
}
// DiskInfoLite 精简版磁盘信息
type DiskInfoLite struct {
Device string `json:"device"`
MountPoint string `json:"mountPoint"`
UsedPercent float64 `json:"usedPercent"`
UsedVolume string `json:"usedVolume"`
ReadBytes uint64 `json:"readBytes"`
WriteBytes uint64 `json:"writeBytes"`
}
// getDiskInfo 采集所有磁盘分区信息
func getDiskInfo() ([]DiskInfo, error) {
partitions, err := disk.Partitions(false)
// fmt.Printf("disk partitions:%v\n\n", partitions)
if err != nil {
// fmt.Printf("get disk partitions err:%s\n", err.Error())
// return nil, err
}
names := make([]string, len(partitions))
// fmt.Println(len(names))
for i, _ := range partitions {
names[i] = partitions[i].Device
}
// fmt.Println(names)
io, err := disk.IOCounters(names...)
// fmt.Printf("disk io:%v\n\n", io)
if err != nil {
//return nil, err
// fmt.Printf("get disk IOCounters err:%s\n", err.Error())
}
disks := make([]DiskInfo, len(partitions))
for i, _ := range disks {
disks[i].Device = partitions[i].Device
disks[i].MountPoint = partitions[i].Mountpoint
disks[i].FsType = partitions[i].Fstype
// 使用量 用路径获取
usage, err := disk.Usage(partitions[i].Mountpoint)
if err != nil {
// fmt.Printf("get disk Usage err:%s\n", err.Error())
break
}
disks[i].Path = usage.Path
disks[i].Total = usage.Total
disks[i].Free = usage.Total
disks[i].Used = usage.Used
disks[i].UsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", usage.UsedPercent), 64)
disks[i].UsedVolume = formatFileSize(usage.Used) + "/" + formatFileSize(usage.Total)
name := partitions[i].Device
if runtime.GOOS == "linux" {
name = filepath.Base(name)
}
//fmt.Println(name, partitions[i].Device)
disks[i].TotalReadCount = io[name].ReadCount
disks[i].TotalWriteCount = io[name].WriteCount
disks[i].TotalReadBytes = io[name].ReadBytes
disks[i].TotalWriteBytes = io[name].WriteBytes
disks[i].TotalReadTime = io[name].ReadTime
disks[i].TotalWriteTime = io[name].WriteTime
// FIXME:分区会变化,应该用name获取
if len(monInfo.Disk) > i {
disks[i].ReadCount = io[name].ReadCount - monInfo.Disk[i].TotalReadCount
disks[i].WriteCount = io[name].WriteCount - monInfo.Disk[i].TotalWriteCount
disks[i].ReadBytes = io[name].ReadBytes - monInfo.Disk[i].TotalReadBytes
disks[i].WriteBytes = io[name].WriteBytes - monInfo.Disk[i].TotalWriteBytes
disks[i].ReadTime = io[name].ReadTime - monInfo.Disk[i].TotalReadTime
disks[i].WriteTime = io[name].WriteTime - monInfo.Disk[i].TotalWriteTime
}
}
if err != nil {
return disks, err
}
return disks, nil
}