From 12c4bb1f520ba13a14e52e730110d11219894972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Fri, 4 Mar 2022 18:42:06 +0200 Subject: [PATCH] [disk][linux] support new stats available with 4.18 and 5.5 kernels https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats --- disk/disk.go | 34 ++++++++++++++++++------------- disk/disk_linux.go | 59 ++++++++++++++++++++++++++++++++++++++++++++---------- disk/disk_test.go | 2 +- 3 files changed, 69 insertions(+), 26 deletions(-) diff --git a/disk/disk.go b/disk/disk.go index dd4cc1d..34ce885 100644 --- a/disk/disk.go +++ b/disk/disk.go @@ -30,20 +30,26 @@ type PartitionStat struct { } type IOCountersStat struct { - ReadCount uint64 `json:"readCount"` - MergedReadCount uint64 `json:"mergedReadCount"` - WriteCount uint64 `json:"writeCount"` - MergedWriteCount uint64 `json:"mergedWriteCount"` - ReadBytes uint64 `json:"readBytes"` - WriteBytes uint64 `json:"writeBytes"` - ReadTime uint64 `json:"readTime"` - WriteTime uint64 `json:"writeTime"` - IopsInProgress uint64 `json:"iopsInProgress"` - IoTime uint64 `json:"ioTime"` - WeightedIO uint64 `json:"weightedIO"` - Name string `json:"name"` - SerialNumber string `json:"serialNumber"` - Label string `json:"label"` + ReadCount uint64 `json:"readCount"` + MergedReadCount uint64 `json:"mergedReadCount"` + WriteCount uint64 `json:"writeCount"` + MergedWriteCount uint64 `json:"mergedWriteCount"` + ReadBytes uint64 `json:"readBytes"` + WriteBytes uint64 `json:"writeBytes"` + ReadTime uint64 `json:"readTime"` + WriteTime uint64 `json:"writeTime"` + IopsInProgress uint64 `json:"iopsInProgress"` + IoTime uint64 `json:"ioTime"` + WeightedIO uint64 `json:"weightedIO"` + DiscardCount uint64 `json:"discardCount"` + MergedDiscardCount uint64 `json:"mergedDiscardCount"` + SectorsDiscardedCount uint64 `json:"sectorsDiscardedCount"` + DiscardTime uint64 `json:"discardTime"` + FlushCount uint64 `json:"flushCount"` + FlushTime uint64 `json:"flushTime"` + Name string `json:"name"` + SerialNumber string `json:"serialNumber"` + Label string `json:"label"` } func (d UsageStat) String() string { diff --git a/disk/disk_linux.go b/disk/disk_linux.go index 5a0cf46..6462155 100644 --- a/disk/disk_linux.go +++ b/disk/disk_linux.go @@ -417,18 +417,55 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC if err != nil { return ret, err } + var discardCount, mergedDiscardCount, sectorsDiscardedCount, discardTime, flushCount, flushTime uint64 + if len(fields) >= 18 { + // kernel 4.18+ + discardCount, err = strconv.ParseUint((fields[14]), 10, 64) + if err != nil { + return ret, err + } + mergedDiscardCount, err = strconv.ParseUint((fields[15]), 10, 64) + if err != nil { + return ret, err + } + sectorsDiscardedCount, err = strconv.ParseUint((fields[16]), 10, 64) + if err != nil { + return ret, err + } + discardTime, err = strconv.ParseUint((fields[17]), 10, 64) + if err != nil { + return ret, err + } + if len(fields) >= 20 { + // kernel 5.5+ + flushCount, err = strconv.ParseUint((fields[18]), 10, 64) + if err != nil { + return ret, err + } + flushTime, err = strconv.ParseUint((fields[19]), 10, 64) + if err != nil { + return ret, err + } + } + } d := IOCountersStat{ - ReadBytes: rbytes * sectorSize, - WriteBytes: wbytes * sectorSize, - ReadCount: reads, - WriteCount: writes, - MergedReadCount: mergedReads, - MergedWriteCount: mergedWrites, - ReadTime: rtime, - WriteTime: wtime, - IopsInProgress: iopsInProgress, - IoTime: iotime, - WeightedIO: weightedIO, + ReadBytes: rbytes * sectorSize, + WriteBytes: wbytes * sectorSize, + ReadCount: reads, + WriteCount: writes, + MergedReadCount: mergedReads, + MergedWriteCount: mergedWrites, + ReadTime: rtime, + WriteTime: wtime, + IopsInProgress: iopsInProgress, + IoTime: iotime, + WeightedIO: weightedIO, + DiscardCount: discardCount, + MergedDiscardCount: mergedDiscardCount, + SectorsDiscardedCount: sectorsDiscardedCount, + DiscardTime: discardTime, + FlushCount: flushCount, + FlushTime: flushTime, } if d == empty { continue diff --git a/disk/disk_test.go b/disk/disk_test.go index 5adae5c..655606c 100644 --- a/disk/disk_test.go +++ b/disk/disk_test.go @@ -125,7 +125,7 @@ func TestDiskIOCountersStat_String(t *testing.T) { WriteBytes: 400, SerialNumber: "SERIAL", } - e := `{"readCount":100,"mergedReadCount":0,"writeCount":200,"mergedWriteCount":0,"readBytes":300,"writeBytes":400,"readTime":0,"writeTime":0,"iopsInProgress":0,"ioTime":0,"weightedIO":0,"name":"sd01","serialNumber":"SERIAL","label":""}` + e := `{"readCount":100,"mergedReadCount":0,"writeCount":200,"mergedWriteCount":0,"readBytes":300,"writeBytes":400,"readTime":0,"writeTime":0,"iopsInProgress":0,"ioTime":0,"weightedIO":0,"discardCount":0,"mergedDiscardCount":0,"sectorsDiscardedCount":0,"discardTime":0,"flushCount":0,"flushTime":0,"name":"sd01","serialNumber":"SERIAL","label":""}` if e != fmt.Sprintf("%v", v) { t.Errorf("DiskUsageStat string is invalid: %v", v) }