Skip to content

Commit

Permalink
✨ Update CPU metrics calculation method and add test
Browse files Browse the repository at this point in the history
The CPU metrics calculation method in cpu.go has been updated with a more accurate method, which involves getting CPU times at the start, waiting for a short interval, then getting CPU times again and calculating the difference. An additional function, totalCPUTime, has been implemented to facilitate this. A new test case for CPU usage calculation has also been added in cpu_test.go.
  • Loading branch information
anxuanzi committed May 11, 2024
1 parent 10953fe commit 57ac882
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 8 deletions.
53 changes: 45 additions & 8 deletions cpu.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,64 @@
package oneuptime_InfrastructureAgent_go

import (
"fmt"
"github.com/gookit/slog"
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/load"
"time"
)

func getCpuMetrics() *CPUMetrics {
avg, err := load.Avg()
//avg, err := load.Avg()
//if err != nil {
// slog.Error(err)
// return nil
//}
//
//numCpu, err := cpu.Counts(true)
//if err != nil {
// slog.Error(err)
// return nil
//}
//
//// Calculate CPU usage, which is the average load over the last minute divided by the number of CPUs
//cpuUsage := (avg.Load1 / float64(numCpu)) * 100

//trying new calculation method, more accurate
// Get CPU times at the start
startTimes, err := cpu.Times(false) // false to get the aggregate of all CPUs
if err != nil {
slog.Error(err)
slog.Error(fmt.Errorf("error fetching initial CPU times: %v", err))
return nil
}

numCpu, err := cpu.Counts(true)
// Wait for a short interval (e.g., 1000 milliseconds)
time.Sleep(1000 * time.Millisecond)

// Get CPU times after the interval
endTimes, err := cpu.Times(false)
if err != nil {
slog.Error(err)
slog.Error(fmt.Errorf("error fetching final CPU times: %v", err))
return nil
}

// Calculate the difference in total and idle times
totalDelta := totalCPUTime(endTimes[0]) - totalCPUTime(startTimes[0])
idleDelta := endTimes[0].Idle - startTimes[0].Idle

// Calculate the CPU usage percentage
if totalDelta == 0 {
slog.Error("totalDelta is 0")
return nil
}
cpuUsagePercent := (1 - idleDelta/totalDelta) * 100

// Calculate CPU usage, which is the average load over the last minute divided by the number of CPUs
cpuUsage := (avg.Load1 / float64(numCpu)) * 100
return &CPUMetrics{
PercentUsed: cpuUsage,
PercentUsed: cpuUsagePercent,
}
}

func totalCPUTime(times cpu.TimesStat) float64 {
return times.User + times.System + times.Idle + times.Nice +
times.Iowait + times.Irq + times.Softirq + times.Steal +
times.Guest + times.GuestNice
}
7 changes: 7 additions & 0 deletions cpu_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package oneuptime_InfrastructureAgent_go

import "testing"

func TestCpu(t *testing.T) {
t.Log("Usage (%): ", getCpuMetrics().PercentUsed)
}

0 comments on commit 57ac882

Please sign in to comment.