...
1
2
3 package load
4
5 import (
6 "context"
7 "log"
8 "math"
9 "sync"
10 "time"
11
12 "github.com/shirou/gopsutil/internal/common"
13 )
14
15 var (
16 loadErr error
17 loadAvg1M float64 = 0.0
18 loadAvg5M float64 = 0.0
19 loadAvg15M float64 = 0.0
20 loadAvgMutex sync.RWMutex
21 loadAvgGoroutineOnce sync.Once
22 )
23
24
25
26
27
28 func loadAvgGoroutine() {
29 var (
30 samplingFrequency time.Duration = 5 * time.Second
31 loadAvgFactor1M float64 = 1 / math.Exp(samplingFrequency.Seconds()/time.Minute.Seconds())
32 loadAvgFactor5M float64 = 1 / math.Exp(samplingFrequency.Seconds()/(5*time.Minute).Seconds())
33 loadAvgFactor15M float64 = 1 / math.Exp(samplingFrequency.Seconds()/(15*time.Minute).Seconds())
34 currentLoad float64
35 )
36
37 counter, err := common.ProcessorQueueLengthCounter()
38 if err != nil || counter == nil {
39 log.Println("gopsutil: unexpected processor queue length counter error, please file an issue on github: err")
40 return
41 }
42
43 tick := time.NewTicker(samplingFrequency).C
44 for {
45 currentLoad, err = counter.GetValue()
46 loadAvgMutex.Lock()
47 loadErr = err
48 loadAvg1M = loadAvg1M*loadAvgFactor1M + currentLoad*(1-loadAvgFactor1M)
49 loadAvg5M = loadAvg5M*loadAvgFactor5M + currentLoad*(1-loadAvgFactor5M)
50 loadAvg15M = loadAvg15M*loadAvgFactor15M + currentLoad*(1-loadAvgFactor15M)
51 loadAvgMutex.Unlock()
52 <-tick
53 }
54 }
55
56
57 func Avg() (*AvgStat, error) {
58 return AvgWithContext(context.Background())
59 }
60
61 func AvgWithContext(ctx context.Context) (*AvgStat, error) {
62 loadAvgGoroutineOnce.Do(func() {
63 go loadAvgGoroutine()
64 })
65 loadAvgMutex.RLock()
66 defer loadAvgMutex.RUnlock()
67 ret := AvgStat{
68 Load1: loadAvg1M,
69 Load5: loadAvg5M,
70 Load15: loadAvg15M,
71 }
72
73 return &ret, loadErr
74 }
75
76 func Misc() (*MiscStat, error) {
77 return MiscWithContext(context.Background())
78 }
79
80 func MiscWithContext(ctx context.Context) (*MiscStat, error) {
81 ret := MiscStat{}
82
83 return &ret, common.ErrNotImplementedError
84 }
85
View as plain text