first try native CPU implementation

This commit is contained in:
mhsanaei 2025-10-01 20:13:32 +02:00
parent 90c3529301
commit e7cfee570b
No known key found for this signature in database
GPG key ID: D875CD086CF668A0

View file

@ -110,6 +110,7 @@ type ServerService struct {
mu sync.Mutex
lastCPUTimes cpu.TimesStat
hasLastCPUSample bool
hasNativeCPUSample bool
emaCPU float64
cpuHistory []CPUSample
cachedCpuSpeedMhz float64
@ -432,10 +433,15 @@ func (s *ServerService) AppendCpuSample(t time.Time, v float64) {
}
func (s *ServerService) sampleCPUUtilization() (float64, error) {
// Prefer native Windows API to avoid external deps for CPU percent
if runtime.GOOS == "windows" {
// Try native platform-specific CPU implementation first (Windows, Linux, macOS)
if pct, err := sys.CPUPercentRaw(); err == nil {
s.mu.Lock()
// First call to native method returns 0 (initializes baseline)
if !s.hasNativeCPUSample {
s.hasNativeCPUSample = true
s.mu.Unlock()
return 0, nil
}
// Smooth with EMA
const alpha = 0.3
if s.emaCPU == 0 {
@ -448,7 +454,6 @@ func (s *ServerService) sampleCPUUtilization() (float64, error) {
return val, nil
}
// If native call fails, fall back to gopsutil times
}
// Read aggregate CPU times (all CPUs combined)
times, err := cpu.Times(false)
if err != nil {
@ -471,17 +476,16 @@ func (s *ServerService) sampleCPUUtilization() (float64, error) {
}
// Compute busy and total deltas
// Note: Guest and GuestNice times are already included in User and Nice respectively,
// so we exclude them to avoid double-counting (Linux kernel accounting)
idleDelta := cur.Idle - s.lastCPUTimes.Idle
// Sum of busy deltas (exclude Idle)
busyDelta := (cur.User - s.lastCPUTimes.User) +
(cur.System - s.lastCPUTimes.System) +
(cur.Nice - s.lastCPUTimes.Nice) +
(cur.Iowait - s.lastCPUTimes.Iowait) +
(cur.Irq - s.lastCPUTimes.Irq) +
(cur.Softirq - s.lastCPUTimes.Softirq) +
(cur.Steal - s.lastCPUTimes.Steal) +
(cur.Guest - s.lastCPUTimes.Guest) +
(cur.GuestNice - s.lastCPUTimes.GuestNice)
(cur.Steal - s.lastCPUTimes.Steal)
totalDelta := busyDelta + idleDelta