1
0
mirror of https://github.com/shirou/gopsutil.git synced 2025-04-26 13:48:59 +08:00

Merge pull request #122 from jimmystewpot/add_netfilter

Add nf_conntrack counter support
This commit is contained in:
shirou 2015-12-16 15:32:43 +09:00
commit f58654fa1c
6 changed files with 88 additions and 1 deletions

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
*~
#*
_obj
*.tmp
*.tmp
.idea

View File

@ -126,6 +126,11 @@ Several methods have been added which are not present in psutil, but will provid
- system wide stats on network protocols (i.e IP, TCP, UDP, etc.)
- sourced from /proc/net/snmp
- iptables nf_conntrack (linux only)
- system wide stats on netfilter conntrack module
- sourced from /proc/sys/net/netfilter/nf_conntrack_count
Some codes are ported from Ohai. many thanks.
@ -155,6 +160,7 @@ net_connections x x
net_protocols x
net_if_addrs
net_if_stats
netfilter_conntrack x
================= ====== ======= ====== =======
Process class

View File

@ -141,6 +141,33 @@ func ByteToString(orig []byte) string {
return string(orig[l:n])
}
// ReadInts reads contents from single line file and returns them as []int32.
func ReadInts(filename string) ([]int64, error) {
f, err := os.Open(filename)
if err != nil {
return []int64{}, err
}
defer f.Close()
var ret []int64
r := bufio.NewReader(f)
// The int files that this is concerned with should only be one liners.
line, err := r.ReadString('\n')
if err != nil {
return []int64{}, err
}
i, err := strconv.ParseInt(strings.Trim(line, "\n"), 10, 32)
if err != nil {
return []int64{}, err
}
ret = append(ret, i)
return ret, nil
}
// Parse to int32 without error
func mustParseInt32(val string) int32 {
vv, _ := strconv.ParseInt(val, 10, 32)

View File

@ -64,6 +64,11 @@ type NetInterfaceStat struct {
Addrs []NetInterfaceAddr `json:"addrs"`
}
type NetFilterStat struct {
ConnTrackCount int64 `json:"conntrack_count"`
ConnTrackMax int64 `json:"conntrack_max"`
}
var constMap = map[string]int{
"TCP": syscall.SOCK_STREAM,
"UDP": syscall.SOCK_DGRAM,

View File

@ -160,3 +160,31 @@ func NetProtoCounters(protocols []string) ([]NetProtoCountersStat, error) {
}
return stats, nil
}
// NetFilterCounters returns iptables conntrack statistics
// the currently in use conntrack count and the max.
// If the file does not exist or is invalid it will return nil.
func NetFilterCounters() ([]NetFilterStat, error) {
countfile := common.HostProc("sys/net/netfilter/nf_conntrack_count")
maxfile := common.HostProc("sys/net/netfilter/nf_conntrack_max")
count, err := common.ReadInts(countfile)
if err != nil {
return nil, err
}
stats := make([]NetFilterStat, 0, 1)
max, err := common.ReadInts(maxfile)
if err != nil {
return nil, err
}
payload := NetFilterStat{
ConnTrackCount: count[0],
ConnTrackMax: max[0],
}
stats = append(stats, payload)
return stats, nil
}

View File

@ -196,3 +196,23 @@ func TestNetConnections(t *testing.T) {
}
}
func TestNetFilterCounters(t *testing.T) {
if ci := os.Getenv("CI"); ci != "" { // skip if test on drone.io
return
}
v, err := NetFilterCounters()
if err != nil {
t.Errorf("could not get NetConnections: %v", err)
}
if len(v) == 0 {
t.Errorf("could not get NetConnections: %v", v)
}
for _, vv := range v {
if vv.ConnTrackMax == 0 {
t.Errorf("nf_conntrack_max needs to be greater than zero: %v", vv)
}
}
}