nginx-ui/server/api/analytic.go

141 lines
3.7 KiB
Go

package api
import (
"encoding/json"
"fmt"
"github.com/0xJacky/Nginx-UI/server/analytic"
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/disk"
"github.com/shirou/gopsutil/v3/host"
"github.com/shirou/gopsutil/v3/load"
"github.com/shirou/gopsutil/v3/mem"
"github.com/shirou/gopsutil/v3/net"
"math"
"net/http"
"runtime"
"strconv"
"time"
"github.com/dustin/go-humanize"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
)
func Analytic(c *gin.Context) {
var upGrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
// upgrade http to websocket
ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
return
}
defer ws.Close()
response := make(gin.H)
for {
// read
mt, message, err := ws.ReadMessage()
if err != nil {
break
}
for {
memoryStat, err := mem.VirtualMemory()
if err != nil {
fmt.Println(err)
return
}
response["memory_total"] = humanize.Bytes(memoryStat.Total)
response["memory_used"] = humanize.Bytes(memoryStat.Used)
response["memory_cached"] = humanize.Bytes(memoryStat.Cached)
response["memory_free"] = humanize.Bytes(memoryStat.Free)
response["memory_swap_used"] = humanize.Bytes(memoryStat.SwapTotal - memoryStat.SwapFree)
response["memory_swap_total"] = humanize.Bytes(memoryStat.SwapTotal)
response["memory_swap_cached"] = humanize.Bytes(memoryStat.SwapCached)
response["memory_swap_percent"] = float64(memoryStat.SwapFree) / math.Max(float64(memoryStat.SwapTotal), 1)
response["memory_pressure"], _ = strconv.ParseFloat(fmt.Sprintf("%.2f", memoryStat.UsedPercent), 64)
cpuTimesBefore, _ := cpu.Times(false)
time.Sleep(1000 * time.Millisecond)
cpuTimesAfter, _ := cpu.Times(false)
threadNum := runtime.GOMAXPROCS(0)
cpuUserUsage := (cpuTimesAfter[0].User - cpuTimesBefore[0].User) / (float64(1000*threadNum) / 1000)
cpuSystemUsage := (cpuTimesAfter[0].System - cpuTimesBefore[0].System) / (float64(1000*threadNum) / 1000)
response["cpu_user"], _ = strconv.ParseFloat(fmt.Sprintf("%.2f",
cpuUserUsage*100), 64)
response["cpu_system"], _ = strconv.ParseFloat(fmt.Sprintf("%.2f",
cpuSystemUsage*100), 64)
response["cpu_idle"], _ = strconv.ParseFloat(fmt.Sprintf("%.2f",
(1-cpuUserUsage+cpuSystemUsage)*100), 64)
response["uptime"], _ = host.Uptime()
response["loadavg"], _ = load.Avg()
diskUsage, _ := disk.Usage(".")
response["disk_used"] = humanize.Bytes(diskUsage.Used)
response["disk_total"] = humanize.Bytes(diskUsage.Total)
response["disk_percentage"], _ = strconv.ParseFloat(fmt.Sprintf("%.2f", diskUsage.UsedPercent), 64)
response["diskIO"] = gin.H{
"writes": analytic.DiskWriteRecord[len(analytic.DiskWriteRecord)-1],
"reads": analytic.DiskReadRecord[len(analytic.DiskReadRecord)-1],
}
network, _ := net.IOCounters(false)
if len(network) > 0 {
response["network"] = network[0]
}
m, _ := json.Marshal(response)
message = m
// write
err = ws.WriteMessage(mt, message)
if err != nil {
break
}
time.Sleep(800 * time.Microsecond)
}
}
}
func GetAnalyticInit(c *gin.Context) {
cpuInfo, _ := cpu.Info()
network, _ := net.IOCounters(false)
var _net net.IOCountersStat
if len(network) > 0 {
_net = network[0]
}
hostInfo, _ := host.Info()
c.JSON(http.StatusOK, gin.H{
"host": hostInfo,
"cpu": gin.H{
"info": cpuInfo,
"user": analytic.CpuUserRecord,
"total": analytic.CpuTotalRecord,
},
"network": gin.H{
"init": _net,
"bytesRecv": analytic.NetRecvRecord,
"bytesSent": analytic.NetSentRecord,
},
"diskIO": gin.H{
"writes": analytic.DiskWriteRecord,
"reads": analytic.DiskReadRecord,
},
})
}