git.sophuwu.com > statlog
mass bar for cpu
sophuwu sophie@sophuwu.com
Mon, 07 Jul 2025 14:12:58 +0200
commit

9442924c4b751fac072d27c3b79e3aeb6a91f763

parent

6c42af6aaa44ec33efaf89ed924e28c81b8f0b56

4 files changed, 84 insertions(+), 14 deletions(-)

jump to
M cmd/main.gocmd/main.go

@@ -3,18 +3,34 @@

import ( "fmt" "git.sophuwu.com/statlog" + "os" + "os/signal" ) +func fatal(e error) { + if e != nil { + fmt.Println("\033[?1049l\033[?25h") + os.Exit(1) + } +} + func main() { + fmt.Println("\033[?25l\033[?1049h\033[2J") + defer fmt.Println("\033[?1049l\033[?25h") hw := &statlog.HWInfo{} - for i := 0; i < 5; i++ { + ch := make(chan os.Signal, 1) + bl := true + go func() { + signal.Notify(ch, os.Interrupt, os.Kill) + <-ch + bl = false + }() + var s string + var e error + for bl { hw.Update() - s, err := hw.MEM.Bar() - if err != nil { - fmt.Println("\nError generating memory bar:", err) - break - } - fmt.Printf("\r%s", s) + s, e = hw.CPU.LoadBar() + fatal(e) + fmt.Printf("\033[2J\033[1;1H\r%s\n", s) } - fmt.Println() }
M device/cpu.godevice/cpu.go

@@ -18,6 +18,34 @@ MHzCore []types.MHz `json:"MHzCore"`

Temp types.Celsius `json:"Temp"` } +func (c *CPU) LoadBar() (s string, err error) { + w, _ := types.TermSize() + l := len(c.LoadCore) + ss := "" + div := 3 + if w < 100 { + div = 2 + } else if w > 200 { + div = 4 + } + w = (w - 2) / div + for i := 0; i < l; i++ { + if ss, err = c.LoadCore[i].Bar(fmt.Sprintf("%2d", i), w); err != nil { + return "", err + } + s += ss + if i%div == div-1 { + s += "\n" + } else { + s += " " + } + } + if s[len(s)-1] == ' ' || s[len(s)-1] == '\n' { + s = s[:len(s)-1] + } + return s, nil +} + func (cpu *CPU) loadTemp() { if cpu.Temp == -100 { return

@@ -111,7 +139,7 @@ func (c *coreLoad) percent() float64 {

if c.v[0][1] == 0 { return 0.0 } - return (c.v[1][1] - c.v[0][1]) / (c.v[1][0] - c.v[0][0]) + return (c.v[1][0] - c.v[0][0]) / (c.v[1][1] - c.v[0][1]) } func (c *CPU) loadUse() {

@@ -151,17 +179,21 @@ }

i++ } elget() + n = 0.0 for j = 0; j < 4 && i < len(b); i++ { - n = 0.0 if b[i] >= 48 && b[i] <= 57 { n = n*10 + float64(b[i]) - 48 } else if b[i] == ' ' { el.readStat(&t, &j, &n) + n = 0.0 j++ } else { return fmt.Errorf("unexpected byte %c at index %d", b[i], i) } } + if j < 3 { + return fmt.Errorf("unexpected end of line at index %d", i) + } elsv() for i < len(b) { if b[i] == '\n' {

@@ -182,7 +214,6 @@ if err != nil || len(cl) == 0 {

goto onErr } c.LoadAvg.FromFloat(cl[0].percent()) - c.LoadAvg.Clamp() cl = cl[1:] if len(cl) == 0 { goto onEmpty

@@ -190,7 +221,6 @@ }

c.LoadCore = make([]types.Percent, len(cl)) for i, j := range cl { c.LoadCore[i].FromFloat(j.percent()) - c.LoadCore[i].Clamp() } return onErr:
M types/const.gotypes/const.go

@@ -2,4 +2,4 @@ package types

import "time" -const SampleDuration = time.Second +var SampleDuration = time.Second
M types/percent.gotypes/percent.go

@@ -8,7 +8,7 @@ func (p Percent) String() string {

if p < 0 { return "" } - return fmt.Sprintf("%3.0f %%", p) + return fmt.Sprintf("%3d %%", int(p)) } func (p Percent) Compact() string {

@@ -47,3 +47,27 @@ }

func (P *Percent) SetValueInt(v int) { *P = Percent(v) } + +func (P *Percent) Bar(title string, w int) (s string, err error) { + if w == 0 { + w, _ = TermSize() + } + c := P.Compact() + s = title + " [" + w = w - len(s) - 2 - len(c) + + if w < 10 { + return "", fmt.Errorf("terminal too narrow") + } + + v := int(P.Value() * float64(w) / 100) + i := 0 + for i = 0; i < v; i++ { + s += "|" + } + for ; i < w; i++ { + s += " " + } + s += c + "] " + return s, nil +}