Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormhsanaei <ho3ein.sanaei@gmail.com>2025-10-01 21:13:32 +0300
committermhsanaei <ho3ein.sanaei@gmail.com>2025-10-01 21:13:32 +0300
commite7cfee570bb7e35ccebdaf2527c4bba30e7eee5a (patch)
treea35b2cc2b9b65d94587c34027a88e1e80622310b /web/service
parent90c3529301e1528b91346a1493a079deb6cb80e7 (diff)
first try native CPU implementation
Diffstat (limited to 'web/service')
-rw-r--r--web/service/server.go40
1 files changed, 22 insertions, 18 deletions
diff --git a/web/service/server.go b/web/service/server.go
index 45a76f86..eb261c88 100644
--- a/web/service/server.go
+++ b/web/service/server.go
@@ -110,6 +110,7 @@ type ServerService struct {
mu sync.Mutex
lastCPUTimes cpu.TimesStat
hasLastCPUSample bool
+ hasNativeCPUSample bool
emaCPU float64
cpuHistory []CPUSample
cachedCpuSpeedMhz float64
@@ -432,23 +433,27 @@ 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" {
- if pct, err := sys.CPUPercentRaw(); err == nil {
- s.mu.Lock()
- // Smooth with EMA
- const alpha = 0.3
- if s.emaCPU == 0 {
- s.emaCPU = pct
- } else {
- s.emaCPU = alpha*pct + (1-alpha)*s.emaCPU
- }
- val := s.emaCPU
+ // 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 val, nil
+ return 0, nil
}
- // If native call fails, fall back to gopsutil times
+ // Smooth with EMA
+ const alpha = 0.3
+ if s.emaCPU == 0 {
+ s.emaCPU = pct
+ } else {
+ s.emaCPU = alpha*pct + (1-alpha)*s.emaCPU
+ }
+ val := s.emaCPU
+ s.mu.Unlock()
+ 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