mirror of
https://github.com/shirou/gopsutil.git
synced 2025-04-26 13:48:59 +08:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
9f8e8d474b
@ -27,7 +27,6 @@ type TimesStat struct {
|
||||
Steal float64 `json:"steal"`
|
||||
Guest float64 `json:"guest"`
|
||||
GuestNice float64 `json:"guestNice"`
|
||||
Stolen float64 `json:"stolen"`
|
||||
}
|
||||
|
||||
type InfoStat struct {
|
||||
@ -80,7 +79,6 @@ func (c TimesStat) String() string {
|
||||
`"steal":` + strconv.FormatFloat(c.Steal, 'f', 1, 64),
|
||||
`"guest":` + strconv.FormatFloat(c.Guest, 'f', 1, 64),
|
||||
`"guestNice":` + strconv.FormatFloat(c.GuestNice, 'f', 1, 64),
|
||||
`"stolen":` + strconv.FormatFloat(c.Stolen, 'f', 1, 64),
|
||||
}
|
||||
|
||||
return `{` + strings.Join(v, ",") + `}`
|
||||
@ -89,7 +87,7 @@ func (c TimesStat) String() string {
|
||||
// Total returns the total number of seconds in a CPUTimesStat
|
||||
func (c TimesStat) Total() float64 {
|
||||
total := c.User + c.System + c.Nice + c.Iowait + c.Irq + c.Softirq + c.Steal +
|
||||
c.Guest + c.GuestNice + c.Idle + c.Stolen
|
||||
c.Guest + c.GuestNice + c.Idle
|
||||
return total
|
||||
}
|
||||
|
||||
@ -100,7 +98,7 @@ func (c InfoStat) String() string {
|
||||
|
||||
func getAllBusy(t TimesStat) (float64, float64) {
|
||||
busy := t.User + t.System + t.Nice + t.Iowait + t.Irq +
|
||||
t.Softirq + t.Steal + t.Guest + t.GuestNice + t.Stolen
|
||||
t.Softirq + t.Steal + t.Guest + t.GuestNice
|
||||
return busy + t.Idle, busy
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ var cpuTimesSize int
|
||||
var emptyTimes cpuTimes
|
||||
|
||||
func init() {
|
||||
getconf, err := exec.LookPath("/usr/bin/getconf")
|
||||
getconf, err := exec.LookPath("getconf")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ import (
|
||||
var CPUTick = float64(100)
|
||||
|
||||
func init() {
|
||||
getconf, err := exec.LookPath("/usr/bin/getconf")
|
||||
getconf, err := exec.LookPath("getconf")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ var ClocksPerSec = float64(128)
|
||||
|
||||
func init() {
|
||||
func() {
|
||||
getconf, err := exec.LookPath("/usr/bin/getconf")
|
||||
getconf, err := exec.LookPath("getconf")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import (
|
||||
var ClocksPerSec = float64(128)
|
||||
|
||||
func init() {
|
||||
getconf, err := exec.LookPath("/usr/bin/getconf")
|
||||
getconf, err := exec.LookPath("getconf")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -44,7 +44,7 @@ func Info() ([]InfoStat, error) {
|
||||
}
|
||||
|
||||
func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
|
||||
psrInfo, err := exec.LookPath("/usr/sbin/psrinfo")
|
||||
psrInfo, err := exec.LookPath("psrinfo")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot find psrinfo: %s", err)
|
||||
}
|
||||
@ -53,7 +53,7 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
|
||||
return nil, fmt.Errorf("cannot execute psrinfo: %s", err)
|
||||
}
|
||||
|
||||
isaInfo, err := exec.LookPath("/usr/bin/isainfo")
|
||||
isaInfo, err := exec.LookPath("isainfo")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot find isainfo: %s", err)
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ func TestCPUTimeStat_String(t *testing.T) {
|
||||
System: 200.1,
|
||||
Idle: 300.1,
|
||||
}
|
||||
e := `{"cpu":"cpu0","user":100.1,"system":200.1,"idle":300.1,"nice":0.0,"iowait":0.0,"irq":0.0,"softirq":0.0,"steal":0.0,"guest":0.0,"guestNice":0.0,"stolen":0.0}`
|
||||
e := `{"cpu":"cpu0","user":100.1,"system":200.1,"idle":300.1,"nice":0.0,"iowait":0.0,"irq":0.0,"softirq":0.0,"steal":0.0,"guest":0.0,"guestNice":0.0}`
|
||||
if e != fmt.Sprintf("%v", v) {
|
||||
t.Errorf("CPUTimesStat string is invalid: %v", v)
|
||||
}
|
||||
|
@ -279,7 +279,7 @@ func getLSB() (*LSB, error) {
|
||||
}
|
||||
}
|
||||
} else if common.PathExists("/usr/bin/lsb_release") {
|
||||
lsb_release, err := exec.LookPath("/usr/bin/lsb_release")
|
||||
lsb_release, err := exec.LookPath("lsb_release")
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ func InfoWithContext(ctx context.Context) (*InfoStat, error) {
|
||||
result.Hostname = hostname
|
||||
|
||||
// Parse versions from output of `uname(1)`
|
||||
uname, err := exec.LookPath("/usr/bin/uname")
|
||||
uname, err := exec.LookPath("uname")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -85,7 +85,7 @@ func InfoWithContext(ctx context.Context) (*InfoStat, error) {
|
||||
switch result.Platform {
|
||||
case "SmartOS":
|
||||
// If everything works, use the current zone ID as the HostID if present.
|
||||
zonename, err := exec.LookPath("/usr/bin/zonename")
|
||||
zonename, err := exec.LookPath("zonename")
|
||||
if err == nil {
|
||||
out, err := invoke.CommandWithContext(ctx, zonename)
|
||||
if err == nil {
|
||||
@ -112,7 +112,7 @@ func InfoWithContext(ctx context.Context) (*InfoStat, error) {
|
||||
// this point there are no hardware facilities available. This behavior
|
||||
// matches that of other supported OSes.
|
||||
if result.HostID == "" {
|
||||
hostID, err := exec.LookPath("/usr/bin/hostid")
|
||||
hostID, err := exec.LookPath("hostid")
|
||||
if err == nil {
|
||||
out, err := invoke.CommandWithContext(ctx, hostID)
|
||||
if err == nil {
|
||||
@ -151,7 +151,7 @@ func BootTime() (uint64, error) {
|
||||
}
|
||||
|
||||
func BootTimeWithContext(ctx context.Context) (uint64, error) {
|
||||
kstat, err := exec.LookPath("/usr/bin/kstat")
|
||||
kstat, err := exec.LookPath("kstat")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -215,7 +215,7 @@ func KernelVersion() (string, error) {
|
||||
|
||||
func KernelVersionWithContext(ctx context.Context) (string, error) {
|
||||
// Parse versions from output of `uname(1)`
|
||||
uname, err := exec.LookPath("/usr/bin/uname")
|
||||
uname, err := exec.LookPath("uname")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -332,49 +332,6 @@ func HostRun(combineWith ...string) string {
|
||||
return GetEnv("HOST_RUN", "/run", combineWith...)
|
||||
}
|
||||
|
||||
// https://gist.github.com/kylelemons/1525278
|
||||
func Pipeline(cmds ...*exec.Cmd) ([]byte, []byte, error) {
|
||||
// Require at least one command
|
||||
if len(cmds) < 1 {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
// Collect the output from the command(s)
|
||||
var output bytes.Buffer
|
||||
var stderr bytes.Buffer
|
||||
|
||||
last := len(cmds) - 1
|
||||
for i, cmd := range cmds[:last] {
|
||||
var err error
|
||||
// Connect each command's stdin to the previous command's stdout
|
||||
if cmds[i+1].Stdin, err = cmd.StdoutPipe(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// Connect each command's stderr to a buffer
|
||||
cmd.Stderr = &stderr
|
||||
}
|
||||
|
||||
// Connect the output and error for the last command
|
||||
cmds[last].Stdout, cmds[last].Stderr = &output, &stderr
|
||||
|
||||
// Start each command
|
||||
for _, cmd := range cmds {
|
||||
if err := cmd.Start(); err != nil {
|
||||
return output.Bytes(), stderr.Bytes(), err
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for each command to complete
|
||||
for _, cmd := range cmds {
|
||||
if err := cmd.Wait(); err != nil {
|
||||
return output.Bytes(), stderr.Bytes(), err
|
||||
}
|
||||
}
|
||||
|
||||
// Return the pipeline output and the collected standard error
|
||||
return output.Bytes(), stderr.Bytes(), nil
|
||||
}
|
||||
|
||||
// getSysctrlEnv sets LC_ALL=C in a list of env vars for use when running
|
||||
// sysctl commands (see DoSysctrl).
|
||||
func getSysctrlEnv(env []string) []string {
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
func DoSysctrlWithContext(ctx context.Context, mib string) ([]string, error) {
|
||||
sysctl, err := exec.LookPath("/usr/sbin/sysctl")
|
||||
sysctl, err := exec.LookPath("sysctl")
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ func SysctlUint(mib string) (uint64, error) {
|
||||
}
|
||||
|
||||
func DoSysctrl(mib string) ([]string, error) {
|
||||
sysctl, err := exec.LookPath("/sbin/sysctl")
|
||||
sysctl, err := exec.LookPath("sysctl")
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
func DoSysctrl(mib string) ([]string, error) {
|
||||
sysctl, err := exec.LookPath("/sbin/sysctl")
|
||||
sysctl, err := exec.LookPath("sysctl")
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func DoSysctrl(mib string) ([]string, error) {
|
||||
sysctl, err := exec.LookPath("/sbin/sysctl")
|
||||
sysctl, err := exec.LookPath("sysctl")
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ func CallLsofWithContext(ctx context.Context, invoke Invoker, pid int32, args ..
|
||||
}
|
||||
out, err := invoke.CommandWithContext(ctx, lsof, cmd...)
|
||||
if err != nil {
|
||||
// if no pid found, lsof returnes code 1.
|
||||
// if no pid found, lsof returns code 1.
|
||||
if err.Error() == "exit status 1" && len(out) == 0 {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ func (l AvgStat) String() string {
|
||||
}
|
||||
|
||||
type MiscStat struct {
|
||||
ProcsTotal int `json:"procsTotal"`
|
||||
ProcsRunning int `json:"procsRunning"`
|
||||
ProcsBlocked int `json:"procsBlocked"`
|
||||
Ctxt int `json:"ctxt"`
|
||||
|
@ -16,14 +16,11 @@ func Avg() (*AvgStat, error) {
|
||||
}
|
||||
|
||||
func AvgWithContext(ctx context.Context) (*AvgStat, error) {
|
||||
filename := common.HostProc("loadavg")
|
||||
line, err := ioutil.ReadFile(filename)
|
||||
values, err := readLoadAvgFromFile()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
values := strings.Fields(string(line))
|
||||
|
||||
load1, err := strconv.ParseFloat(values[0], 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -83,5 +80,30 @@ func MiscWithContext(ctx context.Context) (*MiscStat, error) {
|
||||
|
||||
}
|
||||
|
||||
procsTotal, err := getProcsTotal()
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
ret.ProcsTotal = int(procsTotal)
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func getProcsTotal() (int64, error) {
|
||||
values, err := readLoadAvgFromFile()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return strconv.ParseInt(strings.Split(values[3], "/")[1], 10, 64)
|
||||
}
|
||||
|
||||
func readLoadAvgFromFile() ([]string, error) {
|
||||
loadavgFilename := common.HostProc("loadavg")
|
||||
line, err := ioutil.ReadFile(loadavgFilename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
values := strings.Fields(string(line))
|
||||
return values, nil
|
||||
}
|
||||
|
@ -46,11 +46,12 @@ func TestMisc(t *testing.T) {
|
||||
|
||||
func TestMiscStatString(t *testing.T) {
|
||||
v := MiscStat{
|
||||
ProcsTotal: 4,
|
||||
ProcsRunning: 1,
|
||||
ProcsBlocked: 2,
|
||||
Ctxt: 3,
|
||||
}
|
||||
e := `{"procsRunning":1,"procsBlocked":2,"ctxt":3}`
|
||||
e := `{"procsTotal":4,"procsRunning":1,"procsBlocked":2,"ctxt":3}`
|
||||
if e != fmt.Sprintf("%v", v) {
|
||||
t.Errorf("TestMiscString string is invalid: %v", v)
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
|
||||
}
|
||||
|
||||
func zoneName() (string, error) {
|
||||
zonename, err := exec.LookPath("/usr/bin/zonename")
|
||||
zonename, err := exec.LookPath("zonename")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -69,7 +69,7 @@ func zoneName() (string, error) {
|
||||
var globalZoneMemoryCapacityMatch = regexp.MustCompile(`memory size: ([\d]+) Megabytes`)
|
||||
|
||||
func globalZoneMemoryCapacity() (uint64, error) {
|
||||
prtconf, err := exec.LookPath("/usr/sbin/prtconf")
|
||||
prtconf, err := exec.LookPath("prtconf")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -96,7 +96,7 @@ func globalZoneMemoryCapacity() (uint64, error) {
|
||||
var kstatMatch = regexp.MustCompile(`([^\s]+)[\s]+([^\s]*)`)
|
||||
|
||||
func nonGlobalZoneMemoryCapacity() (uint64, error) {
|
||||
kstat, err := exec.LookPath("/usr/bin/kstat")
|
||||
kstat, err := exec.LookPath("kstat")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat,
|
||||
retIndex int
|
||||
)
|
||||
|
||||
netstat, err := exec.LookPath("/usr/sbin/netstat")
|
||||
netstat, err := exec.LookPath("netstat")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -204,7 +204,7 @@ func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat,
|
||||
}
|
||||
} else {
|
||||
// duplicated interface, list all interfaces
|
||||
ifconfig, err := exec.LookPath("/sbin/ifconfig")
|
||||
ifconfig, err := exec.LookPath("ifconfig")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ func IOCounters(pernic bool) ([]IOCountersStat, error) {
|
||||
}
|
||||
|
||||
func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) {
|
||||
netstat, err := exec.LookPath("/usr/bin/netstat")
|
||||
netstat, err := exec.LookPath("netstat")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -108,30 +108,21 @@ func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
awk_bin, err := exec.LookPath("awk")
|
||||
out, err := invoke.CommandWithContext(ctx, lsof_bin, "-p", strconv.Itoa(int(p.Pid)), "-Fpfn")
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", fmt.Errorf("bad call to lsof: %s", err)
|
||||
}
|
||||
|
||||
sed_bin, err := exec.LookPath("sed")
|
||||
if err != nil {
|
||||
return "", err
|
||||
txtFound := 0
|
||||
lines := strings.Split(string(out), "\n")
|
||||
for i := 1; i < len(lines); i += 2 {
|
||||
if lines[i] == "ftxt" {
|
||||
txtFound++
|
||||
if txtFound == 2 {
|
||||
return lines[i-1][1:], nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lsof := exec.CommandContext(ctx, lsof_bin, "-p", strconv.Itoa(int(p.Pid)), "-Fpfn")
|
||||
awk := exec.CommandContext(ctx, awk_bin, "NR==5{print}")
|
||||
sed := exec.CommandContext(ctx, sed_bin, "s/n\\//\\//")
|
||||
|
||||
output, _, err := common.Pipeline(lsof, awk, sed)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
ret := strings.TrimSpace(string(output))
|
||||
|
||||
return ret, nil
|
||||
return "", fmt.Errorf("missing txt data returned by lsof")
|
||||
}
|
||||
|
||||
// Cmdline returns the command line arguments of the process as a string with
|
||||
|
Loading…
x
Reference in New Issue
Block a user