forked from elastic/beats
-
Notifications
You must be signed in to change notification settings - Fork 0
/
helper.go
108 lines (89 loc) · 2.74 KB
/
helper.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package diskio
import (
"time"
"github.com/elastic/beats/metricbeat/module/docker"
dc "github.com/fsouza/go-dockerclient"
)
type BlkioStats struct {
Time time.Time
Container *docker.Container
reads float64
writes float64
totals float64
}
type BlkioCalculator interface {
getReadPs(old *BlkioRaw, new *BlkioRaw) float64
getWritePs(old *BlkioRaw, new *BlkioRaw) float64
getTotalPs(old *BlkioRaw, new *BlkioRaw) float64
}
type BlkioRaw struct {
Time time.Time
reads uint64
writes uint64
totals uint64
}
type BLkioService struct {
BlkioSTatsPerContainer map[string]BlkioRaw
}
func (io *BLkioService) getBlkioStatsList(rawStats []docker.Stat) []BlkioStats {
formattedStats := []BlkioStats{}
if io.BlkioSTatsPerContainer == nil {
io.BlkioSTatsPerContainer = make(map[string]BlkioRaw)
}
for _, myRawStats := range rawStats {
formattedStats = append(formattedStats, io.getBlkioStats(&myRawStats))
}
return formattedStats
}
func (io *BLkioService) getBlkioStats(myRawStat *docker.Stat) BlkioStats {
newBlkioStats := io.getNewStats(myRawStat.Stats.Read, myRawStat.Stats.BlkioStats.IOServicedRecursive)
oldBlkioStats, exist := io.BlkioSTatsPerContainer[myRawStat.Container.ID]
myBlkioStats := BlkioStats{
Time: myRawStat.Stats.Read,
Container: docker.NewContainer(&myRawStat.Container),
}
if exist {
myBlkioStats.reads = io.getReadPs(&oldBlkioStats, &newBlkioStats)
myBlkioStats.writes = io.getWritePs(&oldBlkioStats, &newBlkioStats)
myBlkioStats.totals = io.getTotalPs(&oldBlkioStats, &newBlkioStats)
}
io.BlkioSTatsPerContainer[myRawStat.Container.ID] = newBlkioStats
return myBlkioStats
}
func (io *BLkioService) getNewStats(time time.Time, blkioEntry []dc.BlkioStatsEntry) BlkioRaw {
stats := BlkioRaw{
Time: time,
reads: 0,
writes: 0,
totals: 0,
}
for _, myEntry := range blkioEntry {
if myEntry.Op == "Write" {
stats.writes = myEntry.Value
} else if myEntry.Op == "Read" {
stats.reads = myEntry.Value
} else if myEntry.Op == "Total" {
stats.totals = myEntry.Value
}
}
return stats
}
func (io *BLkioService) getReadPs(old *BlkioRaw, new *BlkioRaw) float64 {
duration := new.Time.Sub(old.Time)
return calculatePerSecond(duration, old.reads, new.reads)
}
func (io *BLkioService) getWritePs(old *BlkioRaw, new *BlkioRaw) float64 {
duration := new.Time.Sub(old.Time)
return calculatePerSecond(duration, old.writes, new.writes)
}
func (io *BLkioService) getTotalPs(old *BlkioRaw, new *BlkioRaw) float64 {
duration := new.Time.Sub(old.Time)
return calculatePerSecond(duration, old.totals, new.totals)
}
func calculatePerSecond(duration time.Duration, old uint64, new uint64) float64 {
value := float64(new) - float64(old)
if value < 0 {
value = 0
}
return value / duration.Seconds()
}