github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/client/stats/cpu.go (about) 1 package stats 2 3 import ( 4 "runtime" 5 "time" 6 7 shelpers "github.com/hashicorp/nomad/helper/stats" 8 "github.com/shirou/gopsutil/cpu" 9 ) 10 11 // CpuStats calculates cpu usage percentage 12 type CpuStats struct { 13 prevCpuTime float64 14 prevTime time.Time 15 16 totalCpus int 17 } 18 19 // NewCpuStats returns a cpu stats calculator 20 func NewCpuStats() *CpuStats { 21 numCpus := runtime.NumCPU() 22 cpuStats := &CpuStats{ 23 totalCpus: numCpus, 24 } 25 return cpuStats 26 } 27 28 // Percent calculates the cpu usage percentage based on the current cpu usage 29 // and the previous cpu usage where usage is given as time in nanoseconds spend 30 // in the cpu 31 func (c *CpuStats) Percent(cpuTime float64) float64 { 32 now := time.Now() 33 34 if c.prevCpuTime == 0.0 { 35 // invoked first time 36 c.prevCpuTime = cpuTime 37 c.prevTime = now 38 return 0.0 39 } 40 41 timeDelta := now.Sub(c.prevTime).Nanoseconds() 42 ret := c.calculatePercent(c.prevCpuTime, cpuTime, timeDelta) 43 c.prevCpuTime = cpuTime 44 c.prevTime = now 45 return ret 46 } 47 48 // TicksConsumed calculates the total ticks consumes by the process across all 49 // cpu cores 50 func (c *CpuStats) TicksConsumed(percent float64) float64 { 51 return (percent / 100) * shelpers.TotalTicksAvailable() / float64(c.totalCpus) 52 } 53 54 func (c *CpuStats) calculatePercent(t1, t2 float64, timeDelta int64) float64 { 55 vDelta := t2 - t1 56 if timeDelta <= 0 || vDelta <= 0.0 { 57 return 0.0 58 } 59 60 overall_percent := (vDelta / float64(timeDelta)) * 100.0 61 return overall_percent 62 } 63 64 func (h *HostStatsCollector) collectCPUStats() (cpus []*CPUStats, totalTicks float64, err error) { 65 66 ticksConsumed := 0.0 67 cpuStats, err := cpu.Times(true) 68 if err != nil { 69 return nil, 0.0, err 70 } 71 cs := make([]*CPUStats, len(cpuStats)) 72 for idx, cpuStat := range cpuStats { 73 percentCalculator, ok := h.statsCalculator[cpuStat.CPU] 74 if !ok { 75 percentCalculator = NewHostCpuStatsCalculator() 76 h.statsCalculator[cpuStat.CPU] = percentCalculator 77 } 78 idle, user, system, total := percentCalculator.Calculate(cpuStat) 79 cs[idx] = &CPUStats{ 80 CPU: cpuStat.CPU, 81 User: user, 82 System: system, 83 Idle: idle, 84 Total: total, 85 } 86 ticksConsumed += (total / 100.0) * (shelpers.TotalTicksAvailable() / float64(len(cpuStats))) 87 } 88 89 return cs, ticksConsumed, nil 90 }