Added uptime functionality

This commit is contained in:
lin committed 2026-10-05 22:12:10 +02:00
1 parent 403b621478
commit 6430e5ddca
5 files changed
+125 -2

No files matched your search

+5 -2
View File
@@ -6,6 +6,7 @@ import (
"rpi5-health/internal/http_internal"
"rpi5-health/internal/memory"
"rpi5-health/internal/processor"
"rpi5-health/internal/uptime"
)
func main() {
@@ -22,11 +23,13 @@ func main() {
_, 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)
uptime, _ := uptime.GetUptimeInformation()
log.Printf("Total uptime: %s", uptime.FormatSeconds())
cli.Listen()
}
+50
View File
@@ -0,0 +1,50 @@
//go:build linux
package uptime
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func getLinuxUptime() (UptimeInformation, error) {
uptimeFile, err := os.Open("/proc/uptime")
if err != nil {
return UptimeInformation{}, fmt.Errorf("Could not find /proc/uptime. Are you sure you are on linux?")
}
defer uptimeFile.Close()
fileReader := bufio.NewScanner(uptimeFile)
var busyTime float64
fileReader.Scan()
if fileReader.Err() != nil {
return UptimeInformation{}, fmt.Errorf("Could not read /proc/uptime.")
}
data := fileReader.Text()
/*
* fields[0] Time spent busy/suspended
* fields[1] Time spent idling, it's combined from all CPU cores
*/
fields := strings.Split(data, " ")
busyTime, _ = strconv.ParseFloat(fields[0], 64)
return UptimeInformation{
uptime: busyTime,
}, nil
}
func GetUptimeInformation() (UptimeInformation, error) {
info, err := getLinuxUptime()
if err != nil {
return UptimeInformation{}, fmt.Errorf("Could not read uptime info. Error: %v", err)
}
return info, nil
}
+41
View File
@@ -0,0 +1,41 @@
package uptime
import (
"fmt"
"math"
)
type UptimeInformation struct {
uptime float64
}
func (uptimeInfo UptimeInformation) GetUptime() (seconds float64) {
return uptimeInfo.uptime
}
func (uptimeInfo UptimeInformation) FormatSeconds() string {
total := int64(math.Round(uptimeInfo.uptime))
if total < 60 {
return fmt.Sprintf("%d", total)
}
s := total % 60
m := (total / 60) % 60
if total < 3600 {
// e.g., 5:03
return fmt.Sprintf("%d:%02d", m, s)
}
h := (total / 3600) % 24
if total < 86400 {
// e.g., 2:05:03
return fmt.Sprintf("%d:%02d:%02d", h, m, s)
}
d := total / 86400
// e.g., 1:02:05:03
return fmt.Sprintf("%d:%02d:%02d:%02d", d, h, m, s)
}
+23
View File
@@ -0,0 +1,23 @@
//go:build windows
package uptime
import (
"rpi5-health/internal/windows_system"
"golang.org/x/sys/windows"
)
type ULONGLONG uint64
func getWinUptime(uptime *windows.LazyProc) (UptimeInformation, error) {
uptimeMetric, _, _ := uptime.Call()
uptimeSeconds := float64(uptimeMetric) / 1000.0
return UptimeInformation{uptime: uptimeSeconds}, nil
}
func GetUptimeInformation() (UptimeInformation, error) {
return getWinUptime(windows_system.GetWindowsTools().Uptime)
}
+6
View File
@@ -21,16 +21,22 @@ type WindowsSystemCheckTools struct {
* Windows processor information
*/
SystemTimes *windows.LazyProc
/*
* Windows uptime metrics
*/
Uptime *windows.LazyProc
}
func GetWindowsTools() WindowsSystemCheckTools {
kernel32 := sync.OnceValue(func() *windows.LazyDLL { return windows.NewLazySystemDLL("kernel32.dll") })
procGlobalMemoryStatusEx := sync.OnceValue(func() *windows.LazyProc { return kernel32().NewProc("GlobalMemoryStatusEx") })
systemTimes := sync.OnceValue(func() *windows.LazyProc { return kernel32().NewProc("GetSystemTimes") })
uptime := sync.OnceValue(func() *windows.LazyProc { return kernel32().NewProc("GetTickCount64") })
return WindowsSystemCheckTools{
Kernel32: kernel32(),
ProcGlobalMemoryStatusEx: procGlobalMemoryStatusEx(),
SystemTimes: systemTimes(),
Uptime: uptime(),
}
}