From ef63908541b9c2facf14538b4188f20aad19d8fb Mon Sep 17 00:00:00 2001 From: Bob Shannon Date: Fri, 14 Jul 2017 13:43:36 -0400 Subject: [PATCH] Add result_type field to net_response input plugin (#2990) --- plugins/inputs/net_response/README.md | 15 ++++--- plugins/inputs/net_response/net_response.go | 23 ++++++++--- .../inputs/net_response/net_response_test.go | 40 ++++++++++++++++--- 3 files changed, 62 insertions(+), 16 deletions(-) diff --git a/plugins/inputs/net_response/README.md b/plugins/inputs/net_response/README.md index 16c73e8ee..01c681b55 100644 --- a/plugins/inputs/net_response/README.md +++ b/plugins/inputs/net_response/README.md @@ -1,4 +1,4 @@ -# Example Input Plugin +# Network Response Input Plugin The input plugin test UDP/TCP connections response time. It can also check response text. @@ -59,7 +59,8 @@ It can also check response text. - net_response - response_time (float, seconds) - - string_found (bool) # Only if "expected: option is set + - result_type (string) # success, timeout, connection_failed, read_failed, string_mismatch + - [**DEPRECATED**] string_found (boolean) ### Tags: @@ -72,7 +73,11 @@ It can also check response text. ``` $ ./telegraf --config telegraf.conf --input-filter net_response --test -net_response,server=192.168.2.2,port=22,protocol=tcp response_time=0.18070360500000002,string_found=true 1454785464182527094 -net_response,server=192.168.2.2,port=2222,protocol=tcp response_time=1.090124776,string_found=false 1454784433658942325 - +net_response,server=influxdata.com,port=8080,protocol=tcp,host=localhost result_type="timeout" 1499310361000000000 +net_response,server=influxdata.com,port=443,protocol=tcp,host=localhost result_type="success",response_time=0.088703864 1499310361000000000 +net_response,protocol=tcp,host=localhost,server=this.domain.does.not.exist,port=443 result_type="connection_failed" 1499310361000000000 +net_response,protocol=udp,host=localhost,server=influxdata.com,port=8080 result_type="read_failed" 1499310362000000000 +net_response,port=31338,protocol=udp,host=localhost,server=localhost result_type="string_mismatch",string_found=false,response_time=0.00242682 1499310362000000000 +net_response,protocol=udp,host=localhost,server=localhost,port=31338 response_time=0.001128598,result_type="success",string_found=true 1499310362000000000 +net_response,server=this.domain.does.not.exist,port=443,protocol=udp,host=localhost result_type="connection_failed" 1499310362000000000 ``` diff --git a/plugins/inputs/net_response/net_response.go b/plugins/inputs/net_response/net_response.go index ad0de46c3..75d0a328a 100644 --- a/plugins/inputs/net_response/net_response.go +++ b/plugins/inputs/net_response/net_response.go @@ -64,7 +64,12 @@ func (n *NetResponse) TcpGather() (map[string]interface{}, error) { responseTime := time.Since(start).Seconds() // Handle error if err != nil { - return nil, err + if e, ok := err.(net.Error); ok && e.Timeout() { + fields["result_type"] = "timeout" + } else { + fields["result_type"] = "connection_failed" + } + return fields, nil } defer conn.Close() // Send string if needed @@ -88,17 +93,21 @@ func (n *NetResponse) TcpGather() (map[string]interface{}, error) { // Handle error if err != nil { fields["string_found"] = false + fields["result_type"] = "read_failed" } else { // Looking for string in answer RegEx := regexp.MustCompile(`.*` + n.Expect + `.*`) find := RegEx.FindString(string(data)) if find != "" { + fields["result_type"] = "success" fields["string_found"] = true } else { + fields["result_type"] = "string_mismatch" fields["string_found"] = false } } - + } else { + fields["result_type"] = "success" } fields["response_time"] = responseTime return fields, nil @@ -114,11 +123,12 @@ func (n *NetResponse) UdpGather() (map[string]interface{}, error) { LocalAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0") // Connecting conn, err := net.DialUDP("udp", LocalAddr, udpAddr) - defer conn.Close() // Handle error if err != nil { - return nil, err + fields["result_type"] = "connection_failed" + return fields, nil } + defer conn.Close() // Send string msg := []byte(n.Send) conn.Write(msg) @@ -132,14 +142,17 @@ func (n *NetResponse) UdpGather() (map[string]interface{}, error) { responseTime := time.Since(start).Seconds() // Handle error if err != nil { - return nil, err + fields["result_type"] = "read_failed" + return fields, nil } else { // Looking for string in answer RegEx := regexp.MustCompile(`.*` + n.Expect + `.*`) find := RegEx.FindString(string(buf)) if find != "" { + fields["result_type"] = "success" fields["string_found"] = true } else { + fields["result_type"] = "string_mismatch" fields["string_found"] = false } } diff --git a/plugins/inputs/net_response/net_response_test.go b/plugins/inputs/net_response/net_response_test.go index a005c06f5..c7bfb579a 100644 --- a/plugins/inputs/net_response/net_response_test.go +++ b/plugins/inputs/net_response/net_response_test.go @@ -2,7 +2,6 @@ package net_response import ( "net" - "regexp" "sync" "testing" "time" @@ -36,8 +35,18 @@ func TestTCPError(t *testing.T) { } // Error err1 := c.Gather(&acc) - require.Error(t, err1) - assert.Contains(t, err1.Error(), "getsockopt: connection refused") + require.NoError(t, err1) + acc.AssertContainsTaggedFields(t, + "net_response", + map[string]interface{}{ + "result_type": "connection_failed", + }, + map[string]string{ + "server": "", + "port": "9999", + "protocol": "tcp", + }, + ) } func TestTCPOK1(t *testing.T) { @@ -68,6 +77,7 @@ func TestTCPOK1(t *testing.T) { acc.AssertContainsTaggedFields(t, "net_response", map[string]interface{}{ + "result_type": "success", "string_found": true, "response_time": 1.0, }, @@ -108,6 +118,7 @@ func TestTCPOK2(t *testing.T) { acc.AssertContainsTaggedFields(t, "net_response", map[string]interface{}{ + "result_type": "string_mismatch", "string_found": false, "response_time": 1.0, }, @@ -129,10 +140,26 @@ func TestUDPrror(t *testing.T) { Expect: "test", Protocol: "udp", } - // Error + // Gather err1 := c.Gather(&acc) - require.Error(t, err1) - assert.Regexp(t, regexp.MustCompile(`read udp 127.0.0.1:[0-9]*->127.0.0.1:9999: recvfrom: connection refused`), err1.Error()) + // Override response time + for _, p := range acc.Metrics { + p.Fields["response_time"] = 1.0 + } + // Error + require.NoError(t, err1) + acc.AssertContainsTaggedFields(t, + "net_response", + map[string]interface{}{ + "result_type": "read_failed", + "response_time": 1.0, + }, + map[string]string{ + "server": "", + "port": "9999", + "protocol": "udp", + }, + ) } func TestUDPOK1(t *testing.T) { @@ -163,6 +190,7 @@ func TestUDPOK1(t *testing.T) { acc.AssertContainsTaggedFields(t, "net_response", map[string]interface{}{ + "result_type": "success", "string_found": true, "response_time": 1.0, },