blob: dfac10c4275c5063cb84c5f53ae52ea0a933885d [file] [log] [blame]
Serge Bazanskicc25bdf2018-10-25 14:02:58 +02001// +build freebsd openbsd
2
3package load
4
5import (
6 "context"
7 "os/exec"
8 "strings"
9 "unsafe"
10
11 "golang.org/x/sys/unix"
12)
13
14func Avg() (*AvgStat, error) {
15 return AvgWithContext(context.Background())
16}
17
18func AvgWithContext(ctx context.Context) (*AvgStat, error) {
19 // This SysctlRaw method borrowed from
20 // https://github.com/prometheus/node_exporter/blob/master/collector/loadavg_freebsd.go
21 type loadavg struct {
22 load [3]uint32
23 scale int
24 }
25 b, err := unix.SysctlRaw("vm.loadavg")
26 if err != nil {
27 return nil, err
28 }
29 load := *(*loadavg)(unsafe.Pointer((&b[0])))
30 scale := float64(load.scale)
31 ret := &AvgStat{
32 Load1: float64(load.load[0]) / scale,
33 Load5: float64(load.load[1]) / scale,
34 Load15: float64(load.load[2]) / scale,
35 }
36
37 return ret, nil
38}
39
40// Misc returns miscellaneous host-wide statistics.
41// darwin use ps command to get process running/blocked count.
42// Almost same as Darwin implementation, but state is different.
43func Misc() (*MiscStat, error) {
44 return MiscWithContext(context.Background())
45}
46
47func MiscWithContext(ctx context.Context) (*MiscStat, error) {
48 bin, err := exec.LookPath("ps")
49 if err != nil {
50 return nil, err
51 }
52 out, err := invoke.CommandWithContext(ctx, bin, "axo", "state")
53 if err != nil {
54 return nil, err
55 }
56 lines := strings.Split(string(out), "\n")
57
58 ret := MiscStat{}
59 for _, l := range lines {
60 if strings.Contains(l, "R") {
61 ret.ProcsRunning++
62 } else if strings.Contains(l, "D") {
63 ret.ProcsBlocked++
64 }
65 }
66
67 return &ret, nil
68}