package cpu
import (
"context"
"encoding/json"
"fmt"
"math"
"strconv"
"strings"
"sync"
"time"
"github.com/gofiber/fiber/v2/internal/gopsutil/common"
)
type TimesStat struct {
CPU string `json:"cpu"`
User float64 `json:"user"`
System float64 `json:"system"`
Idle float64 `json:"idle"`
Nice float64 `json:"nice"`
Iowait float64 `json:"iowait"`
Irq float64 `json:"irq"`
Softirq float64 `json:"softirq"`
Steal float64 `json:"steal"`
Guest float64 `json:"guest"`
GuestNice float64 `json:"guestNice"`
}
type InfoStat struct {
CPU int32 `json:"cpu"`
VendorID string `json:"vendorId"`
Family string `json:"family"`
Model string `json:"model"`
Stepping int32 `json:"stepping"`
PhysicalID string `json:"physicalId"`
CoreID string `json:"coreId"`
Cores int32 `json:"cores"`
ModelName string `json:"modelName"`
Mhz float64 `json:"mhz"`
CacheSize int32 `json:"cacheSize"`
Flags []string `json:"flags"`
Microcode string `json:"microcode"`
}
type lastPercent struct {
sync .Mutex
lastCPUTimes []TimesStat
lastPerCPUTimes []TimesStat
}
var (
lastCPUPercent lastPercent
invoke common .Invoker = common .Invoke {}
)
func init() {
lastCPUPercent .Lock ()
lastCPUPercent .lastCPUTimes , _ = Times (false )
lastCPUPercent .lastPerCPUTimes , _ = Times (true )
lastCPUPercent .Unlock ()
}
func Counts (logical bool ) (int , error ) {
return CountsWithContext (context .Background (), logical )
}
func (c TimesStat ) String () string {
v := []string {
`"cpu":"` + c .CPU + `"` ,
`"user":` + strconv .FormatFloat (c .User , 'f' , 1 , 64 ),
`"system":` + strconv .FormatFloat (c .System , 'f' , 1 , 64 ),
`"idle":` + strconv .FormatFloat (c .Idle , 'f' , 1 , 64 ),
`"nice":` + strconv .FormatFloat (c .Nice , 'f' , 1 , 64 ),
`"iowait":` + strconv .FormatFloat (c .Iowait , 'f' , 1 , 64 ),
`"irq":` + strconv .FormatFloat (c .Irq , 'f' , 1 , 64 ),
`"softirq":` + strconv .FormatFloat (c .Softirq , 'f' , 1 , 64 ),
`"steal":` + strconv .FormatFloat (c .Steal , 'f' , 1 , 64 ),
`"guest":` + strconv .FormatFloat (c .Guest , 'f' , 1 , 64 ),
`"guestNice":` + strconv .FormatFloat (c .GuestNice , 'f' , 1 , 64 ),
}
return `{` + strings .Join (v , "," ) + `}`
}
func (c TimesStat ) Total () float64 {
total := c .User + c .System + c .Nice + c .Iowait + c .Irq + c .Softirq +
c .Steal + c .Idle
return total
}
func (c InfoStat ) String () string {
s , _ := json .Marshal (c )
return string (s )
}
func getAllBusy(t TimesStat ) (float64 , float64 ) {
busy := t .User + t .System + t .Nice + t .Iowait + t .Irq +
t .Softirq + t .Steal
return busy + t .Idle , busy
}
func calculateBusy(t1 , t2 TimesStat ) float64 {
t1All , t1Busy := getAllBusy (t1 )
t2All , t2Busy := getAllBusy (t2 )
if t2Busy <= t1Busy {
return 0
}
if t2All <= t1All {
return 100
}
return math .Min (100 , math .Max (0 , (t2Busy -t1Busy )/(t2All -t1All )*100 ))
}
func calculateAllBusy(t1 , t2 []TimesStat ) ([]float64 , error ) {
if len (t1 ) != len (t2 ) {
return nil , fmt .Errorf (
"received two CPU counts: %d != %d" ,
len (t1 ), len (t2 ),
)
}
ret := make ([]float64 , len (t1 ))
for i , t := range t2 {
ret [i ] = calculateBusy (t1 [i ], t )
}
return ret , nil
}
func Percent (interval time .Duration , percpu bool ) ([]float64 , error ) {
return PercentWithContext (context .Background (), interval , percpu )
}
func PercentWithContext (ctx context .Context , interval time .Duration , percpu bool ) ([]float64 , error ) {
if interval <= 0 {
return percentUsedFromLastCall (percpu )
}
cpuTimes1 , err := Times (percpu )
if err != nil {
return nil , err
}
if err := common .Sleep (ctx , interval ); err != nil {
return nil , err
}
cpuTimes2 , err := Times (percpu )
if err != nil {
return nil , err
}
return calculateAllBusy (cpuTimes1 , cpuTimes2 )
}
func percentUsedFromLastCall(percpu bool ) ([]float64 , error ) {
cpuTimes , err := Times (percpu )
if err != nil {
return nil , err
}
lastCPUPercent .Lock ()
defer lastCPUPercent .Unlock ()
var lastTimes []TimesStat
if percpu {
lastTimes = lastCPUPercent .lastPerCPUTimes
lastCPUPercent .lastPerCPUTimes = cpuTimes
} else {
lastTimes = lastCPUPercent .lastCPUTimes
lastCPUPercent .lastCPUTimes = cpuTimes
}
if lastTimes == nil {
return nil , fmt .Errorf ("error getting times for cpu percent. lastTimes was nil" )
}
return calculateAllBusy (lastTimes , cpuTimes )
}
The pages are generated with Golds v0.6.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .