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  }