load_bsd.go 1.5 KB

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