From 23eb08be152000a9c7ce9e322e4f4d0b9e89db64 Mon Sep 17 00:00:00 2001 From: Shirou WAKAYAMA Date: Mon, 5 Oct 2015 22:49:01 +0900 Subject: [PATCH 1/4] add tcp connections stat plugin. --- plugins/system/ps.go | 5 ++++ plugins/system/tcpconn.go | 60 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 plugins/system/tcpconn.go diff --git a/plugins/system/ps.go b/plugins/system/ps.go index e715fbd58..94a8a68da 100644 --- a/plugins/system/ps.go +++ b/plugins/system/ps.go @@ -32,6 +32,7 @@ type PS interface { VMStat() (*mem.VirtualMemoryStat, error) SwapStat() (*mem.SwapMemoryStat, error) DockerStat() ([]*DockerContainerStat, error) + NetConnections() ([]net.NetConnectionStat, error) } func add(acc plugins.Accumulator, @@ -90,6 +91,10 @@ func (s *systemPS) NetIO() ([]net.NetIOCountersStat, error) { return net.NetIOCounters(true) } +func (s *systemPS) NetConnections() ([]net.NetConnectionStat, error) { + return net.NetConnections("all") +} + func (s *systemPS) DiskIO() (map[string]disk.DiskIOCountersStat, error) { m, err := disk.DiskIOCounters() if err == common.NotImplementedError { diff --git a/plugins/system/tcpconn.go b/plugins/system/tcpconn.go new file mode 100644 index 000000000..27d5f1da9 --- /dev/null +++ b/plugins/system/tcpconn.go @@ -0,0 +1,60 @@ +package system + +import ( + "fmt" + + "github.com/influxdb/telegraf/plugins" +) + +type TCPConnectionStats struct { + ps PS +} + +func (_ *TCPConnectionStats) Description() string { + return "Read metrics about TCP status such as established, time wait etc" +} + +var tcpstatSampleConfig = "" + +func (_ *TCPConnectionStats) SampleConfig() string { + return tcpstatSampleConfig +} + +func (s *TCPConnectionStats) Gather(acc plugins.Accumulator) error { + netconns, err := s.ps.NetConnections() + if err != nil { + return fmt.Errorf("error getting net connections info: %s", err) + } + counts := make(map[string]int) + + // TODO: add family to tags or else + tags := map[string]string{} + for _, netcon := range netconns { + c, ok := counts[netcon.Status] + if !ok { + counts[netcon.Status] = 0 + } + counts[netcon.Status] = c + 1 + } + + acc.Add("established", counts["ESTABLISHED"], tags) + acc.Add("syn_sent", counts["SYN_SENT"], tags) + acc.Add("syn_recv", counts["SYN_RECV"], tags) + acc.Add("fin_wait1", counts["FIN_WAIT1"], tags) + acc.Add("fin_wait2", counts["FIN_WAIT2"], tags) + acc.Add("time_wait", counts["TIME_WAIT"], tags) + acc.Add("close", counts["CLOSE"], tags) + acc.Add("close_wait", counts["CLOSE_WAIT"], tags) + acc.Add("last_ack", counts["LAST_ACK"], tags) + acc.Add("listen", counts["LISTEN"], tags) + acc.Add("closing", counts["CLOSING"], tags) + acc.Add("none", counts["NONE"], tags) + + return nil +} + +func init() { + plugins.Add("tcpconn", func() plugins.Plugin { + return &TCPConnectionStats{ps: &systemPS{}} + }) +} From 4a6f1ebdeac765a91fc1eeaecdda1c78bb58d82c Mon Sep 17 00:00:00 2001 From: Shirou WAKAYAMA Date: Thu, 8 Oct 2015 22:55:34 +0900 Subject: [PATCH 2/4] add NetConnections to the mockPS. --- plugins/system/mock_PS.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/system/mock_PS.go b/plugins/system/mock_PS.go index 70d0f20d5..602e34ee9 100644 --- a/plugins/system/mock_PS.go +++ b/plugins/system/mock_PS.go @@ -77,3 +77,11 @@ func (m *MockPS) DockerStat() ([]*DockerContainerStat, error) { return r0, r1 } +func (m *MockPS) NetConnections() ([]net.NetConnectionStat, error) { + ret := m.Called() + + r0 := ret.Get(0).([]net.NetConnectionStat) + r1 := ret.Error(1) + + return r0, r1 +} From 103bcedb933ffac84011f4075c19628f042841a3 Mon Sep 17 00:00:00 2001 From: Shirou WAKAYAMA Date: Thu, 8 Oct 2015 23:10:59 +0900 Subject: [PATCH 3/4] add REAME about TCP Connection plugin. --- plugins/system/TCPCONN_README.md | 43 ++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 plugins/system/TCPCONN_README.md diff --git a/plugins/system/TCPCONN_README.md b/plugins/system/TCPCONN_README.md new file mode 100644 index 000000000..219a407ff --- /dev/null +++ b/plugins/system/TCPCONN_README.md @@ -0,0 +1,43 @@ +Telegraf plugin: TCPCONN + +#### Description + +The TCPCONN plugin collects TCP connections state by using `lsof`. + +Supported TCP Connection states are follows. + +- established +- syn_sent +- syn_recv +- fin_wait1 +- fin_wait2 +- time_wait +- close +- close_wait +- last_ack +- listen +- closing +- none + + +# Measurements: +### TCP Connections measurements: + +Meta: +- units: counts + +Measurement names: +- established +- syn_sent +- syn_recv +- fin_wait1 +- fin_wait2 +- time_wait +- close +- close_wait +- last_ack +- listen +- closing +- none + +If there are no connection on the state, the metric is not counted. From 8caff58e9d96a0c3c5aa3a7d2e77b8e0d765ae3d Mon Sep 17 00:00:00 2001 From: Shirou WAKAYAMA Date: Sun, 11 Oct 2015 23:13:35 +0900 Subject: [PATCH 4/4] add UDP socket counts and rename to 'netstat'. --- plugins/system/NETSTAT_README.md | 52 +++++++++++++++++++++++++ plugins/system/TCPCONN_README.md | 43 --------------------- plugins/system/netstat.go | 66 ++++++++++++++++++++++++++++++++ plugins/system/system_test.go | 29 ++++++++++++++ plugins/system/tcpconn.go | 60 ----------------------------- 5 files changed, 147 insertions(+), 103 deletions(-) create mode 100644 plugins/system/NETSTAT_README.md delete mode 100644 plugins/system/TCPCONN_README.md create mode 100644 plugins/system/netstat.go delete mode 100644 plugins/system/tcpconn.go diff --git a/plugins/system/NETSTAT_README.md b/plugins/system/NETSTAT_README.md new file mode 100644 index 000000000..636a7e3af --- /dev/null +++ b/plugins/system/NETSTAT_README.md @@ -0,0 +1,52 @@ +Telegraf plugin: NETSTAT + +#### Description + +The NETSTAT plugin collects TCP connections state and UDP socket counts by using `lsof`. + +Supported TCP Connection states are follows. + +- established +- syn_sent +- syn_recv +- fin_wait1 +- fin_wait2 +- time_wait +- close +- close_wait +- last_ack +- listen +- closing +- none + + +# Measurements: +### TCP Connection State measurements: + +Meta: +- units: counts + +Measurement names: +- tcp_established +- tcp_syn_sent +- tcp_syn_recv +- tcp_fin_wait1 +- tcp_fin_wait2 +- tcp_time_wait +- tcp_close +- tcp_close_wait +- tcp_last_ack +- tcp_listen +- tcp_closing +- tcp_none + +If there are no connection on the state, the metric is not counted. + +### UDP socket counts measurements: + +Meta: +- units: counts + +Measurement names: +- udp_socket + diff --git a/plugins/system/TCPCONN_README.md b/plugins/system/TCPCONN_README.md deleted file mode 100644 index 219a407ff..000000000 --- a/plugins/system/TCPCONN_README.md +++ /dev/null @@ -1,43 +0,0 @@ -Telegraf plugin: TCPCONN - -#### Description - -The TCPCONN plugin collects TCP connections state by using `lsof`. - -Supported TCP Connection states are follows. - -- established -- syn_sent -- syn_recv -- fin_wait1 -- fin_wait2 -- time_wait -- close -- close_wait -- last_ack -- listen -- closing -- none - - -# Measurements: -### TCP Connections measurements: - -Meta: -- units: counts - -Measurement names: -- established -- syn_sent -- syn_recv -- fin_wait1 -- fin_wait2 -- time_wait -- close -- close_wait -- last_ack -- listen -- closing -- none - -If there are no connection on the state, the metric is not counted. diff --git a/plugins/system/netstat.go b/plugins/system/netstat.go new file mode 100644 index 000000000..9fe512ddd --- /dev/null +++ b/plugins/system/netstat.go @@ -0,0 +1,66 @@ +package system + +import ( + "fmt" + "syscall" + + "github.com/influxdb/telegraf/plugins" +) + +type NetStats struct { + ps PS +} + +func (_ *NetStats) Description() string { + return "Read metrics about TCP status such as established, time wait etc and UDP sockets counts." +} + +var tcpstatSampleConfig = "" + +func (_ *NetStats) SampleConfig() string { + return tcpstatSampleConfig +} + +func (s *NetStats) Gather(acc plugins.Accumulator) error { + netconns, err := s.ps.NetConnections() + if err != nil { + return fmt.Errorf("error getting net connections info: %s", err) + } + counts := make(map[string]int) + counts["UDP"] = 0 + + // TODO: add family to tags or else + tags := map[string]string{} + for _, netcon := range netconns { + if netcon.Type == syscall.SOCK_DGRAM { + counts["UDP"] += 1 + continue // UDP has no status + } + c, ok := counts[netcon.Status] + if !ok { + counts[netcon.Status] = 0 + } + counts[netcon.Status] = c + 1 + } + acc.Add("tcp_established", counts["ESTABLISHED"], tags) + acc.Add("tcp_syn_sent", counts["SYN_SENT"], tags) + acc.Add("tcp_syn_recv", counts["SYN_RECV"], tags) + acc.Add("tcp_fin_wait1", counts["FIN_WAIT1"], tags) + acc.Add("tcp_fin_wait2", counts["FIN_WAIT2"], tags) + acc.Add("tcp_time_wait", counts["TIME_WAIT"], tags) + acc.Add("tcp_close", counts["CLOSE"], tags) + acc.Add("tcp_close_wait", counts["CLOSE_WAIT"], tags) + acc.Add("tcp_last_ack", counts["LAST_ACK"], tags) + acc.Add("tcp_listen", counts["LISTEN"], tags) + acc.Add("tcp_closing", counts["CLOSING"], tags) + acc.Add("tcp_none", counts["NONE"], tags) + acc.Add("udp_socket", counts["UDP"], tags) + + return nil +} + +func init() { + plugins.Add("netstat", func() plugins.Plugin { + return &NetStats{ps: &systemPS{}} + }) +} diff --git a/plugins/system/system_test.go b/plugins/system/system_test.go index 68f546add..1219318d9 100644 --- a/plugins/system/system_test.go +++ b/plugins/system/system_test.go @@ -3,6 +3,7 @@ package system import ( "fmt" "reflect" + "syscall" "testing" "github.com/influxdb/telegraf/testutil" @@ -116,6 +117,23 @@ func TestSystemStats_GenerateStats(t *testing.T) { mps.On("SwapStat").Return(sms, nil) + netstats := []net.NetConnectionStat{ + net.NetConnectionStat{ + Type: syscall.SOCK_DGRAM, + }, + net.NetConnectionStat{ + Status: "ESTABLISHED", + }, + net.NetConnectionStat{ + Status: "ESTABLISHED", + }, + net.NetConnectionStat{ + Status: "CLOSE", + }, + } + + mps.On("NetConnections").Return(netstats, nil) + cs := NewCPUStats(&mps) cputags := map[string]string{ @@ -253,6 +271,17 @@ func TestSystemStats_GenerateStats(t *testing.T) { assert.NoError(t, acc.ValidateTaggedValue("free", uint64(6412), swaptags)) assert.NoError(t, acc.ValidateTaggedValue("in", uint64(7), swaptags)) assert.NoError(t, acc.ValidateTaggedValue("out", uint64(830), swaptags)) + + acc.Points = nil + + err = (&NetStats{&mps}).Gather(&acc) + require.NoError(t, err) + netstattags := map[string]string(nil) + + assert.NoError(t, acc.ValidateTaggedValue("tcp_established", 2, netstattags)) + assert.NoError(t, acc.ValidateTaggedValue("tcp_close", 1, netstattags)) + assert.NoError(t, acc.ValidateTaggedValue("udp_socket", 1, netstattags)) + } // Asserts that a given accumulator contains a measurment of type float64 with diff --git a/plugins/system/tcpconn.go b/plugins/system/tcpconn.go deleted file mode 100644 index 27d5f1da9..000000000 --- a/plugins/system/tcpconn.go +++ /dev/null @@ -1,60 +0,0 @@ -package system - -import ( - "fmt" - - "github.com/influxdb/telegraf/plugins" -) - -type TCPConnectionStats struct { - ps PS -} - -func (_ *TCPConnectionStats) Description() string { - return "Read metrics about TCP status such as established, time wait etc" -} - -var tcpstatSampleConfig = "" - -func (_ *TCPConnectionStats) SampleConfig() string { - return tcpstatSampleConfig -} - -func (s *TCPConnectionStats) Gather(acc plugins.Accumulator) error { - netconns, err := s.ps.NetConnections() - if err != nil { - return fmt.Errorf("error getting net connections info: %s", err) - } - counts := make(map[string]int) - - // TODO: add family to tags or else - tags := map[string]string{} - for _, netcon := range netconns { - c, ok := counts[netcon.Status] - if !ok { - counts[netcon.Status] = 0 - } - counts[netcon.Status] = c + 1 - } - - acc.Add("established", counts["ESTABLISHED"], tags) - acc.Add("syn_sent", counts["SYN_SENT"], tags) - acc.Add("syn_recv", counts["SYN_RECV"], tags) - acc.Add("fin_wait1", counts["FIN_WAIT1"], tags) - acc.Add("fin_wait2", counts["FIN_WAIT2"], tags) - acc.Add("time_wait", counts["TIME_WAIT"], tags) - acc.Add("close", counts["CLOSE"], tags) - acc.Add("close_wait", counts["CLOSE_WAIT"], tags) - acc.Add("last_ack", counts["LAST_ACK"], tags) - acc.Add("listen", counts["LISTEN"], tags) - acc.Add("closing", counts["CLOSING"], tags) - acc.Add("none", counts["NONE"], tags) - - return nil -} - -func init() { - plugins.Add("tcpconn", func() plugins.Plugin { - return &TCPConnectionStats{ps: &systemPS{}} - }) -}