Testing for linux cpuinfo
This commit is contained in:
1 parent
cbc9e4a0b4
commit
ea5e79a46a
8 files changed
+172
-20
No files matched your search
+11
-2
@@ -4,14 +4,15 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"rpi5-health/internal/cli"
|
"rpi5-health/internal/cli"
|
||||||
"rpi5-health/internal/http_internal"
|
"rpi5-health/internal/http_internal"
|
||||||
"rpi5-health/internal/system_check"
|
"rpi5-health/internal/memory"
|
||||||
|
"rpi5-health/internal/processor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
srv := http_internal.NewAppServer()
|
srv := http_internal.NewAppServer()
|
||||||
go srv.Start()
|
go srv.Start()
|
||||||
|
|
||||||
memInfo, _ := system_check.GetRamInformation()
|
memInfo, _ := memory.GetRamInformation()
|
||||||
|
|
||||||
const GB = 1024 * 1024 * 1024
|
const GB = 1024 * 1024 * 1024
|
||||||
|
|
||||||
@@ -19,5 +20,13 @@ func main() {
|
|||||||
log.Printf("Available memory: %.2fGB\n", float64(memInfo.AvailableMemory)/GB)
|
log.Printf("Available memory: %.2fGB\n", float64(memInfo.AvailableMemory)/GB)
|
||||||
log.Printf("Used memory: %.2fGB\n", float64(memInfo.GetUsedMemory())/GB)
|
log.Printf("Used memory: %.2fGB\n", float64(memInfo.GetUsedMemory())/GB)
|
||||||
|
|
||||||
|
_, kernel, usage, idle := processor.GetCPUInformation().Usage()
|
||||||
|
|
||||||
|
const HOUR = 60 * 60
|
||||||
|
|
||||||
|
log.Printf("Total time spent idling: %.2f%%\n", idle)
|
||||||
|
log.Printf("Total time spent in kernel mode: %.2f%%\n", kernel)
|
||||||
|
log.Printf("Total time spent in user mode: %.2f%%\n", usage)
|
||||||
|
|
||||||
cli.Listen()
|
cli.Listen()
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
//go:build linux
|
//go:build linux
|
||||||
|
|
||||||
package system_check
|
package memory
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package system_check
|
package memory
|
||||||
|
|
||||||
type MemoryInformation struct {
|
type MemoryInformation struct {
|
||||||
/*
|
/*
|
||||||
@@ -1,29 +1,34 @@
|
|||||||
//go:build windows
|
//go:build windows
|
||||||
|
|
||||||
package system_check
|
package memory
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"rpi5-health/internal/windows_system"
|
||||||
|
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type DWORD uint32
|
||||||
|
type DWORDLONG uint64
|
||||||
|
|
||||||
type memoryStatusEx struct {
|
type memoryStatusEx struct {
|
||||||
/*
|
/*
|
||||||
* Struct for storing memory status information.
|
* Struct for storing memory status information.
|
||||||
*
|
*
|
||||||
* It gets populated via syscall.
|
* It gets populated via syscall.
|
||||||
*/
|
*/
|
||||||
dwLength uint32
|
dwLength DWORD
|
||||||
dwMemoryLoad uint32
|
dwMemoryLoad DWORD
|
||||||
ullTotalPhys uint64
|
ullTotalPhys DWORDLONG
|
||||||
ullAvailPhys uint64
|
ullAvailPhys DWORDLONG
|
||||||
ullTotalPageFile uint64
|
ullTotalPageFile DWORDLONG
|
||||||
ullAvailPageFile uint64
|
ullAvailPageFile DWORDLONG
|
||||||
ullTotalVirtual uint64
|
ullTotalVirtual DWORDLONG
|
||||||
ullAvailVirtual uint64
|
ullAvailVirtual DWORDLONG
|
||||||
ullAvailExtendedVirtual uint64
|
ullAvailExtendedVirtual DWORDLONG
|
||||||
}
|
}
|
||||||
|
|
||||||
func getWinRamInfo(procGlobalMemoryStatusEx *windows.LazyProc) MemoryInformation {
|
func getWinRamInfo(procGlobalMemoryStatusEx *windows.LazyProc) MemoryInformation {
|
||||||
@@ -31,7 +36,7 @@ func getWinRamInfo(procGlobalMemoryStatusEx *windows.LazyProc) MemoryInformation
|
|||||||
|
|
||||||
// * Windows requires the dwLength field to be set to the struct's size
|
// * Windows requires the dwLength field to be set to the struct's size
|
||||||
// * before execution so it knows which OS struct version is being used.
|
// * before execution so it knows which OS struct version is being used.
|
||||||
mem.dwLength = uint32(unsafe.Sizeof(mem))
|
mem.dwLength = DWORD(unsafe.Sizeof(mem))
|
||||||
|
|
||||||
ret, _, err := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&mem))) // exec syscall
|
ret, _, err := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&mem))) // exec syscall
|
||||||
|
|
||||||
@@ -40,11 +45,11 @@ func getWinRamInfo(procGlobalMemoryStatusEx *windows.LazyProc) MemoryInformation
|
|||||||
}
|
}
|
||||||
|
|
||||||
return MemoryInformation{
|
return MemoryInformation{
|
||||||
SystemMemory: mem.ullTotalPhys,
|
SystemMemory: uint64(mem.ullTotalPhys),
|
||||||
AvailableMemory: mem.ullAvailPhys,
|
AvailableMemory: uint64(mem.ullAvailPhys),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetRamInformation() (MemoryInformation, error) {
|
func GetRamInformation() (MemoryInformation, error) {
|
||||||
return getWinRamInfo(getWindowsTools().ProcGlobalMemoryStatusEx), nil
|
return getWinRamInfo(windows_system.GetWindowsTools().ProcGlobalMemoryStatusEx), nil
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package processor
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type ProcessorInformation struct {
|
||||||
|
IdleTimeSinceBoot uint64
|
||||||
|
KernelTimeSinceBoot uint64
|
||||||
|
UserTimeSinceBoot uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (procInfo ProcessorInformation) Usage() (
|
||||||
|
TotalCPUUsage float64,
|
||||||
|
KernelCPUUsage float64,
|
||||||
|
UserCPUUsage float64,
|
||||||
|
IdleCPUUsage float64,
|
||||||
|
) {
|
||||||
|
first := GetCPUInformation()
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
second := GetCPUInformation()
|
||||||
|
|
||||||
|
deltaIdleTime := second.IdleTimeSinceBoot - first.IdleTimeSinceBoot
|
||||||
|
deltaKernelTime := second.KernelTimeSinceBoot - first.KernelTimeSinceBoot
|
||||||
|
deltaUserTime := second.UserTimeSinceBoot - first.UserTimeSinceBoot
|
||||||
|
deltaTotalTime := deltaIdleTime + deltaKernelTime + deltaUserTime
|
||||||
|
|
||||||
|
if deltaTotalTime > 0 {
|
||||||
|
TotalCPUUsage = ((float64(deltaKernelTime) + float64(deltaUserTime)) / float64(deltaTotalTime)) * 100
|
||||||
|
UserCPUUsage = (float64(deltaUserTime) / float64(deltaTotalTime)) * 100
|
||||||
|
KernelCPUUsage = (float64(deltaKernelTime) / float64(deltaTotalTime)) * 100
|
||||||
|
IdleCPUUsage = (float64(deltaIdleTime) / float64(deltaTotalTime)) * 100
|
||||||
|
}
|
||||||
|
|
||||||
|
return TotalCPUUsage, KernelCPUUsage, UserCPUUsage, IdleCPUUsage
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
//go:build linux
|
||||||
|
|
||||||
|
package processor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var numberRegex *regexp.Regexp = regexp.MustCompile(`\d+`)
|
||||||
|
|
||||||
|
func getLinuxCpuInfo() (ProcessorInformation, error) {
|
||||||
|
procFile, err := os.Open("/proc/meminfo")
|
||||||
|
if err != nil {
|
||||||
|
return ProcessorInformation{}, fmt.Errorf("Could not find /proc/meminfo. Are you sure you are on linux?")
|
||||||
|
}
|
||||||
|
defer procFile.Close()
|
||||||
|
|
||||||
|
fileReader := bufio.NewScanner(procFile)
|
||||||
|
|
||||||
|
//var idleTime uint64
|
||||||
|
//var kernelTime uint64
|
||||||
|
//var userTime uint64
|
||||||
|
|
||||||
|
for fileReader.Scan() {
|
||||||
|
line := fileReader.Text()
|
||||||
|
|
||||||
|
if strings.HasPrefix(line, "cpu ") {
|
||||||
|
fields := strings.Split(line, " ")
|
||||||
|
for _, field := range fields {
|
||||||
|
fmt.Print(field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ProcessorInformation{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCPUInformation() ProcessorInformation {
|
||||||
|
info, err := getLinuxCpuInfo()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Could not read processor info. Error: %v", err)
|
||||||
|
return ProcessorInformation{}
|
||||||
|
}
|
||||||
|
return info
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package processor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"rpi5-health/internal/windows_system"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DWORD uint32
|
||||||
|
|
||||||
|
type PFILETIME struct {
|
||||||
|
dwLowDateTime DWORD
|
||||||
|
dwHighDateTime DWORD
|
||||||
|
}
|
||||||
|
|
||||||
|
func getWinCpuInfo(getSystemTimes *windows.LazyProc) ProcessorInformation {
|
||||||
|
var lpIdleTime PFILETIME
|
||||||
|
var lpKernelTime PFILETIME
|
||||||
|
var lpUserTime PFILETIME
|
||||||
|
|
||||||
|
getSystemTimes.Call(
|
||||||
|
uintptr(unsafe.Pointer(&lpIdleTime)),
|
||||||
|
uintptr(unsafe.Pointer(&lpKernelTime)),
|
||||||
|
uintptr(unsafe.Pointer(&lpUserTime)),
|
||||||
|
)
|
||||||
|
|
||||||
|
timeSpentIdlingTicks := fileTimeToTicks(lpIdleTime)
|
||||||
|
timeSpentByKernelTicks := fileTimeToTicks(lpKernelTime) - timeSpentIdlingTicks // kernel time includes idling by default
|
||||||
|
timeSpentByUserTicks := fileTimeToTicks(lpUserTime)
|
||||||
|
|
||||||
|
return ProcessorInformation{
|
||||||
|
IdleTimeSinceBoot: timeSpentIdlingTicks,
|
||||||
|
KernelTimeSinceBoot: timeSpentByKernelTicks,
|
||||||
|
UserTimeSinceBoot: timeSpentByUserTicks,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func fileTimeToTicks(filetime PFILETIME) uint64 {
|
||||||
|
// 100 nanosecond intervals since 1601, january 1
|
||||||
|
return (uint64(filetime.dwHighDateTime) << 32) | uint64(filetime.dwLowDateTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCPUInformation() ProcessorInformation {
|
||||||
|
return getWinCpuInfo(windows_system.GetWindowsTools().SystemTimes)
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
//go:build windows
|
//go:build windows
|
||||||
|
|
||||||
package system_check
|
package windows_system
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
@@ -17,14 +17,20 @@ type WindowsSystemCheckTools struct {
|
|||||||
* Windows memory information
|
* Windows memory information
|
||||||
*/
|
*/
|
||||||
ProcGlobalMemoryStatusEx *windows.LazyProc
|
ProcGlobalMemoryStatusEx *windows.LazyProc
|
||||||
|
/*
|
||||||
|
* Windows processor information
|
||||||
|
*/
|
||||||
|
SystemTimes *windows.LazyProc
|
||||||
}
|
}
|
||||||
|
|
||||||
func getWindowsTools() WindowsSystemCheckTools {
|
func GetWindowsTools() WindowsSystemCheckTools {
|
||||||
kernel32 := sync.OnceValue(func() *windows.LazyDLL { return windows.NewLazySystemDLL("kernel32.dll") })
|
kernel32 := sync.OnceValue(func() *windows.LazyDLL { return windows.NewLazySystemDLL("kernel32.dll") })
|
||||||
procGlobalMemoryStatusEx := sync.OnceValue(func() *windows.LazyProc { return kernel32().NewProc("GlobalMemoryStatusEx") })
|
procGlobalMemoryStatusEx := sync.OnceValue(func() *windows.LazyProc { return kernel32().NewProc("GlobalMemoryStatusEx") })
|
||||||
|
systemTimes := sync.OnceValue(func() *windows.LazyProc { return kernel32().NewProc("GetSystemTimes") })
|
||||||
|
|
||||||
return WindowsSystemCheckTools{
|
return WindowsSystemCheckTools{
|
||||||
Kernel32: kernel32(),
|
Kernel32: kernel32(),
|
||||||
ProcGlobalMemoryStatusEx: procGlobalMemoryStatusEx(),
|
ProcGlobalMemoryStatusEx: procGlobalMemoryStatusEx(),
|
||||||
|
SystemTimes: systemTimes(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user