ssh_crawler/stat/disk_io.go
insanity d75e100746 ing
2017-10-25 17:37:32 +09:00

113 lines
2.5 KiB
Go

package stat
import (
"bufio"
"fmt"
"io"
"strings"
"git.loafle.net/overflow/ssh_crawler/util"
"strconv"
)
type DiskIOStat struct {
Device,
ReadCompleted,
ReadMerged,
SectorRead,
TimeSpentReading,
WritesCompleted,
WritesMerged,
SectorsWritten,
TimeSpentWriting,
IoInProg,
TimeSpentIO,
WeightedTimeSpentIO string
}
func (diskio DiskIOStat) Command() string {
return "cat /proc/diskstats"
}
func (diskio DiskIOStat) Read(r io.Reader, keys []string) (interface{}, error) {
var (
stats = []DiskIOStat{}
scanner = bufio.NewScanner(r)
)
for scanner.Scan() {
parts := strings.Fields(scanner.Text())
if len(parts) < 4 {
return nil, fmt.Errorf("invalid line in %s: %s", "/proc/diskstats", scanner.Text())
}
deviceName := parts[2]
if !strings.HasPrefix(deviceName, "sd") {
continue
}
stats = append(stats, DiskIOStat{
Device: deviceName,
ReadCompleted: parts[3],
ReadMerged: parts[4],
SectorRead: parts[5],
TimeSpentReading: parts[6],
WritesCompleted: parts[7],
WritesMerged: parts[8],
SectorsWritten: parts[9],
TimeSpentWriting: parts[10],
IoInProg: parts[11],
TimeSpentIO: parts[12],
WeightedTimeSpentIO: parts[13],
})
}
if keys == nil {
return &stats, nil
}
res, err :=diskio.parse(keys, stats)
if err != nil {
return nil, err
}
return &res, scanner.Err()
}
func (diskio DiskIOStat) parse(keys []string, data []DiskIOStat) (map[string]string, error) {
resMap := make(map[string]string)
for _, key := range keys {
t := strings.Split(key, ".")
suffix := t[len(t)-1]
ext := util.ExtractInBracket(key)
idx, _ := strconv.Atoi(ext)
switch suffix {
case "device":
resMap[key] = data[idx].Device
case "readcnt":
resMap[key] = data[idx].ReadCompleted
case "merged_readcnt":
resMap[key] = data[idx].ReadMerged
case "readbytes":
resMap[key] = util.Float64ToString(util.StringToFloat64(data[idx].SectorRead) * 512)
case "readtime":
resMap[key] = data[idx].TimeSpentReading
case "writecnt":
resMap[key] = data[idx].WritesCompleted
case "merged_writecnt":
resMap[key] = data[idx].WritesMerged
case "writebytes":
resMap[key] = util.Float64ToString(util.StringToFloat64(data[idx].SectorsWritten) * 512)
case "writetime":
resMap[key] = data[idx].TimeSpentWriting
case "iotime":
resMap[key] = data[idx].TimeSpentIO
case "ioweighted":
resMap[key] = data[idx].WeightedTimeSpentIO
default:
}
}
return resMap, nil
}