Skip to content

Commit f34b623

Browse files
authored
Merge pull request #1314 from chbuescher/master
implemented more AIX no-cgo functions
2 parents f9d3b96 + 3d643b9 commit f34b623

File tree

3 files changed

+186
-17
lines changed

3 files changed

+186
-17
lines changed

cpu/cpu_aix_nocgo.go

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,91 @@ package cpu
55

66
import (
77
"context"
8-
"fmt"
8+
"regexp"
99
"strings"
1010
"strconv"
1111

1212
"github.com/shirou/gopsutil/v3/internal/common"
1313
)
1414

15+
var whiteSpaces = regexp.MustCompile(`\s+`)
16+
1517
func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
16-
return []TimesStat{}, common.ErrNotImplementedError
17-
}
18+
if percpu {
19+
return []TimesStat{}, common.ErrNotImplementedError
20+
} else {
21+
out, err := invoke.CommandWithContext(ctx, "sar", "-u", "10", "1")
22+
if err != nil {
23+
return nil, err
24+
}
25+
lines := strings.Split(string(out), "\n")
26+
if len(lines) < 5 {
27+
return []TimesStat{}, common.ErrNotImplementedError
28+
}
1829

19-
func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
20-
return []InfoStat{}, common.ErrNotImplementedError
30+
ret := TimesStat{CPU: "cpu-total"}
31+
h := whiteSpaces.Split(lines[len(lines)-3], -1) // headers
32+
v := whiteSpaces.Split(lines[len(lines)-2], -1) // values
33+
for i, header := range h {
34+
if t, err := strconv.ParseFloat(v[i], 64); err == nil {
35+
switch header {
36+
case `%usr`:
37+
ret.User = t
38+
case `%sys`:
39+
ret.System = t
40+
case `%wio`:
41+
ret.Iowait = t
42+
case `%idle`:
43+
ret.Idle = t
44+
}
45+
}
46+
}
47+
48+
return []TimesStat{ret}, nil
49+
}
2150
}
2251

23-
func CountsWithContext(ctx context.Context, logical bool) (int, error) {
24-
prtConfOut, err := invoke.CommandWithContext(ctx, "prtconf")
52+
func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
53+
out, err := invoke.CommandWithContext(ctx, "prtconf")
2554
if err != nil {
26-
return 0, fmt.Errorf("cannot execute prtconf: %s", err)
55+
return nil, err
2756
}
28-
for _, line := range strings.Split(string(prtConfOut), "\n") {
29-
parts := strings.Split(line, ": ")
30-
if len(parts) > 1 && parts[0] == "Number Of Processors" {
31-
if ncpu, err := strconv.Atoi(parts[1]); err == nil {
32-
return ncpu, nil
57+
58+
ret := InfoStat{}
59+
for _, line := range strings.Split(string(out), "\n") {
60+
if strings.HasPrefix(line, "Number Of Processors:") {
61+
p := whiteSpaces.Split(line, 4)
62+
if len(p) > 3 {
63+
if t, err := strconv.ParseUint(p[3], 10, 64); err == nil {
64+
ret.Cores = int32(t)
65+
}
66+
}
67+
} else if strings.HasPrefix(line, "Processor Clock Speed:") {
68+
p := whiteSpaces.Split(line, 5)
69+
if len(p) > 4 {
70+
if t, err := strconv.ParseFloat(p[3], 64); err == nil {
71+
switch strings.ToUpper(p[4]) {
72+
case "MHZ":
73+
ret.Mhz = t
74+
case "GHZ":
75+
ret.Mhz = t * 1000.0
76+
case "KHZ":
77+
ret.Mhz = t / 1000.0
78+
default:
79+
ret.Mhz = t
80+
}
81+
}
3382
}
83+
break
3484
}
3585
}
36-
return 0, fmt.Errorf("number of processors not found")
86+
return []InfoStat{ret}, nil
87+
}
88+
89+
func CountsWithContext(ctx context.Context, logical bool) (int, error) {
90+
info, err := InfoWithContext(ctx)
91+
if err == nil {
92+
return int(info[0].Cores), nil
93+
}
94+
return 0, err
3795
}

load/load_aix_nocgo.go

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,62 @@ package load
55

66
import (
77
"context"
8+
"regexp"
9+
"strconv"
10+
"strings"
811

912
"github.com/shirou/gopsutil/v3/internal/common"
1013
)
1114

15+
var separator = regexp.MustCompile(`,?\s+`)
16+
1217
func AvgWithContext(ctx context.Context) (*AvgStat, error) {
18+
line, err := invoke.CommandWithContext(ctx, "uptime")
19+
if err != nil {
20+
return nil, err
21+
}
22+
23+
idx := strings.Index(string(line), "load average:")
24+
if idx < 0 {
25+
return nil, common.ErrNotImplementedError
26+
}
27+
ret := &AvgStat{}
28+
29+
p := separator.Split(string(line[idx:len(line)]), 5)
30+
if 4 < len(p) && p[0] == "load" && p[1] == "average:" {
31+
if t, err := strconv.ParseFloat(p[2], 64); err == nil {
32+
ret.Load1 = t
33+
}
34+
if t, err := strconv.ParseFloat(p[3], 64); err == nil {
35+
ret.Load5 = t
36+
}
37+
if t, err := strconv.ParseFloat(p[4], 64); err == nil {
38+
ret.Load15 = t
39+
}
40+
return ret, nil
41+
}
42+
1343
return nil, common.ErrNotImplementedError
1444
}
1545

1646
func MiscWithContext(ctx context.Context) (*MiscStat, error) {
17-
return nil, common.ErrNotImplementedError
47+
out, err := invoke.CommandWithContext(ctx, "ps", "-Ao", "state")
48+
if err != nil {
49+
return nil, err
50+
}
51+
52+
ret := &MiscStat{}
53+
for _, line := range strings.Split(string(out), "\n") {
54+
ret.ProcsTotal++
55+
switch line {
56+
case "R":
57+
case "A":
58+
ret.ProcsRunning++
59+
case "T":
60+
ret.ProcsBlocked++
61+
default:
62+
continue
63+
}
64+
}
65+
return ret, nil
1866
}

mem/mem_aix_nocgo.go

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,77 @@ package mem
55

66
import (
77
"context"
8+
"regexp"
9+
"strconv"
10+
"strings"
811

912
"github.com/shirou/gopsutil/v3/internal/common"
1013
)
1114

15+
var whiteSpaces = regexp.MustCompile(`\s+`)
16+
1217
func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
13-
return nil, common.ErrNotImplementedError
18+
vmem, swap, err := callSVMon(ctx)
19+
if err != nil {
20+
return nil, err
21+
}
22+
if vmem.Total == 0 {
23+
return nil, common.ErrNotImplementedError
24+
}
25+
vmem.SwapTotal = swap.Total
26+
vmem.SwapFree = swap.Free
27+
return vmem, nil
1428
}
1529

1630
func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
17-
return nil, common.ErrNotImplementedError
31+
_, swap, err := callSVMon(ctx)
32+
if err != nil {
33+
return nil, err
34+
}
35+
if swap.Total == 0 {
36+
return nil, common.ErrNotImplementedError
37+
}
38+
return swap, nil
39+
}
40+
41+
func callSVMon(ctx context.Context) (*VirtualMemoryStat, *SwapMemoryStat, error) {
42+
out, err := invoke.CommandWithContext(ctx, "svmon", "-G")
43+
if err != nil {
44+
return nil, nil, err
45+
}
46+
47+
pagesize := uint64(4096)
48+
vmem := &VirtualMemoryStat{}
49+
swap := &SwapMemoryStat{}
50+
for _, line := range strings.Split(string(out), "\n") {
51+
if strings.HasPrefix(line, "memory") {
52+
p := whiteSpaces.Split(line, 7)
53+
if len(p) > 2 {
54+
if t, err := strconv.ParseUint(p[1], 10, 64); err == nil {
55+
vmem.Total = t * pagesize
56+
}
57+
if t, err := strconv.ParseUint(p[2], 10, 64); err == nil {
58+
vmem.Used = t * pagesize
59+
if vmem.Total > 0 {
60+
vmem.UsedPercent = 100 * float64(vmem.Used) / float64(vmem.Total)
61+
}
62+
}
63+
if t, err := strconv.ParseUint(p[3], 10, 64); err == nil {
64+
vmem.Free = t * pagesize
65+
}
66+
}
67+
} else if strings.HasPrefix(line, "pg space") {
68+
p := whiteSpaces.Split(line, 4)
69+
if len(p) > 3 {
70+
if t, err := strconv.ParseUint(p[2], 10, 64); err == nil {
71+
swap.Total = t * pagesize
72+
}
73+
if t, err := strconv.ParseUint(p[3], 10, 64); err == nil {
74+
swap.Free = swap.Total - t * pagesize
75+
}
76+
}
77+
break
78+
}
79+
}
80+
return vmem, swap, nil
1881
}

0 commit comments

Comments
 (0)