feat(monitor): 自 go-hua 迁入系统资源监控
- Start 后台每秒采集(CPU/内存/磁盘/网络/进程/连接/主机), GetInfo 取快照 - 基于 gopsutil, 附测试、examples/monitor 例程与包 README
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
// 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))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user