Vendor psutils and remove neko
This commit is contained in:
137
plugins/system/ps/net/net.go
Normal file
137
plugins/system/ps/net/net.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net"
|
||||
)
|
||||
|
||||
type NetIOCountersStat struct {
|
||||
Name string `json:"name"` // interface name
|
||||
BytesSent uint64 `json:"bytes_sent"` // number of bytes sent
|
||||
BytesRecv uint64 `json:"bytes_recv"` // number of bytes received
|
||||
PacketsSent uint64 `json:"packets_sent"` // number of packets sent
|
||||
PacketsRecv uint64 `json:"packets_recv"` // number of packets received
|
||||
Errin uint64 `json:"errin"` // total number of errors while receiving
|
||||
Errout uint64 `json:"errout"` // total number of errors while sending
|
||||
Dropin uint64 `json:"dropin"` // total number of incoming packets which were dropped
|
||||
Dropout uint64 `json:"dropout"` // total number of outgoing packets which were dropped (always 0 on OSX and BSD)
|
||||
}
|
||||
|
||||
// Addr is implemented compatibility to psutil
|
||||
type Addr struct {
|
||||
IP string `json:"ip"`
|
||||
Port uint32 `json:"port"`
|
||||
}
|
||||
|
||||
type NetConnectionStat struct {
|
||||
Fd uint32 `json:"fd"`
|
||||
Family uint32 `json:"family"`
|
||||
Type uint32 `json:"type"`
|
||||
Laddr Addr `json:"localaddr"`
|
||||
Raddr Addr `json:"remoteaddr"`
|
||||
Status string `json:"status"`
|
||||
Pid int32 `json:"pid"`
|
||||
}
|
||||
|
||||
// NetInterfaceAddr is designed for represent interface addresses
|
||||
type NetInterfaceAddr struct {
|
||||
Addr string `json:"addr"`
|
||||
}
|
||||
|
||||
type NetInterfaceStat struct {
|
||||
MTU int `json:"mtu"` // maximum transmission unit
|
||||
Name string `json:"name"` // e.g., "en0", "lo0", "eth0.100"
|
||||
HardwareAddr string `json:"hardwareaddr"` // IEEE MAC-48, EUI-48 and EUI-64 form
|
||||
Flags []string `json:"flags"` // e.g., FlagUp, FlagLoopback, FlagMulticast
|
||||
Addrs []NetInterfaceAddr `json:"addrs"`
|
||||
}
|
||||
|
||||
func (n NetIOCountersStat) String() string {
|
||||
s, _ := json.Marshal(n)
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func (n NetConnectionStat) String() string {
|
||||
s, _ := json.Marshal(n)
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func (a Addr) String() string {
|
||||
s, _ := json.Marshal(a)
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func (n NetInterfaceStat) String() string {
|
||||
s, _ := json.Marshal(n)
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func (n NetInterfaceAddr) String() string {
|
||||
s, _ := json.Marshal(n)
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func NetInterfaces() ([]NetInterfaceStat, error) {
|
||||
is, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := make([]NetInterfaceStat, 0, len(is))
|
||||
for _, ifi := range is {
|
||||
|
||||
var flags []string
|
||||
if ifi.Flags&net.FlagUp != 0 {
|
||||
flags = append(flags, "up")
|
||||
}
|
||||
if ifi.Flags&net.FlagBroadcast != 0 {
|
||||
flags = append(flags, "broadcast")
|
||||
}
|
||||
if ifi.Flags&net.FlagLoopback != 0 {
|
||||
flags = append(flags, "loopback")
|
||||
}
|
||||
if ifi.Flags&net.FlagPointToPoint != 0 {
|
||||
flags = append(flags, "pointtopoint")
|
||||
}
|
||||
if ifi.Flags&net.FlagMulticast != 0 {
|
||||
flags = append(flags, "multicast")
|
||||
}
|
||||
|
||||
r := NetInterfaceStat{
|
||||
Name: ifi.Name,
|
||||
MTU: ifi.MTU,
|
||||
HardwareAddr: ifi.HardwareAddr.String(),
|
||||
Flags: flags,
|
||||
}
|
||||
addrs, err := ifi.Addrs()
|
||||
if err == nil {
|
||||
r.Addrs = make([]NetInterfaceAddr, 0, len(addrs))
|
||||
for _, addr := range addrs {
|
||||
r.Addrs = append(r.Addrs, NetInterfaceAddr{
|
||||
Addr: addr.String(),
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
ret = append(ret, r)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func getNetIOCountersAll(n []NetIOCountersStat) ([]NetIOCountersStat, error) {
|
||||
r := NetIOCountersStat{
|
||||
Name: "all",
|
||||
}
|
||||
for _, nic := range n {
|
||||
r.BytesRecv += nic.BytesRecv
|
||||
r.PacketsRecv += nic.PacketsRecv
|
||||
r.Errin += nic.Errin
|
||||
r.Dropin += nic.Dropin
|
||||
r.BytesSent += nic.BytesSent
|
||||
r.PacketsSent += nic.PacketsSent
|
||||
r.Errout += nic.Errout
|
||||
r.Dropout += nic.Dropout
|
||||
}
|
||||
|
||||
return []NetIOCountersStat{r}, nil
|
||||
}
|
||||
74
plugins/system/ps/net/net_darwin.go
Normal file
74
plugins/system/ps/net/net_darwin.go
Normal file
@@ -0,0 +1,74 @@
|
||||
// +build darwin
|
||||
|
||||
package net
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/shirou/gopsutil/common"
|
||||
)
|
||||
|
||||
func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
|
||||
out, err := exec.Command("/usr/sbin/netstat", "-ibdn").Output()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lines := strings.Split(string(out), "\n")
|
||||
ret := make([]NetIOCountersStat, 0, len(lines)-1)
|
||||
exists := make([]string, 0, len(ret))
|
||||
|
||||
for _, line := range lines {
|
||||
values := strings.Fields(line)
|
||||
if len(values) < 1 || values[0] == "Name" {
|
||||
// skip first line
|
||||
continue
|
||||
}
|
||||
if common.StringContains(exists, values[0]) {
|
||||
// skip if already get
|
||||
continue
|
||||
}
|
||||
exists = append(exists, values[0])
|
||||
|
||||
base := 1
|
||||
// sometimes Address is ommitted
|
||||
if len(values) < 11 {
|
||||
base = 0
|
||||
}
|
||||
|
||||
parsed := make([]uint64, 0, 3)
|
||||
vv := []string{
|
||||
values[base+3], // PacketsRecv
|
||||
values[base+4], // Errin
|
||||
values[base+5], // Dropin
|
||||
}
|
||||
for _, target := range vv {
|
||||
if target == "-" {
|
||||
parsed = append(parsed, 0)
|
||||
continue
|
||||
}
|
||||
|
||||
t, err := strconv.ParseUint(target, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
parsed = append(parsed, t)
|
||||
}
|
||||
|
||||
n := NetIOCountersStat{
|
||||
Name: values[0],
|
||||
PacketsRecv: parsed[0],
|
||||
Errin: parsed[1],
|
||||
Dropin: parsed[2],
|
||||
}
|
||||
ret = append(ret, n)
|
||||
}
|
||||
|
||||
if pernic == false {
|
||||
return getNetIOCountersAll(ret)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
83
plugins/system/ps/net/net_freebsd.go
Normal file
83
plugins/system/ps/net/net_freebsd.go
Normal file
@@ -0,0 +1,83 @@
|
||||
// +build freebsd
|
||||
|
||||
package net
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/shirou/gopsutil/common"
|
||||
)
|
||||
|
||||
func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
|
||||
out, err := exec.Command("/usr/bin/netstat", "-ibdn").Output()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lines := strings.Split(string(out), "\n")
|
||||
ret := make([]NetIOCountersStat, 0, len(lines)-1)
|
||||
exists := make([]string, 0, len(ret))
|
||||
|
||||
for _, line := range lines {
|
||||
values := strings.Fields(line)
|
||||
if len(values) < 1 || values[0] == "Name" {
|
||||
continue
|
||||
}
|
||||
if common.StringContains(exists, values[0]) {
|
||||
// skip if already get
|
||||
continue
|
||||
}
|
||||
exists = append(exists, values[0])
|
||||
|
||||
base := 1
|
||||
// sometimes Address is ommitted
|
||||
if len(values) < 13 {
|
||||
base = 0
|
||||
}
|
||||
|
||||
parsed := make([]uint64, 0, 8)
|
||||
vv := []string{
|
||||
values[base+3], // PacketsRecv
|
||||
values[base+4], // Errin
|
||||
values[base+5], // Dropin
|
||||
values[base+6], // BytesRecvn
|
||||
values[base+7], // PacketSent
|
||||
values[base+8], // Errout
|
||||
values[base+9], // BytesSent
|
||||
values[base+11], // Dropout
|
||||
}
|
||||
for _, target := range vv {
|
||||
if target == "-" {
|
||||
parsed = append(parsed, 0)
|
||||
continue
|
||||
}
|
||||
|
||||
t, err := strconv.ParseUint(target, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
parsed = append(parsed, t)
|
||||
}
|
||||
|
||||
n := NetIOCountersStat{
|
||||
Name: values[0],
|
||||
PacketsRecv: parsed[0],
|
||||
Errin: parsed[1],
|
||||
Dropin: parsed[2],
|
||||
BytesRecv: parsed[3],
|
||||
PacketsSent: parsed[4],
|
||||
Errout: parsed[5],
|
||||
BytesSent: parsed[6],
|
||||
Dropout: parsed[7],
|
||||
}
|
||||
ret = append(ret, n)
|
||||
}
|
||||
|
||||
if pernic == false {
|
||||
return getNetIOCountersAll(ret)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
91
plugins/system/ps/net/net_linux.go
Normal file
91
plugins/system/ps/net/net_linux.go
Normal file
@@ -0,0 +1,91 @@
|
||||
// +build linux
|
||||
|
||||
package net
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
common "github.com/shirou/gopsutil/common"
|
||||
)
|
||||
|
||||
// NetIOCounters returnes network I/O statistics for every network
|
||||
// interface installed on the system. If pernic argument is false,
|
||||
// return only sum of all information (which name is 'all'). If true,
|
||||
// every network interface installed on the system is returned
|
||||
// separately.
|
||||
func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
|
||||
filename := "/proc/net/dev"
|
||||
lines, err := common.ReadLines(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
statlen := len(lines) - 1
|
||||
|
||||
ret := make([]NetIOCountersStat, 0, statlen)
|
||||
|
||||
for _, line := range lines[2:] {
|
||||
parts := strings.SplitN(line, ":", 2)
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
interfaceName := strings.TrimSpace(parts[0])
|
||||
if interfaceName == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
fields := strings.Fields(strings.TrimSpace(parts[1]))
|
||||
bytesRecv, err := strconv.ParseUint(fields[0], 10, 64)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
packetsRecv, err := strconv.ParseUint(fields[1], 10, 64)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
errIn, err := strconv.ParseUint(fields[2], 10, 64)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
dropIn, err := strconv.ParseUint(fields[3], 10, 64)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
bytesSent, err := strconv.ParseUint(fields[8], 10, 64)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
packetsSent, err := strconv.ParseUint(fields[9], 10, 64)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
errOut, err := strconv.ParseUint(fields[10], 10, 64)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
dropOut, err := strconv.ParseUint(fields[13], 10, 64)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
nic := NetIOCountersStat{
|
||||
Name: interfaceName,
|
||||
BytesRecv: bytesRecv,
|
||||
PacketsRecv: packetsRecv,
|
||||
Errin: errIn,
|
||||
Dropin: dropIn,
|
||||
BytesSent: bytesSent,
|
||||
PacketsSent: packetsSent,
|
||||
Errout: errOut,
|
||||
Dropout: dropOut,
|
||||
}
|
||||
ret = append(ret, nic)
|
||||
}
|
||||
|
||||
if pernic == false {
|
||||
return getNetIOCountersAll(ret)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
122
plugins/system/ps/net/net_test.go
Normal file
122
plugins/system/ps/net/net_test.go
Normal file
@@ -0,0 +1,122 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAddrString(t *testing.T) {
|
||||
v := Addr{IP: "192.168.0.1", Port: 8000}
|
||||
|
||||
s := fmt.Sprintf("%v", v)
|
||||
if s != "{\"ip\":\"192.168.0.1\",\"port\":8000}" {
|
||||
t.Errorf("Addr string is invalid: %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNetIOCountersStatString(t *testing.T) {
|
||||
v := NetIOCountersStat{
|
||||
Name: "test",
|
||||
BytesSent: 100,
|
||||
}
|
||||
e := `{"name":"test","bytes_sent":100,"bytes_recv":0,"packets_sent":0,"packets_recv":0,"errin":0,"errout":0,"dropin":0,"dropout":0}`
|
||||
if e != fmt.Sprintf("%v", v) {
|
||||
t.Errorf("NetIOCountersStat string is invalid: %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNetConnectionStatString(t *testing.T) {
|
||||
v := NetConnectionStat{
|
||||
Fd: 10,
|
||||
Family: 10,
|
||||
Type: 10,
|
||||
}
|
||||
e := `{"fd":10,"family":10,"type":10,"localaddr":{"ip":"","port":0},"remoteaddr":{"ip":"","port":0},"status":"","pid":0}`
|
||||
if e != fmt.Sprintf("%v", v) {
|
||||
t.Errorf("NetConnectionStat string is invalid: %v", v)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestNetIOCountersAll(t *testing.T) {
|
||||
v, err := NetIOCounters(false)
|
||||
per, err := NetIOCounters(true)
|
||||
if err != nil {
|
||||
t.Errorf("Could not get NetIOCounters: %v", err)
|
||||
}
|
||||
if len(v) != 1 {
|
||||
t.Errorf("Could not get NetIOCounters: %v", v)
|
||||
}
|
||||
if v[0].Name != "all" {
|
||||
t.Errorf("Invalid NetIOCounters: %v", v)
|
||||
}
|
||||
var pr uint64
|
||||
for _, p := range per {
|
||||
pr += p.PacketsRecv
|
||||
}
|
||||
if v[0].PacketsRecv != pr {
|
||||
t.Errorf("invalid sum value: %v, %v", v[0].PacketsRecv, pr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNetIOCountersPerNic(t *testing.T) {
|
||||
v, err := NetIOCounters(true)
|
||||
if err != nil {
|
||||
t.Errorf("Could not get NetIOCounters: %v", err)
|
||||
}
|
||||
if len(v) == 0 {
|
||||
t.Errorf("Could not get NetIOCounters: %v", v)
|
||||
}
|
||||
for _, vv := range v {
|
||||
if vv.Name == "" {
|
||||
t.Errorf("Invalid NetIOCounters: %v", vv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_getNetIOCountersAll(t *testing.T) {
|
||||
n := []NetIOCountersStat{
|
||||
NetIOCountersStat{
|
||||
Name: "a",
|
||||
BytesRecv: 10,
|
||||
PacketsRecv: 10,
|
||||
},
|
||||
NetIOCountersStat{
|
||||
Name: "b",
|
||||
BytesRecv: 10,
|
||||
PacketsRecv: 10,
|
||||
Errin: 10,
|
||||
},
|
||||
}
|
||||
ret, err := getNetIOCountersAll(n)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if len(ret) != 1 {
|
||||
t.Errorf("invalid return count")
|
||||
}
|
||||
if ret[0].Name != "all" {
|
||||
t.Errorf("invalid return name")
|
||||
}
|
||||
if ret[0].BytesRecv != 20 {
|
||||
t.Errorf("invalid count bytesrecv")
|
||||
}
|
||||
if ret[0].Errin != 10 {
|
||||
t.Errorf("invalid count errin")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNetInterfaces(t *testing.T) {
|
||||
v, err := NetInterfaces()
|
||||
if err != nil {
|
||||
t.Errorf("Could not get NetInterfaceStat: %v", err)
|
||||
}
|
||||
if len(v) == 0 {
|
||||
t.Errorf("Could not get NetInterfaceStat: %v", err)
|
||||
}
|
||||
for _, vv := range v {
|
||||
if vv.Name == "" {
|
||||
t.Errorf("Invalid NetInterface: %v", vv)
|
||||
}
|
||||
}
|
||||
}
|
||||
98
plugins/system/ps/net/net_windows.go
Normal file
98
plugins/system/ps/net/net_windows.go
Normal file
@@ -0,0 +1,98 @@
|
||||
// +build windows
|
||||
|
||||
package net
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
common "github.com/shirou/gopsutil/common"
|
||||
)
|
||||
|
||||
var (
|
||||
modiphlpapi = syscall.NewLazyDLL("iphlpapi.dll")
|
||||
procGetExtendedTcpTable = modiphlpapi.NewProc("GetExtendedTcpTable")
|
||||
procGetExtendedUdpTable = modiphlpapi.NewProc("GetExtendedUdpTable")
|
||||
)
|
||||
|
||||
const (
|
||||
TCPTableBasicListener = iota
|
||||
TCPTableBasicConnections
|
||||
TCPTableBasicAll
|
||||
TCPTableOwnerPIDListener
|
||||
TCPTableOwnerPIDConnections
|
||||
TCPTableOwnerPIDAll
|
||||
TCPTableOwnerModuleListener
|
||||
TCPTableOwnerModuleConnections
|
||||
TCPTableOwnerModuleAll
|
||||
)
|
||||
|
||||
func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
|
||||
ifs, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ai, err := getAdapterList()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var ret []NetIOCountersStat
|
||||
|
||||
for _, ifi := range ifs {
|
||||
name := ifi.Name
|
||||
for ; ai != nil; ai = ai.Next {
|
||||
name = common.BytePtrToString(&ai.Description[0])
|
||||
c := NetIOCountersStat{
|
||||
Name: name,
|
||||
}
|
||||
|
||||
row := syscall.MibIfRow{Index: ai.Index}
|
||||
e := syscall.GetIfEntry(&row)
|
||||
if e != nil {
|
||||
return nil, os.NewSyscallError("GetIfEntry", e)
|
||||
}
|
||||
c.BytesSent = uint64(row.OutOctets)
|
||||
c.BytesRecv = uint64(row.InOctets)
|
||||
c.PacketsSent = uint64(row.OutUcastPkts)
|
||||
c.PacketsRecv = uint64(row.InUcastPkts)
|
||||
c.Errin = uint64(row.InErrors)
|
||||
c.Errout = uint64(row.OutErrors)
|
||||
c.Dropin = uint64(row.InDiscards)
|
||||
c.Dropout = uint64(row.OutDiscards)
|
||||
|
||||
ret = append(ret, c)
|
||||
}
|
||||
}
|
||||
|
||||
if pernic == false {
|
||||
return getNetIOCountersAll(ret)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// Return a list of network connections opened by a process
|
||||
func NetConnections(kind string) ([]NetConnectionStat, error) {
|
||||
var ret []NetConnectionStat
|
||||
|
||||
return ret, common.NotImplementedError
|
||||
}
|
||||
|
||||
// borrowed from src/pkg/net/interface_windows.go
|
||||
func getAdapterList() (*syscall.IpAdapterInfo, error) {
|
||||
b := make([]byte, 1000)
|
||||
l := uint32(len(b))
|
||||
a := (*syscall.IpAdapterInfo)(unsafe.Pointer(&b[0]))
|
||||
err := syscall.GetAdaptersInfo(a, &l)
|
||||
if err == syscall.ERROR_BUFFER_OVERFLOW {
|
||||
b = make([]byte, l)
|
||||
a = (*syscall.IpAdapterInfo)(unsafe.Pointer(&b[0]))
|
||||
err = syscall.GetAdaptersInfo(a, &l)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, os.NewSyscallError("GetAdaptersInfo", err)
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
Reference in New Issue
Block a user