378 lines
5.2 KiB
Go
378 lines
5.2 KiB
Go
|
package service
|
|||
|
|
|||
|
import (
|
|||
|
"licserver/internal/model"
|
|||
|
|
|||
|
"runtime"
|
|||
|
|
|||
|
"time"
|
|||
|
|
|||
|
"github.com/shirou/gopsutil/v3/cpu"
|
|||
|
|
|||
|
"github.com/shirou/gopsutil/v3/disk"
|
|||
|
|
|||
|
"github.com/shirou/gopsutil/v3/host"
|
|||
|
|
|||
|
"github.com/shirou/gopsutil/v3/mem"
|
|||
|
|
|||
|
"github.com/shirou/gopsutil/v3/net"
|
|||
|
|
|||
|
"github.com/shirou/gopsutil/v3/process"
|
|||
|
|
|||
|
"gorm.io/gorm"
|
|||
|
)
|
|||
|
|
|||
|
type MonitorService struct {
|
|||
|
db *gorm.DB
|
|||
|
|
|||
|
startTime time.Time
|
|||
|
}
|
|||
|
|
|||
|
func NewMonitorService(db *gorm.DB) *MonitorService {
|
|||
|
|
|||
|
return &MonitorService{
|
|||
|
|
|||
|
db: db,
|
|||
|
|
|||
|
startTime: time.Now(),
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
func (s *MonitorService) GetSystemStatus() (*model.SystemStatus, error) {
|
|||
|
|
|||
|
status := &model.SystemStatus{}
|
|||
|
|
|||
|
// CPU信息
|
|||
|
|
|||
|
if err := s.getCPUInfo(status); err != nil {
|
|||
|
|
|||
|
return nil, err
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
// 内存信息
|
|||
|
|
|||
|
if err := s.getMemoryInfo(status); err != nil {
|
|||
|
|
|||
|
return nil, err
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
// 磁盘信息
|
|||
|
|
|||
|
if err := s.getDiskInfo(status); err != nil {
|
|||
|
|
|||
|
return nil, err
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
// 网络信息
|
|||
|
|
|||
|
if err := s.getNetworkInfo(status); err != nil {
|
|||
|
|
|||
|
return nil, err
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
// 进程信息
|
|||
|
|
|||
|
if err := s.getProcessInfo(status); err != nil {
|
|||
|
|
|||
|
return nil, err
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
// 主机信息
|
|||
|
|
|||
|
if err := s.getHostInfo(status); err != nil {
|
|||
|
|
|||
|
return nil, err
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
// 系统信息
|
|||
|
|
|||
|
s.getSystemInfo(status)
|
|||
|
|
|||
|
return status, nil
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
func (s *MonitorService) getCPUInfo(status *model.SystemStatus) error {
|
|||
|
|
|||
|
cpuPercent, err := cpu.Percent(time.Second, false)
|
|||
|
|
|||
|
if err != nil {
|
|||
|
|
|||
|
return err
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
// Windows 系统不支持 LoadAvg,设置为默认值
|
|||
|
|
|||
|
status.CPU.LoadAvg = []float64{0, 0, 0}
|
|||
|
|
|||
|
cpuInfo, err := cpu.Info()
|
|||
|
|
|||
|
if err != nil {
|
|||
|
|
|||
|
return err
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
status.CPU.Usage = cpuPercent[0]
|
|||
|
|
|||
|
status.CPU.CoreCount = runtime.NumCPU()
|
|||
|
|
|||
|
if len(cpuInfo) > 0 {
|
|||
|
|
|||
|
status.CPU.ModelName = cpuInfo[0].ModelName
|
|||
|
|
|||
|
status.CPU.MHz = cpuInfo[0].Mhz
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return nil
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
func (s *MonitorService) getMemoryInfo(status *model.SystemStatus) error {
|
|||
|
|
|||
|
memInfo, err := mem.VirtualMemory()
|
|||
|
|
|||
|
if err != nil {
|
|||
|
|
|||
|
return err
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
swapInfo, err := mem.SwapMemory()
|
|||
|
|
|||
|
if err != nil {
|
|||
|
|
|||
|
return err
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
status.Memory.Total = memInfo.Total
|
|||
|
|
|||
|
status.Memory.Used = memInfo.Used
|
|||
|
|
|||
|
status.Memory.Free = memInfo.Free
|
|||
|
|
|||
|
status.Memory.UsageRate = memInfo.UsedPercent
|
|||
|
|
|||
|
status.Memory.SwapTotal = swapInfo.Total
|
|||
|
|
|||
|
status.Memory.SwapUsed = swapInfo.Used
|
|||
|
|
|||
|
status.Memory.SwapFree = swapInfo.Free
|
|||
|
|
|||
|
status.Memory.SwapUsageRate = swapInfo.UsedPercent
|
|||
|
|
|||
|
return nil
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
func (s *MonitorService) getDiskInfo(status *model.SystemStatus) error {
|
|||
|
|
|||
|
partitions, err := disk.Partitions(true)
|
|||
|
|
|||
|
if err != nil {
|
|||
|
|
|||
|
return err
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
status.Disk.Partitions = make([]model.DiskPartition, 0)
|
|||
|
|
|||
|
for _, partition := range partitions {
|
|||
|
|
|||
|
usage, err := disk.Usage(partition.Mountpoint)
|
|||
|
|
|||
|
if err != nil {
|
|||
|
|
|||
|
continue
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
status.Disk.Partitions = append(status.Disk.Partitions, model.DiskPartition{
|
|||
|
|
|||
|
Device: partition.Device,
|
|||
|
|
|||
|
Mountpoint: partition.Mountpoint,
|
|||
|
|
|||
|
Fstype: partition.Fstype,
|
|||
|
|
|||
|
Total: usage.Total,
|
|||
|
|
|||
|
Used: usage.Used,
|
|||
|
|
|||
|
Free: usage.Free,
|
|||
|
|
|||
|
UsageRate: usage.UsedPercent,
|
|||
|
})
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return nil
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
func (s *MonitorService) getNetworkInfo(status *model.SystemStatus) error {
|
|||
|
|
|||
|
interfaces, err := net.Interfaces()
|
|||
|
|
|||
|
if err != nil {
|
|||
|
|
|||
|
return err
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
ioCounters, err := net.IOCounters(true)
|
|||
|
|
|||
|
if err != nil {
|
|||
|
|
|||
|
return err
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
status.Network.Interfaces = make([]model.NetworkInterface, 0)
|
|||
|
|
|||
|
for _, iface := range interfaces {
|
|||
|
|
|||
|
var counter net.IOCountersStat
|
|||
|
|
|||
|
for _, io := range ioCounters {
|
|||
|
|
|||
|
if io.Name == iface.Name {
|
|||
|
|
|||
|
counter = io
|
|||
|
|
|||
|
break
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
// 获取接口的地址列表
|
|||
|
|
|||
|
addrs := make([]string, 0)
|
|||
|
|
|||
|
for _, addr := range iface.Addrs {
|
|||
|
addrs = append(addrs, addr.String())
|
|||
|
}
|
|||
|
|
|||
|
status.Network.Interfaces = append(status.Network.Interfaces, model.NetworkInterface{
|
|||
|
|
|||
|
Name: iface.Name,
|
|||
|
|
|||
|
BytesSent: counter.BytesSent,
|
|||
|
|
|||
|
BytesRecv: counter.BytesRecv,
|
|||
|
|
|||
|
PacketsSent: counter.PacketsSent,
|
|||
|
|
|||
|
PacketsRecv: counter.PacketsRecv,
|
|||
|
|
|||
|
Addrs: addrs,
|
|||
|
})
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return nil
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
func (s *MonitorService) getProcessInfo(status *model.SystemStatus) error {
|
|||
|
|
|||
|
processes, err := process.Processes()
|
|||
|
|
|||
|
if err != nil {
|
|||
|
|
|||
|
return err
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
status.Process.Total = len(processes)
|
|||
|
|
|||
|
status.Process.List = make([]model.ProcessInfo, 0)
|
|||
|
|
|||
|
for i := 0; i < 10 && i < len(processes); i++ {
|
|||
|
|
|||
|
p := processes[i]
|
|||
|
|
|||
|
name, _ := p.Name()
|
|||
|
|
|||
|
cpu, _ := p.CPUPercent()
|
|||
|
|
|||
|
mem, _ := p.MemoryPercent()
|
|||
|
|
|||
|
created, _ := p.CreateTime()
|
|||
|
|
|||
|
status.Process.List = append(status.Process.List, model.ProcessInfo{
|
|||
|
|
|||
|
PID: int(p.Pid),
|
|||
|
|
|||
|
Name: name,
|
|||
|
|
|||
|
CPU: cpu,
|
|||
|
|
|||
|
Memory: float64(mem),
|
|||
|
|
|||
|
Created: created,
|
|||
|
})
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return nil
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
func (s *MonitorService) getHostInfo(status *model.SystemStatus) error {
|
|||
|
|
|||
|
info, err := host.Info()
|
|||
|
|
|||
|
if err != nil {
|
|||
|
|
|||
|
return err
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
status.Host.Hostname = info.Hostname
|
|||
|
|
|||
|
status.Host.OS = info.OS
|
|||
|
|
|||
|
status.Host.Platform = info.Platform
|
|||
|
|
|||
|
status.Host.PlatformVersion = info.PlatformVersion
|
|||
|
|
|||
|
status.Host.KernelVersion = info.KernelVersion
|
|||
|
|
|||
|
status.Host.BootTime = time.Unix(int64(info.BootTime), 0)
|
|||
|
|
|||
|
return nil
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
func (s *MonitorService) getSystemInfo(status *model.SystemStatus) {
|
|||
|
|
|||
|
status.System.Uptime = time.Since(s.startTime)
|
|||
|
|
|||
|
status.System.CurrentTime = time.Now()
|
|||
|
|
|||
|
var activeUsers int64
|
|||
|
|
|||
|
s.db.Model(&model.User{}).Count(&activeUsers)
|
|||
|
|
|||
|
status.System.ActiveUsers = int(activeUsers)
|
|||
|
|
|||
|
var totalDevices int64
|
|||
|
|
|||
|
s.db.Model(&model.Device{}).Count(&totalDevices)
|
|||
|
|
|||
|
status.System.TotalDevices = int(totalDevices)
|
|||
|
|
|||
|
}
|