367 lines
5.2 KiB
Go
367 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)
|
||
|
||
}
|