selfapi-v2 / monitor /stats.go
akashyadav758
Dockerize stack, strip watermarking, add navigator monitor
c6e6dac
Raw
History Blame Contribute Delete
1.8 kB
package main
import (
"bufio"
"os"
"strconv"
"strings"
"time"
)
type memInfo struct {
usedGB float64
totalGB float64
pct float64
}
func readMeminfo() memInfo {
f, err := os.Open("/proc/meminfo")
if err != nil {
return memInfo{}
}
defer f.Close()
var totalKB, availKB float64
sc := bufio.NewScanner(f)
for sc.Scan() {
fields := strings.Fields(sc.Text())
if len(fields) < 2 {
continue
}
v, _ := strconv.ParseFloat(fields[1], 64)
switch fields[0] {
case "MemTotal:":
totalKB = v
case "MemAvailable:":
availKB = v
}
}
if totalKB == 0 {
return memInfo{}
}
usedKB := totalKB - availKB
return memInfo{
usedGB: round1(usedKB / 1024 / 1024),
totalGB: round1(totalKB / 1024 / 1024),
pct: round1(usedKB / totalKB * 100),
}
}
func round1(f float64) float64 {
return float64(int(f*10+0.5)) / 10
}
// readCPUPercent samples /proc/stat over a short window.
func readCPUPercent() float64 {
idle1, total1 := cpuSample()
time.Sleep(200 * time.Millisecond)
idle2, total2 := cpuSample()
dt := total2 - total1
if dt == 0 {
return 0
}
return round1((1 - (idle2-idle1)/dt) * 100)
}
func cpuSample() (idle, total float64) {
f, err := os.Open("/proc/stat")
if err != nil {
return 0, 0
}
defer f.Close()
sc := bufio.NewScanner(f)
for sc.Scan() {
fields := strings.Fields(sc.Text())
if len(fields) > 0 && fields[0] == "cpu" {
for i, v := range fields[1:] {
n, _ := strconv.ParseFloat(v, 64)
total += n
if i == 3 { // idle
idle = n
}
}
return idle, total
}
}
return 0, 0
}
func readUptime() int {
b, err := os.ReadFile("/proc/uptime")
if err != nil {
return 0
}
fields := strings.Fields(string(b))
if len(fields) == 0 {
return 0
}
v, _ := strconv.ParseFloat(fields[0], 64)
return int(v)
}