...

Source file src/github.com/shirou/gopsutil/load/load_linux.go

Documentation: github.com/shirou/gopsutil/load

     1  // +build linux
     2  
     3  package load
     4  
     5  import (
     6  	"context"
     7  	"io/ioutil"
     8  	"strconv"
     9  	"strings"
    10  	"syscall"
    11  
    12  	"github.com/shirou/gopsutil/internal/common"
    13  )
    14  
    15  func Avg() (*AvgStat, error) {
    16  	return AvgWithContext(context.Background())
    17  }
    18  
    19  func AvgWithContext(ctx context.Context) (*AvgStat, error) {
    20  	stat, err := fileAvgWithContext(ctx)
    21  	if err != nil {
    22  		stat, err = sysinfoAvgWithContext(ctx)
    23  	}
    24  	return stat, err
    25  }
    26  
    27  func sysinfoAvgWithContext(ctx context.Context) (*AvgStat, error) {
    28  	var info syscall.Sysinfo_t
    29  	if err := syscall.Sysinfo(&info); err != nil {
    30  		return nil, err
    31  	}
    32  
    33  	const siLoadShift = 16
    34  	return &AvgStat{
    35  		Load1:  float64(info.Loads[0]) / float64(1<<siLoadShift),
    36  		Load5:  float64(info.Loads[1]) / float64(1<<siLoadShift),
    37  		Load15: float64(info.Loads[2]) / float64(1<<siLoadShift),
    38  	}, nil
    39  }
    40  
    41  func fileAvgWithContext(ctx context.Context) (*AvgStat, error) {
    42  	values, err := readLoadAvgFromFile()
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  
    47  	load1, err := strconv.ParseFloat(values[0], 64)
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  	load5, err := strconv.ParseFloat(values[1], 64)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  	load15, err := strconv.ParseFloat(values[2], 64)
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  
    60  	ret := &AvgStat{
    61  		Load1:  load1,
    62  		Load5:  load5,
    63  		Load15: load15,
    64  	}
    65  
    66  	return ret, nil
    67  }
    68  
    69  // Misc returnes miscellaneous host-wide statistics.
    70  // Note: the name should be changed near future.
    71  func Misc() (*MiscStat, error) {
    72  	return MiscWithContext(context.Background())
    73  }
    74  
    75  func MiscWithContext(ctx context.Context) (*MiscStat, error) {
    76  	filename := common.HostProc("stat")
    77  	out, err := ioutil.ReadFile(filename)
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  
    82  	ret := &MiscStat{}
    83  	lines := strings.Split(string(out), "\n")
    84  	for _, line := range lines {
    85  		fields := strings.Fields(line)
    86  		if len(fields) != 2 {
    87  			continue
    88  		}
    89  		v, err := strconv.ParseInt(fields[1], 10, 64)
    90  		if err != nil {
    91  			continue
    92  		}
    93  		switch fields[0] {
    94  		case "processes":
    95  			ret.ProcsCreated = int(v)
    96  		case "procs_running":
    97  			ret.ProcsRunning = int(v)
    98  		case "procs_blocked":
    99  			ret.ProcsBlocked = int(v)
   100  		case "ctxt":
   101  			ret.Ctxt = int(v)
   102  		default:
   103  			continue
   104  		}
   105  	}
   106  
   107  	procsTotal, err := getProcsTotal()
   108  	if err != nil {
   109  		return ret, err
   110  	}
   111  	ret.ProcsTotal = int(procsTotal)
   112  
   113  	return ret, nil
   114  }
   115  
   116  func getProcsTotal() (int64, error) {
   117  	values, err := readLoadAvgFromFile()
   118  	if err != nil {
   119  		return 0, err
   120  	}
   121  	return strconv.ParseInt(strings.Split(values[3], "/")[1], 10, 64)
   122  }
   123  
   124  func readLoadAvgFromFile() ([]string, error) {
   125  	loadavgFilename := common.HostProc("loadavg")
   126  	line, err := ioutil.ReadFile(loadavgFilename)
   127  	if err != nil {
   128  		return nil, err
   129  	}
   130  
   131  	values := strings.Fields(string(line))
   132  	return values, nil
   133  }
   134  

View as plain text