usageinfo.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. package usageinfo
  2. import (
  3. "math"
  4. "os/exec"
  5. "runtime"
  6. "strconv"
  7. "strings"
  8. )
  9. /*
  10. Usage Info (CPU / RAM)
  11. author: tobychui
  12. This module get the CPU information on different platform using
  13. native terminal commands
  14. */
  15. const query_cpuproc_command = "ps -eo pcpu,pid,user,args | sort -k 1 -r | head -10"
  16. const query_freemem_command = "top -d1 | sed '4q;d' | awk '{print $(NF-1)}'"
  17. const query_phymem_command = "sysctl hw.physmem | awk '{print $NF}'"
  18. //Get CPU Usage in percentage
  19. func GetCPUUsage() float64 {
  20. usage := float64(0)
  21. if runtime.GOOS == "windows" {
  22. cmd := exec.Command("system/hardware/windows/getCPUload.exe")
  23. out, err := cmd.CombinedOutput()
  24. if err != nil {
  25. usage = 0
  26. }
  27. percentageOnly := strings.Split(string(out), " ")[0]
  28. s, err := strconv.ParseFloat(percentageOnly, 64)
  29. if err != nil {
  30. usage = 0
  31. }
  32. usage = s
  33. } else if runtime.GOOS == "linux" || runtime.GOOS == "freebsd" {
  34. //Get CPU first 10 processes uses most CPU resources
  35. cmd := exec.Command("bash", "-c", query_cpuproc_command)
  36. out, err := cmd.CombinedOutput()
  37. if err != nil {
  38. usage = 0
  39. }
  40. usageCounter := float64(0)
  41. usageInfo := strings.Split(string(out), "\n")
  42. for _, info := range usageInfo {
  43. if strings.Contains(info, "%CPU") == false {
  44. dataChunk := strings.Split(strings.TrimSpace(info), " ")
  45. if len(dataChunk) > 0 {
  46. s, err := strconv.ParseFloat(dataChunk[0], 64)
  47. if err == nil {
  48. usageCounter += s
  49. }
  50. }
  51. }
  52. }
  53. // Prepare queryNCPUCommnad for core count query
  54. queryNCPUCommand := ""
  55. if runtime.GOOS == "linux" {
  56. queryNCPUCommand = "nproc"
  57. } else if runtime.GOOS == "freebsd" {
  58. queryNCPUCommand = "sysctl hw.ncpu | awk '{print $NF}'"
  59. }
  60. // Get CPU core count
  61. cmd = exec.Command(queryNCPUCommand)
  62. out, err = cmd.CombinedOutput()
  63. if err != nil {
  64. return usageCounter
  65. }
  66. // Divide total CPU usage by processes by total CPU core count
  67. coreCount, err := strconv.Atoi(string(out))
  68. if err != nil {
  69. coreCount = 1
  70. }
  71. usage = usageCounter / float64(coreCount)
  72. if usage > float64(100) {
  73. usage = 100
  74. }
  75. } else {
  76. // CPU Usage Not supported on this platform
  77. }
  78. return usage
  79. }
  80. //Get RAM usage, return used / total / used percentage
  81. func GetRAMUsage() (string, string, float64) {
  82. usedRam := "Unknown"
  83. totalRam := "Unknown"
  84. usedPercentage := float64(0)
  85. if runtime.GOOS == "windows" {
  86. cmd := exec.Command("system/hardware/windows/RAMUsage.exe")
  87. out, err := cmd.CombinedOutput()
  88. if err != nil {
  89. return usedRam, totalRam, usedPercentage
  90. }
  91. raminfo := strings.Split(strings.TrimSpace(string(out)), ",")
  92. if len(raminfo) == 3 {
  93. usedRam = raminfo[0]
  94. totalRam = raminfo[1]
  95. s, err := strconv.ParseFloat(raminfo[2], 64)
  96. if err != nil {
  97. return usedRam, totalRam, usedPercentage
  98. }
  99. usedPercentage = s * float64(100)
  100. } else {
  101. return usedRam, totalRam, usedPercentage
  102. }
  103. return usedRam, totalRam, usedPercentage
  104. } else if runtime.GOOS == "linux" {
  105. cmd := exec.Command("bash", "-c", "free -m | grep Mem:")
  106. out, err := cmd.CombinedOutput()
  107. if err != nil {
  108. return usedRam, totalRam, usedPercentage
  109. }
  110. //If the output contain more than one Memory info, only use the first one
  111. if strings.Contains(string(out), "\n") {
  112. out = []byte(strings.Split(string(out), "\n")[0])
  113. }
  114. //Trim of double space to space
  115. for strings.Contains(string(out), " ") {
  116. out = []byte(strings.ReplaceAll(string(out), " ", " "))
  117. }
  118. data := strings.Split(string(out), " ")
  119. if len(data) > 3 {
  120. usedRam = data[2] + " MB"
  121. totalRam = data[1] + " MB"
  122. //Calculate used memory
  123. usedFloat, err := strconv.ParseFloat(data[2], 64)
  124. if err != nil {
  125. return usedRam, totalRam, usedPercentage
  126. }
  127. totalFloat, err := strconv.ParseFloat(data[1], 64)
  128. if err != nil {
  129. return usedRam, totalRam, usedPercentage
  130. }
  131. usedPercentage = usedFloat / totalFloat * 100
  132. return usedRam, totalRam, usedPercentage
  133. }
  134. } else if runtime.GOOS == "freebsd" {
  135. // Get usused memory size (free)
  136. cmd := exec.Command("bash", "-c", query_freemem_command)
  137. freeMemByteArr, err := cmd.CombinedOutput()
  138. if err != nil {
  139. return usedRam, totalRam, usedPercentage
  140. }
  141. freeMemStr := string(freeMemByteArr)
  142. freeMemStr = strings.ReplaceAll(freeMemStr, "\n", "")
  143. freeMemSize, err := strconv.ParseFloat(strings.ReplaceAll(string(freeMemStr), "M", ""), 10)
  144. // Get phy memory size
  145. cmd = exec.Command("bash", "-c", query_phymem_command)
  146. phyMemByteArr, err := cmd.CombinedOutput()
  147. if err != nil {
  148. return usedRam, totalRam, usedPercentage
  149. }
  150. phyMemStr := string(phyMemByteArr)
  151. phyMemStr = strings.ReplaceAll(phyMemStr, "\n", "")
  152. // phyMemSize in MB
  153. phyMemSizeFloat, err := strconv.ParseFloat(phyMemStr, 10)
  154. phyMemSizeFloat = phyMemSizeFloat / 1048576
  155. phyMemSizeFloat = math.Floor(phyMemSizeFloat)
  156. totalRam = strconv.FormatFloat(phyMemSizeFloat, 'f', -1, 64) + "MB"
  157. // Used memory
  158. usedRAMSizeFloat := phyMemSizeFloat - freeMemSize
  159. usedRAMSizeFloat = math.Floor(usedRAMSizeFloat)
  160. usedRam = strconv.FormatFloat(usedRAMSizeFloat, 'f', -1, 64) + "MB"
  161. usedPercentage = usedRAMSizeFloat / phyMemSizeFloat * 100
  162. return usedRam, totalRam, usedPercentage
  163. }
  164. return usedRam, totalRam, usedPercentage
  165. }