github.com/gofiber/fiber/v2@v2.47.0/internal/gopsutil/load/load_bsd.go (about)

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