Utilize timeout in net_response plugin.

Also changing the net_response and http_response plugins to only accept
duration strings for their timeout parameters. This is a breaking config
file change.

closes #1214
This commit is contained in:
Cameron Sparr
2016-05-23 13:33:43 +01:00
parent c6699c36d3
commit c44ecf54a5
10 changed files with 118 additions and 104 deletions

View File

@@ -6,41 +6,30 @@ It can also check response text.
### Configuration:
```
# List of UDP/TCP connections you want to check
[[inputs.net_response]]
protocol = "tcp"
# Server address (default IP localhost)
address = "github.com:80"
# Set timeout (default 1.0)
timeout = 1.0
# Set read timeout (default 1.0)
read_timeout = 1.0
# String sent to the server
send = "ssh"
# Expected string in answer
expect = "ssh"
[[inputs.net_response]]
protocol = "tcp"
address = ":80"
# TCP or UDP 'ping' given url and collect response time in seconds
[[inputs.net_response]]
protocol = "udp"
# Server address (default IP localhost)
## Protocol, must be "tcp" or "udp"
protocol = "tcp"
## Server address (default localhost)
address = "github.com:80"
# Set timeout (default 1.0)
timeout = 1.0
# Set read timeout (default 1.0)
read_timeout = 1.0
# String sent to the server
## Set timeout
timeout = "1s"
## Optional string sent to the server
send = "ssh"
# Expected string in answer
## Optional expected string in answer
expect = "ssh"
## Set read timeout (only used if expecting a response)
read_timeout = "1s"
[[inputs.net_response]]
protocol = "udp"
address = "localhost:161"
timeout = 2.0
timeout = "2s"
```
### Measurements & Fields:

View File

@@ -9,14 +9,15 @@ import (
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/internal"
"github.com/influxdata/telegraf/plugins/inputs"
)
// NetResponses struct
type NetResponse struct {
Address string
Timeout float64
ReadTimeout float64
Timeout internal.Duration
ReadTimeout internal.Duration
Send string
Expect string
Protocol string
@@ -31,29 +32,28 @@ var sampleConfig = `
protocol = "tcp"
## Server address (default localhost)
address = "github.com:80"
## Set timeout (default 1.0 seconds)
timeout = 1.0
## Set read timeout (default 1.0 seconds)
read_timeout = 1.0
## Set timeout
timeout = "1s"
## Optional string sent to the server
# send = "ssh"
## Optional expected string in answer
# expect = "ssh"
## Set read timeout (only used if expecting a response)
read_timeout = "1s"
`
func (_ *NetResponse) SampleConfig() string {
return sampleConfig
}
func (t *NetResponse) TcpGather() (map[string]interface{}, error) {
func (n *NetResponse) TcpGather() (map[string]interface{}, error) {
// Prepare fields
fields := make(map[string]interface{})
// Start Timer
start := time.Now()
// Resolving
tcpAddr, err := net.ResolveTCPAddr("tcp", t.Address)
// Connecting
conn, err := net.DialTCP("tcp", nil, tcpAddr)
conn, err := net.DialTimeout("tcp", n.Address, n.Timeout.Duration)
// Stop timer
responseTime := time.Since(start).Seconds()
// Handle error
@@ -62,17 +62,16 @@ func (t *NetResponse) TcpGather() (map[string]interface{}, error) {
}
defer conn.Close()
// Send string if needed
if t.Send != "" {
msg := []byte(t.Send)
if n.Send != "" {
msg := []byte(n.Send)
conn.Write(msg)
conn.CloseWrite()
// Stop timer
responseTime = time.Since(start).Seconds()
}
// Read string if needed
if t.Expect != "" {
if n.Expect != "" {
// Set read timeout
conn.SetReadDeadline(time.Now().Add(time.Duration(t.ReadTimeout) * time.Second))
conn.SetReadDeadline(time.Now().Add(n.ReadTimeout.Duration))
// Prepare reader
reader := bufio.NewReader(conn)
tp := textproto.NewReader(reader)
@@ -85,7 +84,7 @@ func (t *NetResponse) TcpGather() (map[string]interface{}, error) {
fields["string_found"] = false
} else {
// Looking for string in answer
RegEx := regexp.MustCompile(`.*` + t.Expect + `.*`)
RegEx := regexp.MustCompile(`.*` + n.Expect + `.*`)
find := RegEx.FindString(string(data))
if find != "" {
fields["string_found"] = true
@@ -99,13 +98,13 @@ func (t *NetResponse) TcpGather() (map[string]interface{}, error) {
return fields, nil
}
func (u *NetResponse) UdpGather() (map[string]interface{}, error) {
func (n *NetResponse) UdpGather() (map[string]interface{}, error) {
// Prepare fields
fields := make(map[string]interface{})
// Start Timer
start := time.Now()
// Resolving
udpAddr, err := net.ResolveUDPAddr("udp", u.Address)
udpAddr, err := net.ResolveUDPAddr("udp", n.Address)
LocalAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0")
// Connecting
conn, err := net.DialUDP("udp", LocalAddr, udpAddr)
@@ -115,11 +114,11 @@ func (u *NetResponse) UdpGather() (map[string]interface{}, error) {
return nil, err
}
// Send string
msg := []byte(u.Send)
msg := []byte(n.Send)
conn.Write(msg)
// Read string
// Set read timeout
conn.SetReadDeadline(time.Now().Add(time.Duration(u.ReadTimeout) * time.Second))
conn.SetReadDeadline(time.Now().Add(n.ReadTimeout.Duration))
// Read
buf := make([]byte, 1024)
_, _, err = conn.ReadFromUDP(buf)
@@ -130,7 +129,7 @@ func (u *NetResponse) UdpGather() (map[string]interface{}, error) {
return nil, err
} else {
// Looking for string in answer
RegEx := regexp.MustCompile(`.*` + u.Expect + `.*`)
RegEx := regexp.MustCompile(`.*` + n.Expect + `.*`)
find := RegEx.FindString(string(buf))
if find != "" {
fields["string_found"] = true
@@ -142,28 +141,28 @@ func (u *NetResponse) UdpGather() (map[string]interface{}, error) {
return fields, nil
}
func (c *NetResponse) Gather(acc telegraf.Accumulator) error {
func (n *NetResponse) Gather(acc telegraf.Accumulator) error {
// Set default values
if c.Timeout == 0 {
c.Timeout = 1.0
if n.Timeout.Duration == 0 {
n.Timeout.Duration = time.Second
}
if c.ReadTimeout == 0 {
c.ReadTimeout = 1.0
if n.ReadTimeout.Duration == 0 {
n.ReadTimeout.Duration = time.Second
}
// Check send and expected string
if c.Protocol == "udp" && c.Send == "" {
if n.Protocol == "udp" && n.Send == "" {
return errors.New("Send string cannot be empty")
}
if c.Protocol == "udp" && c.Expect == "" {
if n.Protocol == "udp" && n.Expect == "" {
return errors.New("Expected string cannot be empty")
}
// Prepare host and port
host, port, err := net.SplitHostPort(c.Address)
host, port, err := net.SplitHostPort(n.Address)
if err != nil {
return err
}
if host == "" {
c.Address = "localhost:" + port
n.Address = "localhost:" + port
}
if port == "" {
return errors.New("Bad port")
@@ -172,11 +171,11 @@ func (c *NetResponse) Gather(acc telegraf.Accumulator) error {
tags := map[string]string{"server": host, "port": port}
var fields map[string]interface{}
// Gather data
if c.Protocol == "tcp" {
fields, err = c.TcpGather()
if n.Protocol == "tcp" {
fields, err = n.TcpGather()
tags["protocol"] = "tcp"
} else if c.Protocol == "udp" {
fields, err = c.UdpGather()
} else if n.Protocol == "udp" {
fields, err = n.UdpGather()
tags["protocol"] = "udp"
} else {
return errors.New("Bad protocol")

View File

@@ -5,7 +5,9 @@ import (
"regexp"
"sync"
"testing"
"time"
"github.com/influxdata/telegraf/internal"
"github.com/influxdata/telegraf/testutil"
"github.com/stretchr/testify/assert"
@@ -35,7 +37,7 @@ func TestTCPError(t *testing.T) {
// Error
err1 := c.Gather(&acc)
require.Error(t, err1)
assert.Equal(t, "dial tcp 127.0.0.1:9999: getsockopt: connection refused", err1.Error())
assert.Contains(t, err1.Error(), "getsockopt: connection refused")
}
func TestTCPOK1(t *testing.T) {
@@ -46,8 +48,8 @@ func TestTCPOK1(t *testing.T) {
Address: "127.0.0.1:2004",
Send: "test",
Expect: "test",
ReadTimeout: 3.0,
Timeout: 1.0,
ReadTimeout: internal.Duration{Duration: time.Second * 3},
Timeout: internal.Duration{Duration: time.Second},
Protocol: "tcp",
}
// Start TCP server
@@ -86,8 +88,8 @@ func TestTCPOK2(t *testing.T) {
Address: "127.0.0.1:2004",
Send: "test",
Expect: "test2",
ReadTimeout: 3.0,
Timeout: 1.0,
ReadTimeout: internal.Duration{Duration: time.Second * 3},
Timeout: internal.Duration{Duration: time.Second},
Protocol: "tcp",
}
// Start TCP server
@@ -141,8 +143,8 @@ func TestUDPOK1(t *testing.T) {
Address: "127.0.0.1:2004",
Send: "test",
Expect: "test",
ReadTimeout: 3.0,
Timeout: 1.0,
ReadTimeout: internal.Duration{Duration: time.Second * 3},
Timeout: internal.Duration{Duration: time.Second},
Protocol: "udp",
}
// Start UDP server