91 lines
No EOL
2 KiB
Go
91 lines
No EOL
2 KiB
Go
package providers
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"regexp"
|
|
"strconv"
|
|
|
|
"github.com/codemicro/bar/internal/i3bar"
|
|
)
|
|
|
|
type Memory struct {
|
|
OkThreshold float32
|
|
WarningThreshold float32
|
|
|
|
name string
|
|
}
|
|
|
|
func NewMemory(okThreshold, warningThreshold float32) i3bar.BlockGenerator {
|
|
return &Memory{
|
|
OkThreshold: okThreshold,
|
|
WarningThreshold: warningThreshold,
|
|
name: "memory",
|
|
}
|
|
}
|
|
|
|
var (
|
|
memoryTotalRegexp = regexp.MustCompile(`MemTotal: +(\d+) kB`)
|
|
memoryAvailableRegexp = regexp.MustCompile(`MemAvailable: +(\d+) kB`)
|
|
)
|
|
|
|
func (g *Memory) getStats() (used float32, total float32, err error) {
|
|
fcont, err := ioutil.ReadFile("/proc/meminfo")
|
|
if err != nil {
|
|
return 0, 0, err
|
|
}
|
|
|
|
if x := memoryTotalRegexp.FindSubmatch(fcont); len(x) == 2 {
|
|
totalKB, err := strconv.ParseInt(string(x[1]), 10, 64)
|
|
if err != nil {
|
|
return 0, 0, err
|
|
}
|
|
total = float32(totalKB) / float32(1000*1000)
|
|
} else {
|
|
return 0, 0, errors.New("could not fetch total system memory")
|
|
}
|
|
|
|
var available float32
|
|
if x := memoryAvailableRegexp.FindSubmatch(fcont); len(x) == 2 {
|
|
availableKB, err := strconv.ParseInt(string(x[1]), 10, 64)
|
|
if err != nil {
|
|
return 0, 0, err
|
|
}
|
|
available = float32(availableKB) / float32(1000*1000)
|
|
} else {
|
|
return 0, 0, errors.New("could not fetch available system memory")
|
|
}
|
|
|
|
used = total - available
|
|
|
|
return
|
|
}
|
|
|
|
func (g *Memory) Block(colors *i3bar.ColorSet) (*i3bar.Block, error) {
|
|
used, total, err := g.getStats()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
avail := total - used
|
|
|
|
// TODO: Make the readout change between KB/MB/GB
|
|
|
|
block := &i3bar.Block{
|
|
Name: g.name,
|
|
FullText: fmt.Sprintf("Mem: %.1fGB of %.1fGB", used, total),
|
|
ShortText: fmt.Sprintf("M: %.1fGB", used),
|
|
}
|
|
|
|
if avail < g.WarningThreshold && g.WarningThreshold != 0 {
|
|
block.TextColor = colors.Bad
|
|
} else if avail < g.OkThreshold && g.OkThreshold != 0 {
|
|
block.TextColor = colors.Warning
|
|
}
|
|
|
|
return block, nil
|
|
}
|
|
|
|
func (g *Memory) GetNameAndInstance() (string, string) {
|
|
return g.name, ""
|
|
} |