238
package main
import (
"os"
"time"
)
var (
cpuLoad,
cpuMHz,
cpuTemp int
totalMem,
usedMem,
takenMem,
freeMem,
availMem,
prctMem,
prctBuff,
prctFree float64
)
func errCheck(err error, errFunc func() string) bool {
if err == nil {
return false
}
print(" An error occurred: " + errFunc())
if len(os.Args) > 1 && os.Args[1] == "-d" {
print(err.Error() + "\n")
}
return true
}
func numFromLine(i int, b []byte, n *float64) int {
for ; i < len(b); i++ {
if b[i] == 10 {
return i + 1
}
if b[i] >= 48 && b[i] <= 57 {
*n = *n*10 + float64(b[i]) - 48
}
}
return i
}
func getMem() {
errFunc := func() string {
prctMem = -1
prctBuff = -1
prctFree = -1
return "Unable to read memory.\n"
}
b := make([]byte, 84)
f, err := os.Open("/proc/meminfo")
if errCheck(err, errFunc) {
return
}
_, err = f.Read(b)
if errCheck(err, errFunc) {
return
}
f.Close()
i := numFromLine(0, b, &totalMem)
totalMem /= 1000
i = numFromLine(i, b, &freeMem)
freeMem /= 1000
_ = numFromLine(i, b, &availMem)
availMem /= 1000
usedMem = totalMem - freeMem
takenMem = totalMem - availMem
prctMem = takenMem * 100 / totalMem
prctBuff = (usedMem - takenMem) * 100 / totalMem
prctFree = freeMem * 100 / totalMem
}
func findCPUTypeNo(path string, fileName string, comp string) (string, error) {
var b = make([]byte, 100)
var i int = 0
if fileName == "_label" {
i = 1
}
var err error = nil
for ; err == nil && string(b[:len(comp)]) != comp; i++ {
b, err = os.ReadFile(path + string(i+48) + fileName)
}
if err != nil {
return "", err
}
return string(i + 48 - 1), nil
}
func getCPUTemp() {
errFunc := func() string {
cpuTemp = -1
return "Unable to read CPU temperature.\n"
}
var (
b = make([]byte, 2)
thrmPath = "/sys/class/thermal/thermal_zone"
hwMonPath = "/sys/class/hwmon/hwmon"
)
nStr, err := findCPUTypeNo(thrmPath, "/type", "x86_pkg_temp")
if err != nil {
nStr, err = findCPUTypeNo(hwMonPath, "/name", "k10temp")
if errCheck(err, errFunc) {
return
}
nStrHW := nStr
nStr, err = findCPUTypeNo(hwMonPath+nStrHW+"/temp", "_label", "Tdie")
if errCheck(err, errFunc) {
return
}
b, err = os.ReadFile(hwMonPath + nStrHW + "/temp" + nStr + "_input")
} else {
b, err = os.ReadFile(thrmPath + nStr + "/temp")
}
if errCheck(err, errFunc) {
return
}
cpuTemp = (int(b[0])-48)*10 + int(b[1]) - 48
}
func getCPU() {
readStat := func(n *[4]float64) bool {
errFunc := func() string {
cpuLoad = -1
return "Unable to read cpu load.\n"
}
b := make([]byte, 100)
f, err := os.Open("/proc/stat")
if errCheck(err, errFunc) {
return true
}
_, err = f.Read(b)
if errCheck(err, errFunc) {
return true
}
f.Close()
for i, j := 6, 0; j < 4; i++ {
if b[i] >= 48 && b[i] <= 57 {
n[j] = n[j]*10 + float64(b[i]) - 48
} else if b[i] == ' ' {
j++
}
}
return false
}
var a, b [4]float64
if readStat(&a) {
return
}
time.Sleep(1 * time.Second)
if readStat(&b) {
return
}
cpuLoad = int(100 * ((b[0] + b[1] + b[2]) - (a[0] + a[1] + a[2])) / ((b[0] + b[1] + b[2] + b[3]) - (a[0] + a[1] + a[2] + a[3])))
}
func getMHz() {
b, err := os.ReadFile("/proc/cpuinfo")
if errCheck(err, func() string {
cpuMHz = -1
return "Unable to read cpu MHz.\n"
}) {
return
}
var tmp, j int
cpuMHz = 0
for i := 0; i < len(b); i++ {
if string(b[i:i+7]) == "cpu MHz" {
tmp = 0
for ; i < len(b) && b[i] != 10 && b[i] != '.'; i++ {
if b[i] >= 48 && b[i] <= 57 {
tmp = tmp*10 + int(b[i]) - 48
}
}
cpuMHz += tmp
j++
}
}
cpuMHz /= j
}
func round(f float64) string {
var n int = int(f*1000) % 1000
var s string = ""
if n != 0 {
for i := 0; i < 3; i++ {
if n%10 >= 5 {
n += 10
}
n /= 10
}
}
n = int(f) + n
if n == 0 {
return "0"
}
for n > 0 {
s = string(n%10+48) + s
n /= 10
}
return s
}
func printNWithErr(in interface{}) string {
var n float64
switch v := in.(type) {
case int:
n = float64(v)
break
case float64:
n = v
break
default:
return "Err"
}
if n < 0 {
return "Err"
}
return round(n)
}
func main() {
go getMem()
go getCPUTemp()
go getMHz()
getCPU()
println(" Mem: ", printNWithErr(prctMem), "% USED ", printNWithErr(prctBuff), "% BUFF ", printNWithErr(prctFree), "% FREE CPU: ", printNWithErr(cpuLoad), "% ", printNWithErr(cpuTemp), "C ", printNWithErr(cpuMHz), "MHz")
}