237 lines
6.0 KiB
Go
237 lines
6.0 KiB
Go
package service
|
||
|
||
import (
|
||
"bufio"
|
||
"fmt"
|
||
"os"
|
||
"runtime"
|
||
"strings"
|
||
"time"
|
||
|
||
"ems.agt/src/framework/config"
|
||
"ems.agt/src/framework/utils/parse"
|
||
|
||
"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"
|
||
)
|
||
|
||
// 实例化服务层 SystemInfoImpl 结构体
|
||
var NewSystemInfoImpl = &SystemInfoImpl{}
|
||
|
||
// SystemInfoImpl 服务器系统相关信息 服务层处理
|
||
type SystemInfoImpl struct{}
|
||
|
||
// ProjectInfo 程序项目信息
|
||
func (s *SystemInfoImpl) ProjectInfo() map[string]any {
|
||
// 获取工作目录
|
||
appDir, err := os.Getwd()
|
||
if err != nil {
|
||
appDir = ""
|
||
}
|
||
// 项目依赖
|
||
dependencies := s.dependencies()
|
||
return map[string]any{
|
||
"appDir": appDir,
|
||
"env": config.Env(),
|
||
"name": config.Get("framework.name"),
|
||
"version": config.Get("framework.version"),
|
||
"dependencies": dependencies,
|
||
}
|
||
}
|
||
|
||
// dependencies 读取mod内项目包依赖
|
||
func (s *SystemInfoImpl) dependencies() map[string]string {
|
||
var pkgs = make(map[string]string)
|
||
|
||
// 打开 go.mod 文件
|
||
file, err := os.Open("go.mod")
|
||
if err != nil {
|
||
return pkgs
|
||
}
|
||
defer file.Close()
|
||
|
||
// 使用 bufio.Scanner 逐行读取文件内容
|
||
scanner := bufio.NewScanner(file)
|
||
for scanner.Scan() {
|
||
line := scanner.Text()
|
||
line = strings.TrimSpace(line)
|
||
|
||
// 行不为空,不以module\require开头,不带有 // indirect 注释,则解析包名和版本
|
||
prefixLine := strings.HasPrefix(line, "module") || strings.HasPrefix(line, "require") || strings.HasPrefix(line, "go ")
|
||
suffixLine := strings.HasSuffix(line, ")") || strings.HasSuffix(line, "// indirect")
|
||
if line == "" || prefixLine || suffixLine {
|
||
continue
|
||
}
|
||
|
||
modInfo := strings.Split(line, " ")
|
||
if len(modInfo) >= 2 {
|
||
moduleName := strings.TrimSpace(modInfo[0])
|
||
version := strings.TrimSpace(modInfo[1])
|
||
pkgs[moduleName] = version
|
||
}
|
||
}
|
||
|
||
if err := scanner.Err(); err != nil {
|
||
pkgs["scanner-err"] = err.Error()
|
||
}
|
||
return pkgs
|
||
}
|
||
|
||
// SystemInfo 系统信息
|
||
func (s *SystemInfoImpl) SystemInfo() map[string]any {
|
||
info, err := host.Info()
|
||
if err != nil {
|
||
info.Platform = err.Error()
|
||
}
|
||
// 用户目录
|
||
homeDir, err := os.UserHomeDir()
|
||
if err != nil {
|
||
homeDir = ""
|
||
}
|
||
cmd, err := os.Executable()
|
||
if err != nil {
|
||
cmd = ""
|
||
}
|
||
return map[string]any{
|
||
"platform": info.Platform,
|
||
"go": runtime.Version(),
|
||
"processId": os.Getpid(),
|
||
"arch": info.KernelArch,
|
||
"uname": runtime.GOARCH,
|
||
"release": info.OS,
|
||
"hostname": info.Hostname,
|
||
"homeDir": homeDir,
|
||
"cmd": cmd,
|
||
"execCommand": strings.Join(os.Args, " "),
|
||
}
|
||
}
|
||
|
||
// TimeInfo 系统时间信息
|
||
func (s *SystemInfoImpl) TimeInfo() map[string]string {
|
||
// 获取当前时间
|
||
current := time.Now().Format("2006-01-02 15:04:05")
|
||
// 获取程序运行时间
|
||
uptime := time.Since(config.RunTime()).String()
|
||
// 获取时区
|
||
timezone := time.Now().Format("-0700 MST")
|
||
// 获取时区名称
|
||
timezoneName := time.Now().Format("MST")
|
||
|
||
return map[string]string{
|
||
"current": current,
|
||
"uptime": uptime,
|
||
"timezone": timezone,
|
||
"timezoneName": timezoneName,
|
||
}
|
||
}
|
||
|
||
// MemoryInfo 内存信息
|
||
func (s *SystemInfoImpl) MemoryInfo() map[string]any {
|
||
memInfo, err := mem.VirtualMemory()
|
||
if err != nil {
|
||
memInfo.UsedPercent = 0
|
||
memInfo.Available = 0
|
||
memInfo.Total = 0
|
||
}
|
||
|
||
var memStats runtime.MemStats
|
||
runtime.ReadMemStats(&memStats)
|
||
|
||
return map[string]any{
|
||
"usage": fmt.Sprintf("%.2f", memInfo.UsedPercent), // 内存利用率
|
||
"freemem": parse.Bit(float64(memInfo.Available)), // 可用内存大小(GB)
|
||
"totalmem": parse.Bit(float64(memInfo.Total)), // 总内存大小(GB)
|
||
"rss": parse.Bit(float64(memStats.Sys)), // 常驻内存大小(RSS)
|
||
"heapTotal": parse.Bit(float64(memStats.HeapSys)), // 堆总大小
|
||
"heapUsed": parse.Bit(float64(memStats.HeapAlloc)), // 堆已使用大小
|
||
"external": parse.Bit(float64(memStats.Sys - memStats.HeapSys)), // 外部内存大小(非堆)
|
||
}
|
||
}
|
||
|
||
// CPUInfo CPU信息
|
||
func (s *SystemInfoImpl) CPUInfo() map[string]any {
|
||
var core int32 = 0
|
||
var speed string = "未知"
|
||
var model string = "未知"
|
||
cpuInfo, err := cpu.Info()
|
||
if err == nil {
|
||
core = cpuInfo[0].Cores
|
||
speed = fmt.Sprintf("%.0fMHz", cpuInfo[0].Mhz)
|
||
model = strings.TrimSpace(cpuInfo[0].ModelName)
|
||
}
|
||
|
||
useds := []string{}
|
||
cpuPercent, err := cpu.Percent(0, true)
|
||
if err == nil {
|
||
for _, v := range cpuPercent {
|
||
useds = append(useds, fmt.Sprintf("%.2f", v))
|
||
}
|
||
}
|
||
|
||
return map[string]any{
|
||
"model": model,
|
||
"speed": speed,
|
||
"core": core,
|
||
"coreUsed": useds,
|
||
}
|
||
}
|
||
|
||
// NetworkInfo 网络信息
|
||
func (s *SystemInfoImpl) NetworkInfo() map[string]string {
|
||
ipAddrs := make(map[string]string)
|
||
interfaces, err := net.Interfaces()
|
||
if err == nil {
|
||
for _, iface := range interfaces {
|
||
name := iface.Name
|
||
if name[len(name)-1] == '0' {
|
||
name = name[0 : len(name)-1]
|
||
name = strings.Trim(name, "")
|
||
}
|
||
// ignore localhost
|
||
if name == "lo" {
|
||
continue
|
||
}
|
||
var addrs []string
|
||
for _, v := range iface.Addrs {
|
||
prefix := strings.Split(v.Addr, "/")[0]
|
||
if strings.Contains(prefix, "::") {
|
||
addrs = append(addrs, fmt.Sprintf("IPv6 %s", prefix))
|
||
}
|
||
if strings.Contains(prefix, ".") {
|
||
addrs = append(addrs, fmt.Sprintf("IPv4 %s", prefix))
|
||
}
|
||
}
|
||
ipAddrs[name] = strings.Join(addrs, " / ")
|
||
}
|
||
}
|
||
return ipAddrs
|
||
}
|
||
|
||
// DiskInfo 磁盘信息
|
||
func (s *SystemInfoImpl) DiskInfo() []map[string]string {
|
||
disks := make([]map[string]string, 0)
|
||
|
||
partitions, err := disk.Partitions(false)
|
||
if err != nil {
|
||
return disks
|
||
}
|
||
|
||
for _, partition := range partitions {
|
||
usage, err := disk.Usage(partition.Mountpoint)
|
||
if err != nil {
|
||
continue
|
||
}
|
||
disks = append(disks, map[string]string{
|
||
"size": parse.Bit(float64(usage.Total)),
|
||
"used": parse.Bit(float64(usage.Used)),
|
||
"avail": parse.Bit(float64(usage.Free)),
|
||
"pcent": fmt.Sprintf("%.1f%%", usage.UsedPercent),
|
||
"target": partition.Device,
|
||
})
|
||
}
|
||
return disks
|
||
}
|