github.com/wtfutil/wtf@v0.43.0/modules/resourceusage/widget.go (about) 1 package resourceusage 2 3 import ( 4 "fmt" 5 "math" 6 "time" 7 8 "code.cloudfoundry.org/bytefmt" 9 "github.com/rivo/tview" 10 "github.com/shirou/gopsutil/cpu" 11 "github.com/shirou/gopsutil/mem" 12 "github.com/wtfutil/wtf/view" 13 ) 14 15 // Widget define wtf widget to register widget later 16 type Widget struct { 17 settings *Settings 18 tviewApp *tview.Application 19 view.BarGraph 20 } 21 22 // NewWidget Make new instance of widget 23 func NewWidget(tviewApp *tview.Application, redrawChan chan bool, settings *Settings) *Widget { 24 widget := Widget{ 25 BarGraph: view.NewBarGraph(tviewApp, redrawChan, settings.Name, settings.Common), 26 27 tviewApp: tviewApp, 28 settings: settings, 29 } 30 31 widget.View.SetWrap(false) 32 widget.View.SetWordWrap(false) 33 34 return &widget 35 } 36 37 /* -------------------- Exported Functions -------------------- */ 38 39 // MakeGraph - Load the dead drop stats 40 func MakeGraph(widget *Widget) { 41 cpuStats, memInfo := getDataFromSystem(widget) 42 43 var itemsCount = 0 44 if widget.settings.showCPU { 45 itemsCount += len(cpuStats) 46 } 47 48 if widget.settings.showMem { 49 itemsCount++ 50 } 51 52 if widget.settings.showSwp { 53 itemsCount++ 54 } 55 56 var stats = make([]view.Bar, itemsCount) 57 var nextIndex = 0 58 59 if widget.settings.showCPU && len(cpuStats) > 0 { 60 for i, stat := range cpuStats { 61 // Stats sometimes jump outside the 0-100 range, possibly due to timing 62 stat = math.Min(100, stat) 63 stat = math.Max(0, stat) 64 65 var label string 66 if widget.settings.cpuCombined { 67 label = "CPU" 68 } else { 69 label = fmt.Sprint(i) 70 } 71 72 bar := view.Bar{ 73 Label: label, 74 Percent: int(stat), 75 ValueLabel: fmt.Sprintf("%d%%", int(stat)), 76 LabelColor: "red", 77 } 78 79 stats[nextIndex] = bar 80 nextIndex++ 81 } 82 } 83 84 if widget.settings.showMem { 85 usedMemLabel := bytefmt.ByteSize(memInfo.Used) 86 totalMemLabel := bytefmt.ByteSize(memInfo.Total) 87 88 if usedMemLabel[len(usedMemLabel)-1] == totalMemLabel[len(totalMemLabel)-1] { 89 usedMemLabel = usedMemLabel[:len(usedMemLabel)-1] 90 } 91 92 stats[nextIndex] = view.Bar{ 93 Label: "Mem", 94 Percent: int(memInfo.UsedPercent), 95 ValueLabel: fmt.Sprintf("%s/%s", usedMemLabel, totalMemLabel), 96 LabelColor: "green", 97 } 98 nextIndex++ 99 } 100 101 if widget.settings.showSwp { 102 swapUsed := memInfo.SwapTotal - memInfo.SwapFree 103 var swapPercent float64 104 if memInfo.SwapTotal > 0 { 105 swapPercent = float64(swapUsed) / float64(memInfo.SwapTotal) 106 } 107 108 usedSwapLabel := bytefmt.ByteSize(swapUsed) 109 totalSwapLabel := bytefmt.ByteSize(memInfo.SwapTotal) 110 111 if usedSwapLabel[len(usedSwapLabel)-1] == totalSwapLabel[len(totalSwapLabel)-1] { 112 usedSwapLabel = usedSwapLabel[:len(usedSwapLabel)-1] 113 } 114 115 stats[nextIndex] = view.Bar{ 116 Label: "Swp", 117 Percent: int(swapPercent * 100), 118 ValueLabel: fmt.Sprintf("%s/%s", usedSwapLabel, totalSwapLabel), 119 LabelColor: "yellow", 120 } 121 } 122 123 widget.BarGraph.BuildBars(stats) 124 125 } 126 127 // Refresh & update after interval time 128 func (widget *Widget) Refresh() { 129 if widget.Disabled() { 130 return 131 } 132 133 widget.View.Clear() 134 MakeGraph(widget) 135 } 136 137 /* -------------------- Unexported Functions -------------------- */ 138 139 func getDataFromSystem(widget *Widget) (cpuStats []float64, memInfo mem.VirtualMemoryStat) { 140 if widget.settings.showCPU { 141 rCPUStats, err := cpu.Percent(time.Duration(0), !widget.settings.cpuCombined) 142 if err == nil { 143 cpuStats = rCPUStats 144 } 145 } 146 147 if widget.settings.showMem || widget.settings.showSwp { 148 rMemInfo, err := mem.VirtualMemory() 149 if err == nil { 150 memInfo = *rMemInfo 151 } 152 } 153 154 return cpuStats, memInfo 155 }