diff --git a/README.rst b/README.rst index ad594cf..8d11ae7 100644 --- a/README.rst +++ b/README.rst @@ -186,8 +186,9 @@ threads cpu_percent cpu_affinity memory_percent +parent x x children -connections +connections x x is_running ================ ===== ======= ====== ======= @@ -231,7 +232,6 @@ hostname x x x x - wait_procs - Process class - - parent (use ppid instead) - as_dict - wait diff --git a/common/common_darwin.go b/common/common_darwin.go index cc74601..6cdefb4 100644 --- a/common/common_darwin.go +++ b/common/common_darwin.go @@ -74,6 +74,10 @@ func CallLsof(invoke Invoker, pid int32, args ...string) ([]string, error) { } out, err := invoke.Command(lsof, cmd...) if err != nil { + // if not pid found, lsof returnes code 1 + if err.Error() == "exit status 1" && len(out) == 0 { + return []string{}, nil + } return []string{}, err } lines := strings.Split(string(out), "\n") diff --git a/common/common_linux.go b/common/common_linux.go index 3c760e5..bfd96a9 100644 --- a/common/common_linux.go +++ b/common/common_linux.go @@ -8,6 +8,8 @@ import ( "strings" ) +// CallLsof invokes lsof to get connection informations. +// This is same as darwin currently. func CallLsof(invoke Invoker, pid int32, args ...string) ([]string, error) { var cmd []string if pid == 0 { // will get from all processes. @@ -22,6 +24,10 @@ func CallLsof(invoke Invoker, pid int32, args ...string) ([]string, error) { } out, err := invoke.Command(lsof, cmd...) if err != nil { + // if not pid found, lsof returnes code 1 + if err.Error() == "exit status 1" && len(out) == 0 { + return []string{}, nil + } return []string{}, err } lines := strings.Split(string(out), "\n") diff --git a/net/net_darwin.go b/net/net_darwin.go index da722dc..bcf2915 100644 --- a/net/net_darwin.go +++ b/net/net_darwin.go @@ -91,8 +91,13 @@ func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) { return ret, nil } -// Return a list of network connections opened by a process +// Return a list of network connections opened. func NetConnections(kind string) ([]NetConnectionStat, error) { + return NetConnectionsPid(kind, 0) +} + +// Return a list of network connections opened by a process. +func NetConnectionsPid(kind string, pid int32) ([]NetConnectionStat, error) { var ret []NetConnectionStat args := []string{"-i"} @@ -126,7 +131,7 @@ func NetConnections(kind string) ([]NetConnectionStat, error) { } // we can not use -F filter to get all of required information at once. - r, err := common.CallLsof(invoke, 0, args...) + r, err := common.CallLsof(invoke, pid, args...) if err != nil { return nil, err } diff --git a/net/net_linux.go b/net/net_linux.go index de0d65a..6e54244 100644 --- a/net/net_linux.go +++ b/net/net_linux.go @@ -90,7 +90,13 @@ func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) { return ret, nil } +// Return a list of network connections opened. func NetConnections(kind string) ([]NetConnectionStat, error) { + return NetConnectionsPid(kind, 0) +} + +// Return a list of network connections opened by a process. +func NetConnectionsPid(kind string, pid int32) ([]NetConnectionStat, error) { var ret []NetConnectionStat args := []string{"-i"} @@ -124,7 +130,7 @@ func NetConnections(kind string) ([]NetConnectionStat, error) { } // we can not use -F filter to get all of required information at once. - r, err := common.CallLsof(invoke, 0, args...) + r, err := common.CallLsof(invoke, pid, args...) if err != nil { return nil, err } diff --git a/process/process_darwin.go b/process/process_darwin.go index 634d5cf..dab9f13 100644 --- a/process/process_darwin.go +++ b/process/process_darwin.go @@ -286,7 +286,7 @@ func (p *Process) OpenFiles() ([]OpenFilesStat, error) { } func (p *Process) Connections() ([]net.NetConnectionStat, error) { - return nil, common.NotImplementedError + return net.NetConnectionsPid("all", p.Pid) } func (p *Process) IsRunning() (bool, error) { diff --git a/process/process_linux.go b/process/process_linux.go index 79039bf..e108518 100644 --- a/process/process_linux.go +++ b/process/process_linux.go @@ -211,7 +211,7 @@ func (p *Process) OpenFiles() ([]OpenFilesStat, error) { } func (p *Process) Connections() ([]net.NetConnectionStat, error) { - return nil, common.NotImplementedError + return net.NetConnectionsPid("all", p.Pid) } func (p *Process) IsRunning() (bool, error) { diff --git a/process/process_test.go b/process/process_test.go index dba0ed9..3d6ee34 100644 --- a/process/process_test.go +++ b/process/process_test.go @@ -97,7 +97,7 @@ func Test_Process_MemoryInfo(t *testing.T) { v, err := p.MemoryInfo() if err != nil { - t.Errorf("geting ppid error %v", err) + t.Errorf("geting memory info error %v", err) } empty := MemoryInfoStat{} if v == nil || *v == empty { @@ -110,7 +110,7 @@ func Test_Process_CmdLine(t *testing.T) { v, err := p.Cmdline() if err != nil { - t.Errorf("geting ppid error %v", err) + t.Errorf("geting cmdline error %v", err) } if !strings.Contains(v, "process.test") { t.Errorf("invalid cmd line %v", v) @@ -134,7 +134,7 @@ func Test_Process_Status(t *testing.T) { v, err := p.Status() if err != nil { - t.Errorf("geting ppid error %v", err) + t.Errorf("geting status error %v", err) } if !strings.HasPrefix(v, "S") && v != "running" && v != "sleeping" { t.Errorf("could not get state %v", v) @@ -289,3 +289,18 @@ func Test_Parent(t *testing.T) { t.Fatalf("wrong parent pid") } } + +func Test_Connections(t *testing.T) { + p := testGetProcess() + + c, err := p.Connections() + if err != nil { + t.Fatalf("error %v", err) + } + // TODO: + // Since go test open no conneciton, ret is empty. + // should invoke child process or other solutions. + if len(c) != 0 { + t.Fatalf("wrong connections") + } +}