Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 33 additions & 7 deletions cpu.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package systats

import (
"errors"
"regexp"
"strconv"
"strings"
Expand All @@ -12,13 +13,16 @@ import (

// CPU holds information on CPU and CPU usage
type CPU struct {
LoadAvg int `json:"loadAvg"`
CoreAvg []int `json:"coreAvg"`
Model string `json:"model"`
NoOfCores int `json:"noOfCores"`
Freq string `json:"freq"`
Cache string `json:"cache"`
Time int64 `json:"time"`
LoadAvg int `json:"loadAvg"`
CoreAvg []int `json:"coreAvg"`
Load1 float64 `json:"load1"`
Load5 float64 `json:"load5"`
Load15 float64 `json:"load15"`
Model string `json:"model"`
NoOfCores int `json:"noOfCores"`
Freq string `json:"freq"`
Cache string `json:"cache"`
Time int64 `json:"time"`
}

func getCPU(systats *SyStats, milliseconds int) (CPU, error) {
Expand All @@ -43,9 +47,31 @@ func getCPU(systats *SyStats, milliseconds int) (CPU, error) {

processCPUInfoFileContent(&output, &cpuinfoStr)

loadAvgStr, err := fileops.ReadFileWithError(systats.LoadAvgPath)
if err != nil {
return output, err
}
if err := processLoadAvgFileContent(&output, &loadAvgStr); err != nil {
return output, err
}

return output, nil
}

// processLoadAvgFileContent parses /proc/loadavg's 1/5/15-minute load
// averages - the traditional Unix "load average" (uptime/top/w), distinct
// from LoadAvg/CoreAvg above which are CPU utilization percentages.
func processLoadAvgFileContent(output *CPU, content *string) error {
fields := strings.Fields(*content)
if len(fields) < 3 {
return errors.New("unexpected loadavg format")
}
output.Load1 = strops.ToFloat64(fields[0])
output.Load5 = strops.ToFloat64(fields[1])
output.Load15 = strops.ToFloat64(fields[2])
return nil
}

func processCPUInfoFileContent(output *CPU, content *string) {
split := strings.Split(*content, "\n")

Expand Down
2 changes: 2 additions & 0 deletions systats.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type SyStats struct {
EtcPath string
UptimePath string
MountsPath string
LoadAvgPath string
// ProcessCPUMode selects how GetTopProcesses computes CPU usage:
// CPUUsageInstant (default, used when left empty) or CPUUsageAverage.
ProcessCPUMode string
Expand All @@ -44,6 +45,7 @@ func New() SyStats {
EtcPath: "/etc/",
UptimePath: "/proc/uptime",
MountsPath: "/proc/mounts",
LoadAvgPath: "/proc/loadavg",
ProcessCPUMode: CPUUsageInstant,
}
}
Expand Down
16 changes: 16 additions & 0 deletions systats_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ func TestGetCPU(t *testing.T) {
syStats := systats.SyStats{
CPUinfoFilePath: "./test_files/cpuinfo.txt",
StatFilePath: "/proc/stat",
LoadAvgPath: "./test_files/loadavg.txt",
}
cpu, err := syStats.GetCPU()
if err != nil {
Expand All @@ -160,6 +161,21 @@ func TestGetCPU(t *testing.T) {
t.Errorf("Got invalid value. got: %d, want: %d", cpu.NoOfCores, 4)
return
}

if cpu.Load1 != 0.52 {
t.Errorf("Got invalid value. got: %f, want: %f", cpu.Load1, 0.52)
return
}

if cpu.Load5 != 0.58 {
t.Errorf("Got invalid value. got: %f, want: %f", cpu.Load5, 0.58)
return
}

if cpu.Load15 != 0.59 {
t.Errorf("Got invalid value. got: %f, want: %f", cpu.Load15, 0.59)
return
}
}

func TestGetSystem(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions test_files/loadavg.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.52 0.58 0.59 2/391 12345
Loading