Initial import: nasmon health monitor, split out of home_nas
Go service (nasmon/) plus nfpm packaging (packaging/), carried over from the home_nas monorepo. Adds rpm packaging alongside the existing deb build (Fedora/RHEL/Rocky dependency names via nfpm overrides, per-format systemd unit path, dpkg+rpm-compatible maintainer scripts) and a Gitea Actions workflow that builds both formats on every push. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
package collect
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Memory struct {
|
||||
Total uint64 `json:"total"`
|
||||
Available uint64 `json:"available"`
|
||||
Used uint64 `json:"used"` // Total - Available
|
||||
SwapTotal uint64 `json:"swap_total"`
|
||||
SwapUsed uint64 `json:"swap_used"`
|
||||
ARCSize uint64 `json:"arc_size"`
|
||||
ARCMax uint64 `json:"arc_max"`
|
||||
}
|
||||
|
||||
func ReadMemory() (Memory, error) {
|
||||
b, err := os.ReadFile("/proc/meminfo")
|
||||
if err != nil {
|
||||
return Memory{}, err
|
||||
}
|
||||
m := parseMeminfo(b)
|
||||
if ab, err := os.ReadFile("/proc/spl/kstat/zfs/arcstats"); err == nil {
|
||||
m.ARCSize, m.ARCMax = parseArcstats(ab)
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func parseMeminfo(b []byte) Memory {
|
||||
kv := map[string]uint64{}
|
||||
sc := bufio.NewScanner(bytes.NewReader(b))
|
||||
for sc.Scan() {
|
||||
f := strings.Fields(sc.Text())
|
||||
if len(f) < 2 {
|
||||
continue
|
||||
}
|
||||
n, err := strconv.ParseUint(f[1], 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
kv[strings.TrimSuffix(f[0], ":")] = n * 1024
|
||||
}
|
||||
m := Memory{
|
||||
Total: kv["MemTotal"],
|
||||
Available: kv["MemAvailable"],
|
||||
SwapTotal: kv["SwapTotal"],
|
||||
}
|
||||
m.Used = m.Total - m.Available
|
||||
m.SwapUsed = m.SwapTotal - kv["SwapFree"]
|
||||
return m
|
||||
}
|
||||
|
||||
// parseArcstats picks "size" and "c_max" from the kstat table (name type data).
|
||||
func parseArcstats(b []byte) (size, max uint64) {
|
||||
sc := bufio.NewScanner(bytes.NewReader(b))
|
||||
for sc.Scan() {
|
||||
f := strings.Fields(sc.Text())
|
||||
if len(f) != 3 {
|
||||
continue
|
||||
}
|
||||
n, err := strconv.ParseUint(f[2], 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
switch f[0] {
|
||||
case "size":
|
||||
size = n
|
||||
case "c_max":
|
||||
max = n
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user