Files
Beach/internal/beach/host_linux.go
T
2026-10-27 16:57:53 -06:00

54 lines
1.4 KiB
Go

//go:build linux
package beach
import (
"os"
"runtime"
"sync"
"syscall"
"time"
)
var (
cpuMu sync.Mutex
lastCPU cpuTimes
lastAt time.Time
lastPct float64
)
func readFile(p string) string { b, _ := os.ReadFile(p); return string(b) }
// CollectHost reads /proc. CPU use is the change since the previous call; the
// first call takes a short sample of its own.
func CollectHost() Host {
h := Host{Supported: true, CPUs: runtime.NumCPU(), Disks: []Filesystem{}}
h.Hostname, _ = os.Hostname()
h.Uptime = parseUptime(readFile("/proc/uptime"))
h.Load = parseLoad(readFile("/proc/loadavg"))
h.MemTotal, h.MemUsed, h.SwapTotal, h.SwapUsed = parseMeminfo(readFile("/proc/meminfo"))
cpuMu.Lock()
if now, err := parseCPU(readFile("/proc/stat")); err == nil {
if lastAt.IsZero() {
time.Sleep(250 * time.Millisecond)
if n2, err := parseCPU(readFile("/proc/stat")); err == nil {
lastPct, now = cpuPct(now, n2), n2
}
lastCPU, lastAt = now, time.Now()
} else if time.Since(lastAt) > 500*time.Millisecond {
lastPct = cpuPct(lastCPU, now)
lastCPU, lastAt = now, time.Now()
}
}
h.CPUPct = lastPct
cpuMu.Unlock()
for _, m := range realMounts(readFile("/proc/mounts")) {
var st syscall.Statfs_t
if syscall.Statfs(m, &st) == nil && st.Blocks > 0 {
bs := uint64(st.Bsize)
h.Disks = append(h.Disks, Filesystem{Mount: m, Total: st.Blocks * bs, Used: (st.Blocks - st.Bfree) * bs})
}
}
return h
}