mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2026-04-22 23:57:20 +08:00
0b80fa53cf
- implement getSystemInfo to gather CPU and memory usage - add platform-specific implementations for memory and CPU usage - enhance OpenAPI documentation to include system resource metrics
105 lines
2.1 KiB
Go
105 lines
2.1 KiB
Go
//go:build darwin
|
|
|
|
package api
|
|
|
|
import (
|
|
"os/exec"
|
|
"runtime"
|
|
"strconv"
|
|
"strings"
|
|
"syscall"
|
|
"unsafe"
|
|
)
|
|
|
|
func getMemoryInfo() (total, used uint64) {
|
|
total = sysctl64("hw.memsize")
|
|
if total == 0 {
|
|
return 0, 0
|
|
}
|
|
|
|
pageSize, err := syscall.SysctlUint32("hw.pagesize")
|
|
if err != nil {
|
|
return total, 0
|
|
}
|
|
|
|
freeCount, _ := syscall.SysctlUint32("vm.page_free_count")
|
|
purgeableCount, _ := syscall.SysctlUint32("vm.page_purgeable_count")
|
|
speculativeCount, _ := syscall.SysctlUint32("vm.page_speculative_count")
|
|
|
|
// inactive pages not available via sysctl, parse vm_stat
|
|
inactiveCount := vmStatPages("Pages inactive")
|
|
|
|
available := uint64(freeCount+purgeableCount+speculativeCount)*uint64(pageSize) +
|
|
inactiveCount*uint64(pageSize)
|
|
if available > total {
|
|
return total, 0
|
|
}
|
|
return total, total - available
|
|
}
|
|
|
|
// vmStatPages parses vm_stat output for a specific counter
|
|
func vmStatPages(key string) uint64 {
|
|
out, err := exec.Command("vm_stat").Output()
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
for _, line := range strings.Split(string(out), "\n") {
|
|
if strings.HasPrefix(line, key) {
|
|
// format: "Pages inactive: 479321."
|
|
parts := strings.Split(line, ":")
|
|
if len(parts) < 2 {
|
|
continue
|
|
}
|
|
s := strings.TrimSpace(parts[1])
|
|
s = strings.TrimSuffix(s, ".")
|
|
val, err := strconv.ParseUint(s, 10, 64)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
return val
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func sysctl64(name string) uint64 {
|
|
s, err := syscall.Sysctl(name)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
b := []byte(s)
|
|
for len(b) < 8 {
|
|
b = append(b, 0)
|
|
}
|
|
return *(*uint64)(unsafe.Pointer(&b[0]))
|
|
}
|
|
|
|
func getCPUUsage() float64 {
|
|
s, err := syscall.Sysctl("vm.loadavg")
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
|
|
raw := []byte(s)
|
|
for len(raw) < 24 {
|
|
raw = append(raw, 0)
|
|
}
|
|
|
|
// struct loadavg { fixpt_t ldavg[3]; long fscale; }
|
|
ldavg0 := *(*uint32)(unsafe.Pointer(&raw[0]))
|
|
fscale := *(*int64)(unsafe.Pointer(&raw[16]))
|
|
|
|
if fscale == 0 {
|
|
return 0
|
|
}
|
|
|
|
load1 := float64(ldavg0) / float64(fscale)
|
|
numCPU := float64(runtime.NumCPU())
|
|
|
|
usage := load1 / numCPU * 100
|
|
if usage > 100 {
|
|
usage = 100
|
|
}
|
|
return usage
|
|
}
|