analytic.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package analytic
  2. import (
  3. "fmt"
  4. "github.com/0xJacky/Nginx-UI/internal/analytic"
  5. "github.com/0xJacky/Nginx-UI/internal/logger"
  6. "github.com/shirou/gopsutil/v3/cpu"
  7. "github.com/shirou/gopsutil/v3/host"
  8. "github.com/shirou/gopsutil/v3/load"
  9. "github.com/shirou/gopsutil/v3/net"
  10. "github.com/spf13/cast"
  11. "net/http"
  12. "runtime"
  13. "time"
  14. "github.com/gin-gonic/gin"
  15. "github.com/gorilla/websocket"
  16. )
  17. func Analytic(c *gin.Context) {
  18. var upGrader = websocket.Upgrader{
  19. CheckOrigin: func(r *http.Request) bool {
  20. return true
  21. },
  22. }
  23. // upgrade http to websocket
  24. ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
  25. if err != nil {
  26. logger.Error(err)
  27. return
  28. }
  29. defer ws.Close()
  30. var stat Stat
  31. for {
  32. stat.Memory, err = analytic.GetMemoryStat()
  33. if err != nil {
  34. logger.Error(err)
  35. return
  36. }
  37. cpuTimesBefore, _ := cpu.Times(false)
  38. time.Sleep(1000 * time.Millisecond)
  39. cpuTimesAfter, _ := cpu.Times(false)
  40. threadNum := runtime.GOMAXPROCS(0)
  41. cpuUserUsage := (cpuTimesAfter[0].User - cpuTimesBefore[0].User) / (float64(1000*threadNum) / 1000)
  42. cpuSystemUsage := (cpuTimesAfter[0].System - cpuTimesBefore[0].System) / (float64(1000*threadNum) / 1000)
  43. stat.CPU = CPUStat{
  44. User: cast.ToFloat64(fmt.Sprintf("%.2f", cpuUserUsage*100)),
  45. System: cast.ToFloat64(fmt.Sprintf("%.2f", cpuSystemUsage*100)),
  46. Idle: cast.ToFloat64(fmt.Sprintf("%.2f", (1-cpuUserUsage-cpuSystemUsage)*100)),
  47. Total: cast.ToFloat64(fmt.Sprintf("%.2f", (cpuUserUsage+cpuSystemUsage)*100)),
  48. }
  49. stat.Uptime, _ = host.Uptime()
  50. stat.LoadAvg, _ = load.Avg()
  51. stat.Disk, err = analytic.GetDiskStat()
  52. if err != nil {
  53. logger.Error(err)
  54. return
  55. }
  56. network, _ := net.IOCounters(false)
  57. if len(network) > 0 {
  58. stat.Network = network[0]
  59. }
  60. // write
  61. err = ws.WriteJSON(stat)
  62. if err != nil || websocket.IsUnexpectedCloseError(err,
  63. websocket.CloseGoingAway,
  64. websocket.CloseNoStatusReceived,
  65. websocket.CloseNormalClosure) {
  66. logger.Error(err)
  67. break
  68. }
  69. time.Sleep(800 * time.Microsecond)
  70. }
  71. }
  72. func GetAnalyticInit(c *gin.Context) {
  73. cpuInfo, err := cpu.Info()
  74. if err != nil {
  75. logger.Error(err)
  76. }
  77. network, err := net.IOCounters(false)
  78. if err != nil {
  79. logger.Error(err)
  80. }
  81. memory, err := analytic.GetMemoryStat()
  82. if err != nil {
  83. logger.Error(err)
  84. }
  85. diskStat, err := analytic.GetDiskStat()
  86. if err != nil {
  87. logger.Error(err)
  88. }
  89. var _net net.IOCountersStat
  90. if len(network) > 0 {
  91. _net = network[0]
  92. }
  93. hostInfo, _ := host.Info()
  94. switch hostInfo.Platform {
  95. case "ubuntu":
  96. hostInfo.Platform = "Ubuntu"
  97. case "centos":
  98. hostInfo.Platform = "CentOS"
  99. }
  100. loadAvg, err := load.Avg()
  101. if err != nil {
  102. logger.Error(err)
  103. }
  104. c.JSON(http.StatusOK, InitResp{
  105. Host: hostInfo,
  106. CPU: CPURecords{
  107. Info: cpuInfo,
  108. User: analytic.CpuUserRecord,
  109. Total: analytic.CpuTotalRecord,
  110. },
  111. Network: NetworkRecords{
  112. Init: _net,
  113. BytesRecv: analytic.NetRecvRecord,
  114. BytesSent: analytic.NetSentRecord,
  115. },
  116. DiskIO: DiskIORecords{
  117. Writes: analytic.DiskWriteRecord,
  118. Reads: analytic.DiskReadRecord,
  119. },
  120. Memory: memory,
  121. Disk: diskStat,
  122. LoadAvg: loadAvg,
  123. })
  124. }