mirror of
https://github.com/taigrr/wtf
synced 2025-01-18 04:03:14 -08:00
101 lines
3.9 KiB
Go
101 lines
3.9 KiB
Go
package linux
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// DiskStat is disk statistics to help measure disk activity.
|
|
//
|
|
// Note:
|
|
// * On a very busy or long-lived system values may wrap.
|
|
// * No kernel locks are held while modifying these counters. This implies that
|
|
// minor inaccuracies may occur.
|
|
//
|
|
// More more info see:
|
|
// https://www.kernel.org/doc/Documentation/iostats.txt and
|
|
// https://www.kernel.org/doc/Documentation/block/stat.txt
|
|
type DiskStat struct {
|
|
Major int `json:"major"` // major device number
|
|
Minor int `json:"minor"` // minor device number
|
|
Name string `json:"name"` // device name
|
|
ReadIOs uint64 `json:"read_ios"` // number of read I/Os processed
|
|
ReadMerges uint64 `json:"read_merges"` // number of read I/Os merged with in-queue I/O
|
|
ReadSectors uint64 `json:"read_sectors"` // number of 512 byte sectors read
|
|
ReadTicks uint64 `json:"read_ticks"` // total wait time for read requests in milliseconds
|
|
WriteIOs uint64 `json:"write_ios"` // number of write I/Os processed
|
|
WriteMerges uint64 `json:"write_merges"` // number of write I/Os merged with in-queue I/O
|
|
WriteSectors uint64 `json:"write_sectors"` // number of 512 byte sectors written
|
|
WriteTicks uint64 `json:"write_ticks"` // total wait time for write requests in milliseconds
|
|
InFlight uint64 `json:"in_flight"` // number of I/Os currently in flight
|
|
IOTicks uint64 `json:"io_ticks"` // total time this block device has been active in milliseconds
|
|
TimeInQueue uint64 `json:"time_in_queue"` // total wait time for all requests in milliseconds
|
|
}
|
|
|
|
// ReadDiskStats reads and parses the file.
|
|
//
|
|
// Note:
|
|
// * Assumes a well formed file and will panic if it isn't.
|
|
func ReadDiskStats(path string) ([]DiskStat, error) {
|
|
data, err := ioutil.ReadFile(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
devices := strings.Split(string(data), "\n")
|
|
results := make([]DiskStat, len(devices)-1)
|
|
|
|
for i := range results {
|
|
fields := strings.Fields(devices[i])
|
|
Major, _ := strconv.ParseInt(fields[0], 10, strconv.IntSize)
|
|
results[i].Major = int(Major)
|
|
Minor, _ := strconv.ParseInt(fields[1], 10, strconv.IntSize)
|
|
results[i].Minor = int(Minor)
|
|
results[i].Name = fields[2]
|
|
results[i].ReadIOs, _ = strconv.ParseUint(fields[3], 10, 64)
|
|
results[i].ReadMerges, _ = strconv.ParseUint(fields[4], 10, 64)
|
|
results[i].ReadSectors, _ = strconv.ParseUint(fields[5], 10, 64)
|
|
results[i].ReadTicks, _ = strconv.ParseUint(fields[6], 10, 64)
|
|
results[i].WriteIOs, _ = strconv.ParseUint(fields[7], 10, 64)
|
|
results[i].WriteMerges, _ = strconv.ParseUint(fields[8], 10, 64)
|
|
results[i].WriteSectors, _ = strconv.ParseUint(fields[9], 10, 64)
|
|
results[i].WriteTicks, _ = strconv.ParseUint(fields[10], 10, 64)
|
|
results[i].InFlight, _ = strconv.ParseUint(fields[11], 10, 64)
|
|
results[i].IOTicks, _ = strconv.ParseUint(fields[12], 10, 64)
|
|
results[i].TimeInQueue, _ = strconv.ParseUint(fields[13], 10, 64)
|
|
}
|
|
|
|
return results, nil
|
|
}
|
|
|
|
// GetReadBytes returns the number of bytes read.
|
|
func (ds *DiskStat) GetReadBytes() int64 {
|
|
return int64(ds.ReadSectors) * 512
|
|
}
|
|
|
|
// GetReadTicks returns the duration waited for read requests.
|
|
func (ds *DiskStat) GetReadTicks() time.Duration {
|
|
return time.Duration(ds.ReadTicks) * time.Millisecond
|
|
}
|
|
|
|
// GetWriteBytes returns the number of bytes written.
|
|
func (ds *DiskStat) GetWriteBytes() int64 {
|
|
return int64(ds.WriteSectors) * 512
|
|
}
|
|
|
|
// GetReadTicks returns the duration waited for write requests.
|
|
func (ds *DiskStat) GetWriteTicks() time.Duration {
|
|
return time.Duration(ds.WriteTicks) * time.Millisecond
|
|
}
|
|
|
|
// GetIOTicks returns the duration the disk has been active.
|
|
func (ds *DiskStat) GetIOTicks() time.Duration {
|
|
return time.Duration(ds.IOTicks) * time.Millisecond
|
|
}
|
|
|
|
// GetTimeInQueue returns the duration waited for all requests.
|
|
func (ds *DiskStat) GetTimeInQueue() time.Duration {
|
|
return time.Duration(ds.TimeInQueue) * time.Millisecond
|
|
}
|