Files
zogo/monitor/monitor.go
T
4566704 30a0889ffa feat(monitor): 自 go-hua 迁入系统资源监控
- Start 后台每秒采集(CPU/内存/磁盘/网络/进程/连接/主机), GetInfo 取快照
- 基于 gopsutil, 附测试、examples/monitor 例程与包 README
2026-09-20 12:29:37 +08:00

173 lines
4.6 KiB
Go

// Package monitor 提供系统资源监控(CPU/内存/磁盘/网络/进程/连接/主机),后台定时采集,GetInfo 随时取最新快照。
package monitor
import (
"fmt"
"sync"
"time"
)
// MonInfo 全量监控信息快照
type MonInfo struct {
Host HostInfo `json:"host"`
Cpu CpuInfo `json:"cpu"`
Mem MemInfo `json:"mem"`
Load LoadInfo `json:"load"`
Process []ProcessInfo `json:"process"`
Disk []DiskInfo `json:"disk"`
Net []NetInfo `json:"net"`
Conn NetConnInfo `json:"conn"`
Ver string `json:"ver"`
}
// MonInfoSimple 精简版监控信息(适合定时上报)
type MonInfoSimple struct {
Host HostInfo `json:"host"`
Cpu CpuInfoLite `json:"cpu"`
Mem MemInfo `json:"mem"`
Load LoadInfo `json:"load"`
Conn NetConnInfo `json:"conn"`
Net NetInfoLite `json:"net"`
Disk []DiskInfoLite `json:"disk"`
Ver string `json:"ver"`
}
var (
interval int = 1
monInfo MonInfo
mux sync.Mutex
one sync.Once
)
// Start 启动后台采集
// 普通信息每秒刷新,主机/连接信息每 5 秒刷新一次;ver 为程序版本号
func Start(ver string) {
monInfo.Ver = ver
one.Do(proc)
}
// GetInfo 获取最新的监控信息快照
func GetInfo() MonInfo {
mux.Lock()
info := monInfo
mux.Unlock()
return info
}
// proc 监控采集主循环
func proc() {
go func() {
var i uint64 = 0
// CPU信息应该不会变,CPU热插拨除外
{
cpuBaseVal, _ := getCpuInfo()
monInfo.Cpu.Core = cpuBaseVal.Core
monInfo.Cpu.Logic = cpuBaseVal.Logic
monInfo.Cpu.Info = cpuBaseVal.Info
monInfo.Cpu.Core = cpuBaseVal.Core
}
// 循环获取信息
for {
i = i + uint64(interval)
//每次都获取
diskVal, err := getDiskInfo()
if err != nil {
fmt.Println("获取硬盘信出错:", err.Error())
}
cpuUsedVal, _ := getCpuUsed()
memVal, _ := getMemInfo()
netVal, _ := getNetInfo()
loadVal, _ := getLoadInfo()
process, _ := GetProcessInfo()
mux.Lock()
//只获取CPU使用率,CPU基本信息一般不会发生改变
monInfo.Cpu.UsedPercent = cpuUsedVal.UsedPercent
monInfo.Cpu.Used = cpuUsedVal.Used
monInfo.Load = loadVal
monInfo.Disk = diskVal
monInfo.Mem = memVal
monInfo.Net = netVal
monInfo.Process = process
mux.Unlock()
// 间隔5次调用一次 // 建议60秒获取一次,例如更改计算机名,导致获取不准确
if i%5 == 0 {
hostVal, _ := getHostInfo()
connVal, _ := getNetConnInfo()
mux.Lock()
monInfo.Host = hostVal
monInfo.Conn = connVal
mux.Unlock()
}
time.Sleep(time.Second * time.Duration(interval))
}
}()
}
// ToLiteInfo 将全量信息转换为精简版
func ToLiteInfo(info MonInfo) MonInfoSimple {
lite := MonInfoSimple{}
lite.Host = info.Host
lite.Load = info.Load
lite.Mem = info.Mem
lite.Conn = info.Conn
lite.Cpu.Core = info.Cpu.Core
lite.Cpu.Logic = info.Cpu.Logic
lite.Cpu.UsedPercent = info.Cpu.UsedPercent
lite.Cpu.Logic = info.Cpu.Logic
lite.Cpu.Name = make([]string, len(info.Cpu.Info))
for index, c := range info.Cpu.Info {
lite.Cpu.Name[index] = c.ModelName
}
lite.Disk = make([]DiskInfoLite, len(info.Disk))
for index, d := range info.Disk {
lite.Disk[index].Device = d.Device
lite.Disk[index].MountPoint = d.MountPoint
lite.Disk[index].UsedPercent = d.UsedPercent
lite.Disk[index].UsedVolume = d.UsedVolume
lite.Disk[index].ReadBytes = d.ReadBytes
lite.Disk[index].WriteBytes = d.WriteBytes
}
lite.Net = NetInfoLite{}
for _, n := range info.Net {
lite.Net.BytesSent += n.BytesSent
lite.Net.BytesRecv += n.BytesRecv
lite.Net.PacketsSent += n.PacketsSent
lite.Net.PacketsRecv += n.PacketsRecv
lite.Net.TotalBytesSent += n.TotalBytesSent
lite.Net.TotalBytesRecv += n.TotalBytesRecv
}
lite.Ver = info.Ver
return lite
}
// 字节的单位转换 保留两位小数
func formatFileSize(fileSize uint64) (size string) {
if fileSize < 1024 {
//return strconv.FormatInt(fileSize, 10) + "B"
return fmt.Sprintf("%.2fB", float64(fileSize)/float64(1))
} else if fileSize < (1024 * 1024) {
return fmt.Sprintf("%.2fKB", float64(fileSize)/float64(1024))
} else if fileSize < (1024 * 1024 * 1024) {
return fmt.Sprintf("%.2fMB", float64(fileSize)/float64(1024*1024))
} else if fileSize < (1024 * 1024 * 1024 * 1024) {
return fmt.Sprintf("%.2fGB", float64(fileSize)/float64(1024*1024*1024))
} else if fileSize < (1024 * 1024 * 1024 * 1024 * 1024) {
return fmt.Sprintf("%.2fTB", float64(fileSize)/float64(1024*1024*1024*1024))
} else { //if fileSize < (1024 * 1024 * 1024 * 1024 * 1024 * 1024)
return fmt.Sprintf("%.2fEB", float64(fileSize)/float64(1024*1024*1024*1024*1024))
}
}