| // +build freebsd openbsd |
| |
| package load |
| |
| import ( |
| "context" |
| "os/exec" |
| "strings" |
| "unsafe" |
| |
| "golang.org/x/sys/unix" |
| ) |
| |
| func Avg() (*AvgStat, error) { |
| return AvgWithContext(context.Background()) |
| } |
| |
| func AvgWithContext(ctx context.Context) (*AvgStat, error) { |
| // This SysctlRaw method borrowed from |
| // https://github.com/prometheus/node_exporter/blob/master/collector/loadavg_freebsd.go |
| type loadavg struct { |
| load [3]uint32 |
| scale int |
| } |
| b, err := unix.SysctlRaw("vm.loadavg") |
| if err != nil { |
| return nil, err |
| } |
| load := *(*loadavg)(unsafe.Pointer((&b[0]))) |
| scale := float64(load.scale) |
| ret := &AvgStat{ |
| Load1: float64(load.load[0]) / scale, |
| Load5: float64(load.load[1]) / scale, |
| Load15: float64(load.load[2]) / scale, |
| } |
| |
| 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) { |
| bin, err := exec.LookPath("ps") |
| if err != nil { |
| return nil, err |
| } |
| out, err := invoke.CommandWithContext(ctx, bin, "axo", "state") |
| if err != nil { |
| return nil, err |
| } |
| lines := strings.Split(string(out), "\n") |
| |
| ret := MiscStat{} |
| for _, l := range lines { |
| if strings.Contains(l, "R") { |
| ret.ProcsRunning++ |
| } else if strings.Contains(l, "D") { |
| ret.ProcsBlocked++ |
| } |
| } |
| |
| return &ret, nil |
| } |