2014-04-18 21:28:00 +09:00
|
|
|
// +build windows
|
|
|
|
|
2014-12-30 22:09:05 +09:00
|
|
|
package load
|
2014-04-18 21:28:00 +09:00
|
|
|
|
2014-11-27 10:18:15 +09:00
|
|
|
import (
|
2017-12-31 15:25:49 +09:00
|
|
|
"context"
|
2020-11-02 16:51:13 +03:00
|
|
|
"log"
|
2020-10-22 17:13:43 +03:00
|
|
|
"sync"
|
|
|
|
"time"
|
2017-12-31 15:25:49 +09:00
|
|
|
|
2020-11-02 16:51:13 +03:00
|
|
|
"github.com/shirou/gopsutil/cpu"
|
2015-10-20 00:04:57 +09:00
|
|
|
"github.com/shirou/gopsutil/internal/common"
|
2014-11-27 10:18:15 +09:00
|
|
|
)
|
|
|
|
|
2020-10-22 17:13:43 +03:00
|
|
|
var (
|
|
|
|
loadErr error
|
|
|
|
loadAvg1M float64 = 0.0
|
|
|
|
loadAvg5M float64 = 0.0
|
|
|
|
loadAvg15M float64 = 0.0
|
|
|
|
loadAvgMutex sync.RWMutex
|
|
|
|
loadAvgGoroutineOnce sync.Once
|
|
|
|
)
|
|
|
|
|
|
|
|
// loadAvgGoroutine updates avg data by fetching current load by interval
|
|
|
|
// TODO register callback rather than this
|
|
|
|
// see https://psutil.readthedocs.io/en/latest/#psutil.getloadavg
|
|
|
|
// code https://github.com/giampaolo/psutil/blob/master/psutil/arch/windows/wmi.c
|
|
|
|
func loadAvgGoroutine() {
|
|
|
|
const (
|
|
|
|
loadAvgFactor1F = 0.9200444146293232478931553241
|
|
|
|
loadAvgFactor5F = 0.9834714538216174894737477501
|
|
|
|
loadAvgFactor15F = 0.9944598480048967508795473394
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2020-11-02 16:51:13 +03:00
|
|
|
sleepInterval time.Duration = 5 * time.Second
|
|
|
|
currentLoad float64
|
2020-10-22 17:13:43 +03:00
|
|
|
)
|
|
|
|
|
2020-11-02 16:51:13 +03:00
|
|
|
counter, err := common.ProcessorQueueLengthCounter()
|
|
|
|
loadErr = err
|
|
|
|
if err != nil || counter == nil {
|
2020-10-22 17:13:43 +03:00
|
|
|
loadAvgMutex.Unlock()
|
2020-11-02 16:51:13 +03:00
|
|
|
log.Println("unexpected processor queue length counter error, please file an issue on github")
|
2020-10-22 17:13:43 +03:00
|
|
|
return
|
|
|
|
}
|
2020-11-02 16:51:13 +03:00
|
|
|
|
2020-10-22 17:13:43 +03:00
|
|
|
for {
|
2020-11-02 16:51:13 +03:00
|
|
|
currentLoad, loadErr = counter.GetValue()
|
|
|
|
if loadErr != nil {
|
|
|
|
goto SKIP
|
2020-10-22 17:13:43 +03:00
|
|
|
}
|
2020-11-02 16:51:13 +03:00
|
|
|
// comment following block if you want load to be 0 as long as process queue is zero
|
|
|
|
{
|
|
|
|
if currentLoad == 0.0 {
|
|
|
|
percent, err := cpu.Percent(0, false)
|
|
|
|
if err == nil {
|
|
|
|
currentLoad = percent[0] / 100
|
|
|
|
// load averages are also given some amount of the currentLoad
|
|
|
|
// maybe they shouldnt?
|
|
|
|
if loadAvg1M == 0 {
|
|
|
|
loadAvg1M = currentLoad
|
|
|
|
}
|
|
|
|
if loadAvg5M == 0 {
|
|
|
|
loadAvg5M = currentLoad / 2
|
|
|
|
}
|
|
|
|
if loadAvg15M == 0 {
|
|
|
|
loadAvg15M = currentLoad / 3
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-10-22 17:13:43 +03:00
|
|
|
}
|
2020-11-02 16:51:13 +03:00
|
|
|
loadAvg1M = loadAvg1M*loadAvgFactor1F + currentLoad*(1.0-loadAvgFactor1F)
|
|
|
|
loadAvg5M = loadAvg5M*loadAvgFactor5F + currentLoad*(1.0-loadAvgFactor5F)
|
|
|
|
loadAvg15M = loadAvg15M*loadAvgFactor15F + currentLoad*(1.0-loadAvgFactor15F)
|
|
|
|
|
|
|
|
SKIP:
|
2020-10-22 17:13:43 +03:00
|
|
|
loadAvgMutex.Unlock()
|
2020-11-02 16:51:13 +03:00
|
|
|
time.Sleep(sleepInterval)
|
|
|
|
loadAvgMutex.Lock()
|
2020-10-22 17:13:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-22 23:09:12 +09:00
|
|
|
func Avg() (*AvgStat, error) {
|
2017-12-31 15:25:49 +09:00
|
|
|
return AvgWithContext(context.Background())
|
|
|
|
}
|
|
|
|
|
|
|
|
func AvgWithContext(ctx context.Context) (*AvgStat, error) {
|
2020-11-02 16:51:13 +03:00
|
|
|
loadAvgGoroutineOnce.Do(func() {
|
|
|
|
loadAvgMutex.Lock()
|
|
|
|
go loadAvgGoroutine()
|
|
|
|
})
|
2020-10-22 17:13:43 +03:00
|
|
|
loadAvgMutex.RLock()
|
|
|
|
defer loadAvgMutex.RUnlock()
|
|
|
|
ret := AvgStat{
|
|
|
|
Load1: loadAvg1M,
|
|
|
|
Load5: loadAvg5M,
|
|
|
|
Load15: loadAvg15M,
|
|
|
|
}
|
2014-04-18 21:28:00 +09:00
|
|
|
|
2020-10-22 17:13:43 +03:00
|
|
|
return &ret, loadErr
|
2014-04-18 21:28:00 +09:00
|
|
|
}
|
2016-02-20 22:52:16 +09:00
|
|
|
|
|
|
|
func Misc() (*MiscStat, error) {
|
2017-12-31 15:25:49 +09:00
|
|
|
return MiscWithContext(context.Background())
|
|
|
|
}
|
|
|
|
|
|
|
|
func MiscWithContext(ctx context.Context) (*MiscStat, error) {
|
2016-02-20 22:52:16 +09:00
|
|
|
ret := MiscStat{}
|
|
|
|
|
2016-04-01 21:34:39 +09:00
|
|
|
return &ret, common.ErrNotImplementedError
|
2016-02-20 22:52:16 +09:00
|
|
|
}
|