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 }