From e24e72062bbb20b1955d3e9c62f9f94a7b02cd74 Mon Sep 17 00:00:00 2001 From: xca1075 Date: Fri, 3 Jun 2022 17:01:36 +0200 Subject: [PATCH] aix: split code, that uses perfstat, to _cgo and _nocgo files --- cpu/cpu_aix.go | 58 ------------------------------ cpu/cpu_aix_cgo.go | 66 ++++++++++++++++++++++++++++++++++ cpu/cpu_aix_nocgo.go | 36 +++++++++++++++++++ disk/disk_aix.go | 67 ---------------------------------- disk/disk_aix_cgo.go | 76 +++++++++++++++++++++++++++++++++++++++ disk/disk_aix_nocgo.go | 16 +++++++++ load/load_aix.go | 52 --------------------------- load/load_aix_cgo.go | 60 +++++++++++++++++++++++++++++++ load/load_aix_nocgo.go | 16 +++++++++ mem/mem_aix.go | 43 ---------------------- mem/mem_aix_cgo.go | 51 ++++++++++++++++++++++++++ mem/mem_aix_nocgo.go | 16 +++++++++ net/net_aix.go | 27 -------------- net/net_aix_cgo.go | 36 +++++++++++++++++++ net/net_aix_nocgo.go | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++ 15 files changed, 470 insertions(+), 247 deletions(-) create mode 100644 cpu/cpu_aix_cgo.go create mode 100644 cpu/cpu_aix_nocgo.go create mode 100644 disk/disk_aix_cgo.go create mode 100644 disk/disk_aix_nocgo.go create mode 100644 load/load_aix_cgo.go create mode 100644 load/load_aix_nocgo.go create mode 100644 mem/mem_aix_cgo.go create mode 100644 mem/mem_aix_nocgo.go create mode 100644 net/net_aix_cgo.go create mode 100644 net/net_aix_nocgo.go diff --git a/cpu/cpu_aix.go b/cpu/cpu_aix.go index 8f35bdc..1439d1d 100644 --- a/cpu/cpu_aix.go +++ b/cpu/cpu_aix.go @@ -5,70 +5,12 @@ package cpu import ( "context" - - "github.com/power-devops/perfstat" ) func Times(percpu bool) ([]TimesStat, error) { return TimesWithContext(context.Background(), percpu) } -func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { - var ret []TimesStat - if percpu { - cpus, err := perfstat.CpuStat() - if err != nil { - return nil, err - } - for _, c := range cpus { - ct := &TimesStat{ - CPU: c.Name, - Idle: float64(c.Idle), - User: float64(c.User), - System: float64(c.Sys), - Iowait: float64(c.Wait), - } - ret = append(ret, *ct) - } - } else { - c, err := perfstat.CpuUtilTotalStat() - if err != nil { - return nil, err - } - ct := &TimesStat{ - CPU: "cpu-total", - Idle: float64(c.IdlePct), - User: float64(c.UserPct), - System: float64(c.KernPct), - Iowait: float64(c.WaitPct), - } - ret = append(ret, *ct) - } - return ret, nil -} - func Info() ([]InfoStat, error) { return InfoWithContext(context.Background()) } - -func InfoWithContext(ctx context.Context) ([]InfoStat, error) { - c, err := perfstat.CpuTotalStat() - if err != nil { - return nil, err - } - info := InfoStat{ - CPU: 0, - Mhz: float64(c.ProcessorHz / 1000000), - Cores: int32(c.NCpusCfg), - } - result := []InfoStat{info} - return result, nil -} - -func CountsWithContext(ctx context.Context, logical bool) (int, error) { - c, err := perfstat.CpuTotalStat() - if err != nil { - return 0, err - } - return c.NCpusCfg, nil -} diff --git a/cpu/cpu_aix_cgo.go b/cpu/cpu_aix_cgo.go new file mode 100644 index 0000000..4fb504e --- /dev/null +++ b/cpu/cpu_aix_cgo.go @@ -0,0 +1,66 @@ +//go:build aix +// +build aix + +package cpu + +import ( + "context" + + "github.com/power-devops/perfstat" +) + +func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { + var ret []TimesStat + if percpu { + cpus, err := perfstat.CpuStat() + if err != nil { + return nil, err + } + for _, c := range cpus { + ct := &TimesStat{ + CPU: c.Name, + Idle: float64(c.Idle), + User: float64(c.User), + System: float64(c.Sys), + Iowait: float64(c.Wait), + } + ret = append(ret, *ct) + } + } else { + c, err := perfstat.CpuUtilTotalStat() + if err != nil { + return nil, err + } + ct := &TimesStat{ + CPU: "cpu-total", + Idle: float64(c.IdlePct), + User: float64(c.UserPct), + System: float64(c.KernPct), + Iowait: float64(c.WaitPct), + } + ret = append(ret, *ct) + } + return ret, nil +} + +func InfoWithContext(ctx context.Context) ([]InfoStat, error) { + c, err := perfstat.CpuTotalStat() + if err != nil { + return nil, err + } + info := InfoStat{ + CPU: 0, + Mhz: float64(c.ProcessorHz / 1000000), + Cores: int32(c.NCpusCfg), + } + result := []InfoStat{info} + return result, nil +} + +func CountsWithContext(ctx context.Context, logical bool) (int, error) { + c, err := perfstat.CpuTotalStat() + if err != nil { + return 0, err + } + return c.NCpusCfg, nil +} diff --git a/cpu/cpu_aix_nocgo.go b/cpu/cpu_aix_nocgo.go new file mode 100644 index 0000000..afa52f2 --- /dev/null +++ b/cpu/cpu_aix_nocgo.go @@ -0,0 +1,36 @@ +//go:build aix && !cgo +// +build aix,!cgo + +package cpu + +import ( + "context" + "strings" + "strconv" +) + +func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { + return []TimesStat{}, common.ErrNotImplementedError +} + +func InfoWithContext(ctx context.Context) ([]InfoStat, error) { + return []InfoStat{}, common.ErrNotImplementedError +} + +func CountsWithContext(ctx context.Context, logical bool) (int, error) { + prtConfOut, err := invoke.CommandWithContext(ctx, "prtconf") + if err != nil { + return 0, fmt.Errorf("cannot execute prtconf: %s", err) + } + for _, line := range strings.Split(string(prtConfOut), "\n") { + if parts := strings.Split(line, ": "); len(parts) < 2 { + continue + } + if parts[0] == "Number Of Processors" { + if ncpu, err := strconv.Atoi(parts[1]); err == nil { + return ncpu, nil + } + } + } + return 0, fmt.Errorf("number of processors not found") +} diff --git a/disk/disk_aix.go b/disk/disk_aix.go index e37686b..bc71712 100644 --- a/disk/disk_aix.go +++ b/disk/disk_aix.go @@ -5,81 +5,14 @@ package disk import ( "context" - "fmt" - "github.com/power-devops/perfstat" "github.com/shirou/gopsutil/v3/internal/common" ) -var FSType map[int]string - -func init() { - FSType = map[int]string{ - 0: "jfs2", 1: "namefs", 2: "nfs", 3: "jfs", 5: "cdrom", 6: "proc", - 16: "special-fs", 17: "cache-fs", 18: "nfs3", 19: "automount-fs", 20: "pool-fs", 32: "vxfs", - 33: "veritas-fs", 34: "udfs", 35: "nfs4", 36: "nfs4-pseudo", 37: "smbfs", 38: "mcr-pseudofs", - 39: "ahafs", 40: "sterm-nfs", 41: "asmfs", - } -} - -func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { - f, err := perfstat.FileSystemStat() - if err != nil { - return nil, err - } - ret := make([]PartitionStat, len(f)) - - for _, fs := range f { - fstyp, exists := FSType[fs.FSType] - if !exists { - fstyp = "unknown" - } - info := PartitionStat{ - Device: fs.Device, - Mountpoint: fs.MountPoint, - Fstype: fstyp, - } - ret = append(ret, info) - } - - return ret, err -} - func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { return nil, common.ErrNotImplementedError } -func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { - f, err := perfstat.FileSystemStat() - if err != nil { - return nil, err - } - - blocksize := uint64(512) - for _, fs := range f { - if path == fs.MountPoint { - fstyp, exists := FSType[fs.FSType] - if !exists { - fstyp = "unknown" - } - info := UsageStat{ - Path: path, - Fstype: fstyp, - Total: uint64(fs.TotalBlocks) * blocksize, - Free: uint64(fs.FreeBlocks) * blocksize, - Used: uint64(fs.TotalBlocks-fs.FreeBlocks) * blocksize, - InodesTotal: uint64(fs.TotalInodes), - InodesFree: uint64(fs.FreeInodes), - InodesUsed: uint64(fs.TotalInodes - fs.FreeInodes), - } - info.UsedPercent = (float64(info.Used) / float64(info.Total)) * 100.0 - info.InodesUsedPercent = (float64(info.InodesUsed) / float64(info.InodesTotal)) * 100.0 - return &info, nil - } - } - return nil, fmt.Errorf("mountpoint %s not found", path) -} - func SerialNumberWithContext(ctx context.Context, name string) (string, error) { return "", common.ErrNotImplementedError } diff --git a/disk/disk_aix_cgo.go b/disk/disk_aix_cgo.go new file mode 100644 index 0000000..aa534df --- /dev/null +++ b/disk/disk_aix_cgo.go @@ -0,0 +1,76 @@ +//go:build aix && cgo +// +build aix,cgo + +package disk + +import ( + "context" + "fmt" + + "github.com/power-devops/perfstat" +) + +var FSType map[int]string + +func init() { + FSType = map[int]string{ + 0: "jfs2", 1: "namefs", 2: "nfs", 3: "jfs", 5: "cdrom", 6: "proc", + 16: "special-fs", 17: "cache-fs", 18: "nfs3", 19: "automount-fs", 20: "pool-fs", 32: "vxfs", + 33: "veritas-fs", 34: "udfs", 35: "nfs4", 36: "nfs4-pseudo", 37: "smbfs", 38: "mcr-pseudofs", + 39: "ahafs", 40: "sterm-nfs", 41: "asmfs", + } +} + +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { + f, err := perfstat.FileSystemStat() + if err != nil { + return nil, err + } + ret := make([]PartitionStat, len(f)) + + for _, fs := range f { + fstyp, exists := FSType[fs.FSType] + if !exists { + fstyp = "unknown" + } + info := PartitionStat{ + Device: fs.Device, + Mountpoint: fs.MountPoint, + Fstype: fstyp, + } + ret = append(ret, info) + } + + return ret, err +} + +func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { + f, err := perfstat.FileSystemStat() + if err != nil { + return nil, err + } + + blocksize := uint64(512) + for _, fs := range f { + if path == fs.MountPoint { + fstyp, exists := FSType[fs.FSType] + if !exists { + fstyp = "unknown" + } + info := UsageStat{ + Path: path, + Fstype: fstyp, + Total: uint64(fs.TotalBlocks) * blocksize, + Free: uint64(fs.FreeBlocks) * blocksize, + Used: uint64(fs.TotalBlocks-fs.FreeBlocks) * blocksize, + InodesTotal: uint64(fs.TotalInodes), + InodesFree: uint64(fs.FreeInodes), + InodesUsed: uint64(fs.TotalInodes - fs.FreeInodes), + } + info.UsedPercent = (float64(info.Used) / float64(info.Total)) * 100.0 + info.InodesUsedPercent = (float64(info.InodesUsed) / float64(info.InodesTotal)) * 100.0 + return &info, nil + } + } + return nil, fmt.Errorf("mountpoint %s not found", path) +} diff --git a/disk/disk_aix_nocgo.go b/disk/disk_aix_nocgo.go new file mode 100644 index 0000000..b8fe2ee --- /dev/null +++ b/disk/disk_aix_nocgo.go @@ -0,0 +1,16 @@ +//go:build aix && !cgo +// +build aix,!cgo + +package disk + +import ( + "context" +) + +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { + return []PartitionStat{}, common.ErrNotImplementedError +} + +func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { + return nil, common.ErrNotImplementedError +} diff --git a/load/load_aix.go b/load/load_aix.go index e7f9f94..78b3912 100644 --- a/load/load_aix.go +++ b/load/load_aix.go @@ -3,69 +3,17 @@ package load -/* -#cgo LDFLAGS: -L/usr/lib -lperfstat - -#include -#include -*/ -import "C" - import ( "context" - "unsafe" - - "github.com/power-devops/perfstat" ) func Avg() (*AvgStat, error) { return AvgWithContext(context.Background()) } -func AvgWithContext(ctx context.Context) (*AvgStat, error) { - c, err := perfstat.CpuTotalStat() - if err != nil { - return nil, err - } - ret := &AvgStat{ - Load1: float64(c.LoadAvg1), - Load5: float64(c.LoadAvg5), - Load15: float64(c.LoadAvg15), - } - - return ret, nil -} - // Misc returns miscellaneous host-wide statistics. // darwin use ps command to get process running/blocked count. // Almost same as Darwin implementation, but state is different. func Misc() (*MiscStat, error) { return MiscWithContext(context.Background()) } - -func MiscWithContext(ctx context.Context) (*MiscStat, error) { - info := C.struct_procentry64{} - cpid := C.pid_t(0) - - ret := MiscStat{} - for { - // getprocs first argument is a void* - num, err := C.getprocs64(unsafe.Pointer(&info), C.sizeof_struct_procentry64, nil, 0, &cpid, 1) - if err != nil { - return nil, err - } - - ret.ProcsTotal++ - switch info.pi_state { - case C.SACTIVE: - ret.ProcsRunning++ - case C.SSTOP: - ret.ProcsBlocked++ - } - - if num == 0 { - break - } - } - return &ret, nil -} diff --git a/load/load_aix_cgo.go b/load/load_aix_cgo.go new file mode 100644 index 0000000..bbbf287 --- /dev/null +++ b/load/load_aix_cgo.go @@ -0,0 +1,60 @@ +//go:build aix && cgo +// +build aix,cgo + +package load + +/* +#cgo LDFLAGS: -L/usr/lib -lperfstat + +#include +#include +*/ +import "C" + +import ( + "context" + "unsafe" + + "github.com/power-devops/perfstat" +) + +func AvgWithContext(ctx context.Context) (*AvgStat, error) { + c, err := perfstat.CpuTotalStat() + if err != nil { + return nil, err + } + ret := &AvgStat{ + Load1: float64(c.LoadAvg1), + Load5: float64(c.LoadAvg5), + Load15: float64(c.LoadAvg15), + } + + return ret, nil +} + +func MiscWithContext(ctx context.Context) (*MiscStat, error) { + info := C.struct_procentry64{} + cpid := C.pid_t(0) + + ret := MiscStat{} + for { + // getprocs first argument is a void* + num, err := C.getprocs64(unsafe.Pointer(&info), C.sizeof_struct_procentry64, nil, 0, &cpid, 1) + if err != nil { + return nil, err + } + + ret.ProcsTotal++ + switch info.pi_state { + case C.SACTIVE: + ret.ProcsRunning++ + case C.SSTOP: + ret.ProcsBlocked++ + } + + if num == 0 { + break + } + } + return &ret, nil +} diff --git a/load/load_aix_nocgo.go b/load/load_aix_nocgo.go new file mode 100644 index 0000000..f5fbd36 --- /dev/null +++ b/load/load_aix_nocgo.go @@ -0,0 +1,16 @@ +//go:build aix && !cgo +// +build aix,!cgo + +package load + +import ( + "context" +) + +func AvgWithContext(ctx context.Context) (*AvgStat, error) { + return nil, common.ErrNotImplementedError +} + +func MiscWithContext(ctx context.Context) (*MiscStat, error) { + return nil, common.ErrNotImplementedError +} diff --git a/mem/mem_aix.go b/mem/mem_aix.go index 9b2196d..22a6a4e 100644 --- a/mem/mem_aix.go +++ b/mem/mem_aix.go @@ -5,55 +5,12 @@ package mem import ( "context" - - "github.com/power-devops/perfstat" ) func VirtualMemory() (*VirtualMemoryStat, error) { return VirtualMemoryWithContext(context.Background()) } -func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { - m, err := perfstat.MemoryTotalStat() - if err != nil { - return nil, err - } - pagesize := uint64(4096) - ret := VirtualMemoryStat{ - Total: uint64(m.RealTotal) * pagesize, - Available: uint64(m.RealAvailable) * pagesize, - Free: uint64(m.RealFree) * pagesize, - Used: uint64(m.RealInUse) * pagesize, - UsedPercent: 100 * float64(m.RealInUse) / float64(m.RealTotal), - Active: uint64(m.VirtualActive) * pagesize, - SwapTotal: uint64(m.PgSpTotal) * pagesize, - SwapFree: uint64(m.PgSpFree) * pagesize, - } - return &ret, nil -} - func SwapMemory() (*SwapMemoryStat, error) { return SwapMemoryWithContext(context.Background()) } - -func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { - m, err := perfstat.MemoryTotalStat() - if err != nil { - return nil, err - } - pagesize := uint64(4096) - swapUsed := uint64(m.PgSpTotal-m.PgSpFree-m.PgSpRsvd) * pagesize - swapTotal := uint64(m.PgSpTotal) * pagesize - ret := SwapMemoryStat{ - Total: swapTotal, - Free: uint64(m.PgSpFree) * pagesize, - Used: swapUsed, - UsedPercent: float64(100*swapUsed) / float64(swapTotal), - Sin: uint64(m.PgSpIn), - Sout: uint64(m.PgSpOut), - PgIn: uint64(m.PageIn), - PgOut: uint64(m.PageOut), - PgFault: uint64(m.PageFaults), - } - return &ret, nil -} diff --git a/mem/mem_aix_cgo.go b/mem/mem_aix_cgo.go new file mode 100644 index 0000000..67e11df --- /dev/null +++ b/mem/mem_aix_cgo.go @@ -0,0 +1,51 @@ +//go:build aix && cgo +// +build aix,cgo + +package mem + +import ( + "context" + + "github.com/power-devops/perfstat" +) + +func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { + m, err := perfstat.MemoryTotalStat() + if err != nil { + return nil, err + } + pagesize := uint64(4096) + ret := VirtualMemoryStat{ + Total: uint64(m.RealTotal) * pagesize, + Available: uint64(m.RealAvailable) * pagesize, + Free: uint64(m.RealFree) * pagesize, + Used: uint64(m.RealInUse) * pagesize, + UsedPercent: 100 * float64(m.RealInUse) / float64(m.RealTotal), + Active: uint64(m.VirtualActive) * pagesize, + SwapTotal: uint64(m.PgSpTotal) * pagesize, + SwapFree: uint64(m.PgSpFree) * pagesize, + } + return &ret, nil +} + +func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { + m, err := perfstat.MemoryTotalStat() + if err != nil { + return nil, err + } + pagesize := uint64(4096) + swapUsed := uint64(m.PgSpTotal-m.PgSpFree-m.PgSpRsvd) * pagesize + swapTotal := uint64(m.PgSpTotal) * pagesize + ret := SwapMemoryStat{ + Total: swapTotal, + Free: uint64(m.PgSpFree) * pagesize, + Used: swapUsed, + UsedPercent: float64(100*swapUsed) / float64(swapTotal), + Sin: uint64(m.PgSpIn), + Sout: uint64(m.PgSpOut), + PgIn: uint64(m.PageIn), + PgOut: uint64(m.PageOut), + PgFault: uint64(m.PageFaults), + } + return &ret, nil +} diff --git a/mem/mem_aix_nocgo.go b/mem/mem_aix_nocgo.go new file mode 100644 index 0000000..ab86d45 --- /dev/null +++ b/mem/mem_aix_nocgo.go @@ -0,0 +1,16 @@ +//go:build aix && !cgo +// +build aix,!cgo + +package mem + +import ( + "context" +) + +func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { + return nil, common.ErrNotImplementedError +} + +func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { + return nil, common.ErrNotImplementedError +} diff --git a/net/net_aix.go b/net/net_aix.go index 91734a3..81feaa8 100644 --- a/net/net_aix.go +++ b/net/net_aix.go @@ -11,7 +11,6 @@ import ( "strings" "syscall" - "github.com/power-devops/perfstat" "github.com/shirou/gopsutil/v3/internal/common" ) @@ -19,32 +18,6 @@ func IOCounters(pernic bool) ([]IOCountersStat, error) { return IOCountersWithContext(context.Background(), pernic) } -func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { - ifs, err := perfstat.NetIfaceStat() - if err != nil { - return nil, err - } - - iocounters := make([]IOCountersStat, 0, len(ifs)) - for _, netif := range ifs { - n := IOCountersStat{ - Name: netif.Name, - BytesSent: uint64(netif.OBytes), - BytesRecv: uint64(netif.IBytes), - PacketsSent: uint64(netif.OPackets), - PacketsRecv: uint64(netif.IPackets), - Errin: uint64(netif.OErrors), - Errout: uint64(netif.IErrors), - Dropout: uint64(netif.XmitDrops), - } - iocounters = append(iocounters, n) - } - if pernic == false { - return getIOCountersAll(iocounters) - } - return iocounters, nil -} - // IOCountersByFile exists just for compatibility with Linux. func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { return IOCountersByFileWithContext(context.Background(), pernic, filename) diff --git a/net/net_aix_cgo.go b/net/net_aix_cgo.go new file mode 100644 index 0000000..8cf8c91 --- /dev/null +++ b/net/net_aix_cgo.go @@ -0,0 +1,36 @@ +//go:build aix && cgo +// +build aix,cgo + +package net + +import ( + "context" + + "github.com/power-devops/perfstat" +) + +func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { + ifs, err := perfstat.NetIfaceStat() + if err != nil { + return nil, err + } + + iocounters := make([]IOCountersStat, 0, len(ifs)) + for _, netif := range ifs { + n := IOCountersStat{ + Name: netif.Name, + BytesSent: uint64(netif.OBytes), + BytesRecv: uint64(netif.IBytes), + PacketsSent: uint64(netif.OPackets), + PacketsRecv: uint64(netif.IPackets), + Errin: uint64(netif.OErrors), + Errout: uint64(netif.IErrors), + Dropout: uint64(netif.XmitDrops), + } + iocounters = append(iocounters, n) + } + if pernic == false { + return getIOCountersAll(iocounters) + } + return iocounters, nil +} diff --git a/net/net_aix_nocgo.go b/net/net_aix_nocgo.go new file mode 100644 index 0000000..11b6222 --- /dev/null +++ b/net/net_aix_nocgo.go @@ -0,0 +1,97 @@ +//go:build aix && !cgo +// +build aix,!cgo + +package net + +import ( + "context" + "fmt" + "regexp" + "strconv" + "strings" + "syscall" + + "github.com/shirou/gopsutil/v3/internal/common" +) + +func parseNetstatI(output string) ([]IOCountersStat, error) { + lines := strings.Split(string(output), "\n") + ret := make([]IOCountersStat, 0, len(lines)-1) + exists := make([]string, 0, len(ret)) + + // Check first line is header + if len(lines) > 0 && strings.Fields(lines[0])[0] != "Name" { + return nil, fmt.Errorf("not a 'netstat -i' output") + } + + for _, line := range lines[1:] { + values := strings.Fields(line) + if len(values) < 1 || values[0] == "Name" { + continue + } + if common.StringsHas(exists, values[0]) { + // skip if already get + continue + } + exists = append(exists, values[0]) + + if len(values) < 9 { + continue + } + + base := 1 + // sometimes Address is omitted + if len(values) < 10 { + base = 0 + } + + parsed := make([]uint64, 0, 5) + vv := []string{ + values[base+3], // Ipkts == PacketsRecv + values[base+4], // Ierrs == Errin + values[base+5], // Opkts == PacketsSent + values[base+6], // Oerrs == Errout + values[base+8], // Drops == Dropout + } + + for _, target := range vv { + if target == "-" { + parsed = append(parsed, 0) + continue + } + + t, err := strconv.ParseUint(target, 10, 64) + if err != nil { + return nil, err + } + parsed = append(parsed, t) + } + + n := IOCountersStat{ + Name: values[0], + PacketsRecv: parsed[0], + Errin: parsed[1], + PacketsSent: parsed[2], + Errout: parsed[3], + Dropout: parsed[4], + } + ret = append(ret, n) + } + return ret, nil +} + +func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { + out, err := invoke.CommandWithContext(ctx, "netstat", "-idn") + if err != nil { + return nil, err + } + + iocounters, err := parseNetstatI(string(out)) + if err != nil { + return nil, err + } + if pernic == false { + return getIOCountersAll(iocounters) + } + return iocounters, nil +}