summaryrefslogtreecommitdiffstats
path: root/widgets/mem.go
blob: 1c85f3bc188f541f6ea89b3bd0c20e7075c450fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package widgets

import (
	"fmt"
	"log"
	"time"

	"github.com/prometheus/client_golang/prometheus"
	psMem "github.com/shirou/gopsutil/mem"

	ui "github.com/xxxserxxx/gotop/termui"
	"github.com/xxxserxxx/gotop/utils"
)

type MemWidget struct {
	*ui.LineGraph
	updateInterval time.Duration
	mainMetric     prometheus.Gauge
	swapMetric     prometheus.Gauge
}

type MemoryInfo struct {
	Total       uint64
	Used        uint64
	UsedPercent float64
}

func (self *MemWidget) renderMemInfo(line string, memoryInfo MemoryInfo) {
	self.Data[line] = append(self.Data[line], memoryInfo.UsedPercent)
	memoryTotalBytes, memoryTotalMagnitude := utils.ConvertBytes(memoryInfo.Total)
	memoryUsedBytes, memoryUsedMagnitude := utils.ConvertBytes(memoryInfo.Used)
	self.Labels[line] = fmt.Sprintf("%3.0f%% %5.1f%s/%.0f%s",
		memoryInfo.UsedPercent,
		memoryUsedBytes,
		memoryUsedMagnitude,
		memoryTotalBytes,
		memoryTotalMagnitude,
	)
}

func (self *MemWidget) updateMainMemory() {
	mainMemory, err := psMem.VirtualMemory()
	if err != nil {
		log.Printf("failed to get main memory info from gopsutil: %v", err)
	} else {
		self.renderMemInfo("Main", MemoryInfo{
			Total:       mainMemory.Total,
			Used:        mainMemory.Used,
			UsedPercent: mainMemory.UsedPercent,
		})
		if self.mainMetric != nil {
			self.mainMetric.Set(mainMemory.UsedPercent)
		}
	}
}

func NewMemWidget(updateInterval time.Duration, horizontalScale int) *MemWidget {
	self := &MemWidget{
		LineGraph:      ui.NewLineGraph(),
		updateInterval: updateInterval,
	}
	self.Title = " Memory Usage "
	self.HorizontalScale = horizontalScale
	self.Data["Main"] = []float64{0}
	self.Data["Swap"] = []float64{0}

	self.updateMainMemory()
	self.updateSwapMemory()

	go func() {
		for range time.NewTicker(self.updateInterval).C {
			self.Lock()
			self.updateMainMemory()
			self.updateSwapMemory()
			self.Unlock()
		}
	}()

	return self
}

func (b *MemWidget) EnableMetric() {
	b.mainMetric = prometheus.NewGauge(prometheus.GaugeOpts{
		Namespace: "gotop",
		Subsystem: "memory",
		Name:      "main",
	})
	mainMemory, err := psMem.VirtualMemory()
	if err == nil {
		b.mainMetric.Set(mainMemory.UsedPercent)
	}
	prometheus.MustRegister(b.mainMetric)

	b.swapMetric = prometheus.NewGauge(prometheus.GaugeOpts{
		Namespace: "gotop",
		Subsystem: "memory",
		Name:      "swap",
	})
	swapMemory, err := psMem.SwapMemory()
	if err == nil {
		b.swapMetric.Set(swapMemory.UsedPercent)
	}
	prometheus.MustRegister(b.swapMetric)
}

func (b *MemWidget) Scale(i int) {
	b.LineGraph.HorizontalScale = i
}