aix: split code, that uses perfstat, to _cgo and _nocgo files

pull/1302/head
xca1075 3 years ago
parent ce49e45ed3
commit e24e72062b

@ -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
}

@ -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
}

@ -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")
}

@ -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
}

@ -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)
}

@ -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
}

@ -3,69 +3,17 @@
package load
/*
#cgo LDFLAGS: -L/usr/lib -lperfstat
#include <libperfstat.h>
#include <procinfo.h>
*/
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
}

@ -0,0 +1,60 @@
//go:build aix && cgo
// +build aix,cgo
package load
/*
#cgo LDFLAGS: -L/usr/lib -lperfstat
#include <libperfstat.h>
#include <procinfo.h>
*/
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
}

@ -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
}

@ -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
}

@ -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
}

@ -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
}

@ -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)

@ -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
}

@ -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
}
Loading…
Cancel
Save