184 lines
4.5 KiB
Go
184 lines
4.5 KiB
Go
|
|
package apis
|
||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
"github.com/shirou/gopsutil/v3/net"
|
||
|
|
"runtime"
|
||
|
|
"strconv"
|
||
|
|
"strings"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"github.com/gin-gonic/gin"
|
||
|
|
"github.com/go-admin-team/go-admin-core/sdk/api"
|
||
|
|
"github.com/go-admin-team/go-admin-core/sdk/pkg"
|
||
|
|
"github.com/shirou/gopsutil/v3/cpu"
|
||
|
|
"github.com/shirou/gopsutil/v3/disk"
|
||
|
|
"github.com/shirou/gopsutil/v3/host"
|
||
|
|
"github.com/shirou/gopsutil/v3/mem"
|
||
|
|
)
|
||
|
|
|
||
|
|
const (
|
||
|
|
B = 1
|
||
|
|
KB = 1024 * B
|
||
|
|
MB = 1024 * KB
|
||
|
|
GB = 1024 * MB
|
||
|
|
)
|
||
|
|
|
||
|
|
var excludeNetInterfaces = []string{
|
||
|
|
"lo", "tun", "docker", "veth", "br-", "vmbr", "vnet", "kube",
|
||
|
|
}
|
||
|
|
|
||
|
|
type ServerMonitor struct {
|
||
|
|
api.Api
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetHourDiffer 获取相差时间
|
||
|
|
func GetHourDiffer(startTime, endTime string) int64 {
|
||
|
|
t1, err1 := time.ParseInLocation("2006-01-02 15:04:05", startTime, time.Local)
|
||
|
|
t2, err2 := time.ParseInLocation("2006-01-02 15:04:05", endTime, time.Local)
|
||
|
|
if err1 != nil || err2 != nil || !t1.Before(t2) {
|
||
|
|
return 0
|
||
|
|
}
|
||
|
|
return (t2.Unix() - t1.Unix()) / 3600
|
||
|
|
}
|
||
|
|
|
||
|
|
// ServerInfo 获取系统信息
|
||
|
|
func (e ServerMonitor) ServerInfo(c *gin.Context) {
|
||
|
|
e.Context = c
|
||
|
|
|
||
|
|
osInfo := getOSInfo()
|
||
|
|
memInfo := getMemoryInfo()
|
||
|
|
swapInfo := getSwapInfo()
|
||
|
|
cpuInfo := getCPUInfo()
|
||
|
|
diskInfo := getDiskInfo()
|
||
|
|
netInfo := getNetworkInfo()
|
||
|
|
|
||
|
|
bootTime, _ := host.BootTime()
|
||
|
|
cachedBootTime := time.Unix(int64(bootTime), 0)
|
||
|
|
|
||
|
|
e.Custom(gin.H{
|
||
|
|
"code": 200,
|
||
|
|
"os": osInfo,
|
||
|
|
"mem": memInfo,
|
||
|
|
"cpu": cpuInfo,
|
||
|
|
"disk": diskInfo,
|
||
|
|
"net": netInfo,
|
||
|
|
"swap": swapInfo,
|
||
|
|
"location": "Aliyun",
|
||
|
|
"bootTime": GetHourDiffer(cachedBootTime.Format("2006-01-02 15:04:05"), time.Now().Format("2006-01-02 15:04:05")),
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func getOSInfo() map[string]interface{} {
|
||
|
|
sysInfo, _ := host.Info()
|
||
|
|
return map[string]interface{}{
|
||
|
|
"goOs": runtime.GOOS,
|
||
|
|
"arch": runtime.GOARCH,
|
||
|
|
"mem": runtime.MemProfileRate,
|
||
|
|
"compiler": runtime.Compiler,
|
||
|
|
"version": runtime.Version(),
|
||
|
|
"numGoroutine": runtime.NumGoroutine(),
|
||
|
|
"ip": pkg.GetLocalHost(),
|
||
|
|
"projectDir": pkg.GetCurrentPath(),
|
||
|
|
"hostName": sysInfo.Hostname,
|
||
|
|
"time": time.Now().Format("2006-01-02 15:04:05"),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func getMemoryInfo() map[string]interface{} {
|
||
|
|
memory, _ := mem.VirtualMemory()
|
||
|
|
return map[string]interface{}{
|
||
|
|
"used": memory.Used / MB,
|
||
|
|
"total": memory.Total / MB,
|
||
|
|
"percent": pkg.Round(memory.UsedPercent, 2),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func getSwapInfo() map[string]interface{} {
|
||
|
|
memory, _ := mem.VirtualMemory()
|
||
|
|
return map[string]interface{}{
|
||
|
|
"used": memory.SwapTotal - memory.SwapFree,
|
||
|
|
"total": memory.SwapTotal,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func getCPUInfo() map[string]interface{} {
|
||
|
|
cpuInfo, _ := cpu.Info()
|
||
|
|
percent, _ := cpu.Percent(0, false)
|
||
|
|
cpuNum, _ := cpu.Counts(false)
|
||
|
|
return map[string]interface{}{
|
||
|
|
"cpuInfo": cpuInfo,
|
||
|
|
"percent": pkg.Round(percent[0], 2),
|
||
|
|
"cpuNum": cpuNum,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func getDiskInfo() map[string]interface{} {
|
||
|
|
var diskTotal, diskUsed, diskUsedPercent float64
|
||
|
|
diskList := make([]disk.UsageStat, 0)
|
||
|
|
|
||
|
|
diskInfo, err := disk.Partitions(true)
|
||
|
|
if err == nil {
|
||
|
|
for _, p := range diskInfo {
|
||
|
|
diskDetail, err := disk.Usage(p.Mountpoint)
|
||
|
|
if err == nil {
|
||
|
|
diskDetail.UsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", diskDetail.UsedPercent), 64)
|
||
|
|
diskDetail.Total /= MB
|
||
|
|
diskDetail.Used /= MB
|
||
|
|
diskDetail.Free /= MB
|
||
|
|
diskList = append(diskList, *diskDetail)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
d, _ := disk.Usage("/")
|
||
|
|
diskTotal = float64(d.Total / GB)
|
||
|
|
diskUsed = float64(d.Used / GB)
|
||
|
|
diskUsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", d.UsedPercent), 64)
|
||
|
|
|
||
|
|
return map[string]interface{}{
|
||
|
|
"total": diskTotal,
|
||
|
|
"used": diskUsed,
|
||
|
|
"percent": diskUsedPercent,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func getNetworkInfo() map[string]interface{} {
|
||
|
|
netInSpeed, netOutSpeed := trackNetworkSpeed()
|
||
|
|
return map[string]interface{}{
|
||
|
|
"in": pkg.Round(float64(netInSpeed/KB), 2),
|
||
|
|
"out": pkg.Round(float64(netOutSpeed/KB), 2),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func trackNetworkSpeed() (uint64, uint64) {
|
||
|
|
var netInSpeed, netOutSpeed, netInTransfer, netOutTransfer, lastUpdateNetStats uint64
|
||
|
|
nc, err := net.IOCounters(true)
|
||
|
|
if err == nil {
|
||
|
|
for _, v := range nc {
|
||
|
|
if isListContainsStr(excludeNetInterfaces, v.Name) {
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
netInTransfer += v.BytesRecv
|
||
|
|
netOutTransfer += v.BytesSent
|
||
|
|
}
|
||
|
|
now := uint64(time.Now().Unix())
|
||
|
|
diff := now - lastUpdateNetStats
|
||
|
|
if diff > 0 {
|
||
|
|
netInSpeed = (netInTransfer - netInTransfer) / diff
|
||
|
|
netOutSpeed = (netOutTransfer - netOutTransfer) / diff
|
||
|
|
}
|
||
|
|
lastUpdateNetStats = now
|
||
|
|
}
|
||
|
|
return netInSpeed, netOutSpeed
|
||
|
|
}
|
||
|
|
|
||
|
|
func isListContainsStr(list []string, str string) bool {
|
||
|
|
for _, item := range list {
|
||
|
|
if strings.Contains(str, item) {
|
||
|
|
return true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return false
|
||
|
|
}
|