package resources import ( "time" "github.com/shirou/gopsutil/cpu" "github.com/shirou/gopsutil/load" ) type HostCPUStatesPct cpu.TimesStat type HostCPUTimesStatWrap struct { CPUTimesStats []cpu.TimesStat Ts int64 } func GetHostCPUCount() (int, error) { return cpu.Counts(true) } func GetHostCPULoad() (*load.AvgStat, error) { return load.Avg() } // GetHostCPUUsage calc now and last call within gopsutil/cpu func GetHostCPUUsage() (float64, error) { return GetHostCPUUsageWithInterval(0) } // GetHostCPUUsageWithInterval if d is 0, calc now and last call within gopsutil/cpu. // if d is not 0, calc two call that need sleep within gopsutil/cpu. func GetHostCPUUsageWithInterval(d time.Duration) (float64, error) { var total float64 usages, err := cpu.Percent(d, false) if err != nil { return total, err } for _, usage := range usages { total += usage } return total, nil } func GetHostCPUStatesWithInterval(d time.Duration) ([]HostCPUStatesPct, error) { states := make([]HostCPUStatesPct, 0) pre, err := cpu.Times(false) if err != nil { return states, err } preWrap := HostCPUTimesStatWrap{CPUTimesStats: pre, Ts: time.Now().Unix()} time.Sleep(d) now, err := cpu.Times(false) if err != nil { return states, err } nowWrap := HostCPUTimesStatWrap{CPUTimesStats: now, Ts: time.Now().Unix()} return calculateCPUStates(&preWrap, &nowWrap), nil } func GetHostCPUStatesWithPre(preWrap *HostCPUTimesStatWrap) ( []HostCPUStatesPct, *HostCPUTimesStatWrap, error) { states := make([]HostCPUStatesPct, 0) now, err := cpu.Times(false) if err != nil { return states, nil, err } nowWrap := HostCPUTimesStatWrap{CPUTimesStats: now, Ts: time.Now().Unix()} if preWrap == nil { return calculateCPUStates(&nowWrap, &nowWrap), &nowWrap, nil } return calculateCPUStates(preWrap, &nowWrap), &nowWrap, nil } func calculateCPUStates(preWrap, nowWrap *HostCPUTimesStatWrap) []HostCPUStatesPct { states := make([]HostCPUStatesPct, 0) duration := nowWrap.Ts - preWrap.Ts for _, now := range nowWrap.CPUTimesStats { state := HostCPUStatesPct{ CPU: now.CPU, } for _, pre := range preWrap.CPUTimesStats { if pre.CPU == now.CPU { state.User = calcPct(pre.User, now.User, float64(duration)) state.System = calcPct(pre.System, now.System, float64(duration)) state.Nice = calcPct(pre.Nice, now.Nice, float64(duration)) state.Idle = calcPct(pre.Idle, now.Idle, float64(duration)) state.Iowait = calcPct(pre.Iowait, now.Iowait, float64(duration)) state.Irq = calcPct(pre.Irq, now.Irq, float64(duration)) state.Softirq = calcPct(pre.Softirq, now.Softirq, float64(duration)) state.Steal = calcPct(pre.Steal, now.Steal, float64(duration)) state.Guest = calcPct(pre.Guest, now.Guest, float64(duration)) state.GuestNice = calcPct(pre.GuestNice, now.GuestNice, float64(duration)) break } } states = append(states, state) } return states } func calcPct(pre, now, second float64) float64 { diff := now - pre if diff > 0 && second > 0 { return (diff / second) * 100 } return 0 }