forked from elastic/beats
-
Notifications
You must be signed in to change notification settings - Fork 0
/
diskstat_linux.go
97 lines (81 loc) · 2.79 KB
/
diskstat_linux.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
// +build linux
package diskio
import (
"github.com/pkg/errors"
"github.com/shirou/gopsutil/disk"
"github.com/elastic/beats/metricbeat/module/system"
)
func Get_CLK_TCK() uint32 {
//return uint32(C.sysconf(C._SC_CLK_TCK))
//NOTE: _SC_CLK_TCK should be fetched from sysconf using cgo
return uint32(100)
}
func NewDiskIOStat() *DiskIOStat {
d := &DiskIOStat{}
d.lastDiskIOCounters = make(map[string]disk.IOCountersStat)
return d
}
// create current cpu sampling
// need call as soon as get IOCounters
func (stat *DiskIOStat) OpenSampling() error {
return stat.curCpu.Get()
}
func (stat *DiskIOStat) CalIOStatistics(counter disk.IOCountersStat) (DiskIOMetric, error) {
var last disk.IOCountersStat
var ok bool
var result DiskIOMetric
// if last counter not found, create one and return all 0
if last, ok = stat.lastDiskIOCounters[counter.Name]; !ok {
stat.lastDiskIOCounters[counter.Name] = counter
return result, nil
}
// calculate the delta ms between the CloseSampling and OpenSampling
deltams := 1000.0 * float64(stat.curCpu.Total()-stat.lastCpu.Total()) / float64(system.NumCPU) / float64(Get_CLK_TCK())
if deltams <= 0 {
return result, errors.New("The delta cpu time between close sampling and open sampling is less or equal to 0")
}
rd_ios := counter.ReadCount - last.ReadCount
rd_merges := counter.MergedReadCount - last.MergedReadCount
rd_bytes := counter.ReadBytes - last.ReadBytes
rd_ticks := counter.ReadTime - last.ReadTime
wr_ios := counter.WriteCount - last.WriteCount
wr_merges := counter.MergedWriteCount - last.MergedWriteCount
wr_bytes := counter.WriteBytes - last.WriteBytes
wr_ticks := counter.WriteTime - last.WriteTime
ticks := counter.IoTime - last.IoTime
aveq := counter.WeightedIO - last.WeightedIO
n_ios := rd_ios + wr_ios
n_ticks := rd_ticks + wr_ticks
n_bytes := rd_bytes + wr_bytes
size := float64(0)
wait := float64(0)
svct := float64(0)
if n_ios > 0 {
size = float64(n_bytes) / float64(n_ios)
wait = float64(n_ticks) / float64(n_ios)
svct = float64(ticks) / float64(n_ios)
}
queue := float64(aveq) / deltams
per_sec := func(x uint64) float64 {
return 1000.0 * float64(x) / deltams
}
result.ReadRequestMergeCountPerSec = per_sec(rd_merges)
result.WriteRequestMergeCountPerSec = per_sec(wr_merges)
result.ReadRequestCountPerSec = per_sec(rd_ios)
result.WriteRequestCountPerSec = per_sec(wr_ios)
result.ReadBytesPerSec = per_sec(rd_bytes)
result.WriteBytesPerSec = per_sec(wr_bytes)
result.AvgRequestSize = size
result.AvgQueueSize = queue
result.AvgAwaitTime = wait
result.AvgServiceTime = svct
result.BusyPct = 100.0 * float64(ticks) / deltams
if result.BusyPct > 100.0 {
result.BusyPct = 100.0
}
stat.lastDiskIOCounters[counter.Name] = counter
return result, nil
}
func (stat *DiskIOStat) CloseSampling() {
stat.lastCpu = stat.curCpu
}