package agent import ( "bytes" "os/exec" "runtime" "strconv" "golang.org/x/sys/unix" ) // cpuPercent sums the per-process CPU shares ps reports. macOS exposes the // host CPU ticks only through Mach calls, which need cgo. func cpuPercent() (float64, error) { out, err := exec.Command("/bin/ps", "-A", "-o", "%cpu=").Output() if err != nil { return 0, err } var sum float64 for _, f := range bytes.Fields(out) { // Some locales print a decimal comma. v, _ := strconv.ParseFloat(string(bytes.Replace(f, []byte(","), []byte("."), 1)), 64) sum += v } return clampPercent(sum / float64(runtime.NumCPU())), nil } // memUsage takes the kernel's own share of memory still available // (kern.memorystatus_level, what `memory_pressure` prints). func memUsage() (total, used uint64, err error) { total, err = unix.SysctlUint64("hw.memsize") if err != nil { return 0, 0, err } level, err := unix.SysctlUint32("kern.memorystatus_level") if err != nil { return 0, 0, err } if level > 100 { level = 100 } return total, total / 100 * uint64(100-level), nil }