From ba551c4bb0a81d7945658acc71a38d3b58a12f26 Mon Sep 17 00:00:00 2001 From: Vladimir S Date: Thu, 26 Oct 2017 23:35:37 +0300 Subject: [PATCH] Perform DNS lookup before ping (#3385) --- plugins/inputs/ping/README.md | 7 +++-- plugins/inputs/ping/ping.go | 33 +++++++++++++++++++----- plugins/inputs/ping/ping_test.go | 3 +++ plugins/inputs/ping/ping_windows.go | 32 ++++++++++++++--------- plugins/inputs/ping/ping_windows_test.go | 8 +++++- 5 files changed, 61 insertions(+), 22 deletions(-) diff --git a/plugins/inputs/ping/README.md b/plugins/inputs/ping/README.md index 2274f42c9..914477c54 100644 --- a/plugins/inputs/ping/README.md +++ b/plugins/inputs/ping/README.md @@ -28,11 +28,14 @@ urls = ["www.google.com"] # required - packets_received ( from ping output ) - percent_reply_loss ( compute from packets_transmitted and reply_received ) - percent_packets_loss ( compute from packets_transmitted and packets_received ) -- errors ( when host can not be found or wrong prameters is passed to application ) +- errors ( when host can not be found or wrong parameters is passed to application ) - response time - average_response_ms ( compute from minimum_response_ms and maximum_response_ms ) - minimum_response_ms ( from ping output ) - maximum_response_ms ( from ping output ) +- result_code + - 0: success + - 1: no such host ### Tags: @@ -44,5 +47,5 @@ urls = ["www.google.com"] # required ``` $ ./telegraf --config telegraf.conf --input-filter ping --test * Plugin: ping, Collection 1 -ping,host=WIN-PBAPLP511R7,url=www.google.com average_response_ms=7i,maximum_response_ms=9i,minimum_response_ms=7i,packets_received=4i,packets_transmitted=4i,percent_packet_loss=0,percent_reply_loss=0,reply_received=4i 1469879119000000000 +ping,host=WIN-PBAPLP511R7,url=www.google.com result_code=0i,average_response_ms=7i,maximum_response_ms=9i,minimum_response_ms=7i,packets_received=4i,packets_transmitted=4i,percent_packet_loss=0,percent_reply_loss=0,reply_received=4i 1469879119000000000 ``` diff --git a/plugins/inputs/ping/ping.go b/plugins/inputs/ping/ping.go index dcbb2c286..cae575bfd 100644 --- a/plugins/inputs/ping/ping.go +++ b/plugins/inputs/ping/ping.go @@ -5,6 +5,7 @@ package ping import ( "errors" "fmt" + "net" "os/exec" "runtime" "strconv" @@ -76,6 +77,17 @@ func (p *Ping) Gather(acc telegraf.Accumulator) error { wg.Add(1) go func(u string) { defer wg.Done() + tags := map[string]string{"url": u} + fields := map[string]interface{}{"result_code": 0} + + _, err := net.LookupHost(u) + if err != nil { + acc.AddError(err) + fields["result_code"] = 1 + acc.AddFields("ping", fields, tags) + return + } + args := p.args(u) totalTimeout := float64(p.Count)*p.Timeout + float64(p.Count-1)*p.PingInterval @@ -99,24 +111,23 @@ func (p *Ping) Gather(acc telegraf.Accumulator) error { } else { acc.AddError(err) } + acc.AddFields("ping", fields, tags) return } } - tags := map[string]string{"url": u} trans, rec, min, avg, max, stddev, err := processPingOutput(out) if err != nil { // fatal error acc.AddError(fmt.Errorf("%s: %s", err, u)) + acc.AddFields("ping", fields, tags) return } // Calculate packet loss percentage loss := float64(trans-rec) / float64(trans) * 100.0 - fields := map[string]interface{}{ - "packets_transmitted": trans, - "packets_received": rec, - "percent_packet_loss": loss, - } + fields["packets_transmitted"] = trans + fields["packets_received"] = rec + fields["percent_packet_loss"] = loss if min > 0 { fields["minimum_response_ms"] = min } @@ -194,7 +205,6 @@ func processPingOutput(out string) (int, int, float64, float64, float64, float64 for _, line := range lines { if strings.Contains(line, "transmitted") && strings.Contains(line, "received") { - err = nil stats := strings.Split(line, ", ") // Transmitted packets trans, err = strconv.Atoi(strings.Split(stats[0], " ")[0]) @@ -209,8 +219,17 @@ func processPingOutput(out string) (int, int, float64, float64, float64, float64 } else if strings.Contains(line, "min/avg/max") { stats := strings.Split(line, " ")[3] min, err = strconv.ParseFloat(strings.Split(stats, "/")[0], 64) + if err != nil { + return trans, recv, min, avg, max, stddev, err + } avg, err = strconv.ParseFloat(strings.Split(stats, "/")[1], 64) + if err != nil { + return trans, recv, min, avg, max, stddev, err + } max, err = strconv.ParseFloat(strings.Split(stats, "/")[2], 64) + if err != nil { + return trans, recv, min, avg, max, stddev, err + } stddev, err = strconv.ParseFloat(strings.Split(stats, "/")[3], 64) if err != nil { return trans, recv, min, avg, max, stddev, err diff --git a/plugins/inputs/ping/ping_test.go b/plugins/inputs/ping/ping_test.go index 8d422d4b2..eafe89428 100644 --- a/plugins/inputs/ping/ping_test.go +++ b/plugins/inputs/ping/ping_test.go @@ -158,6 +158,7 @@ func TestPingGather(t *testing.T) { "average_response_ms": 43.628, "maximum_response_ms": 51.806, "standard_deviation_ms": 5.325, + "result_code": 0, } acc.AssertContainsTaggedFields(t, "ping", fields, tags) @@ -198,6 +199,7 @@ func TestLossyPingGather(t *testing.T) { "average_response_ms": 44.033, "maximum_response_ms": 51.806, "standard_deviation_ms": 5.325, + "result_code": 0, } acc.AssertContainsTaggedFields(t, "ping", fields, tags) } @@ -230,6 +232,7 @@ func TestBadPingGather(t *testing.T) { "packets_transmitted": 2, "packets_received": 0, "percent_packet_loss": 100.0, + "result_code": 0, } acc.AssertContainsTaggedFields(t, "ping", fields, tags) } diff --git a/plugins/inputs/ping/ping_windows.go b/plugins/inputs/ping/ping_windows.go index 1c83ee84e..9645d175a 100644 --- a/plugins/inputs/ping/ping_windows.go +++ b/plugins/inputs/ping/ping_windows.go @@ -4,6 +4,7 @@ package ping import ( "errors" + "net" "os/exec" "regexp" "strconv" @@ -158,6 +159,18 @@ func (p *Ping) Gather(acc telegraf.Accumulator) error { wg.Add(1) go func(u string) { defer wg.Done() + + tags := map[string]string{"url": u} + fields := map[string]interface{}{"result_code": 0} + + _, err := net.LookupHost(u) + if err != nil { + errorChannel <- err + fields["result_code"] = 1 + acc.AddFields("ping", fields, tags) + return + } + args := p.args(u) totalTimeout := p.timeout() * float64(p.Count) out, err := p.pingHost(totalTimeout, args...) @@ -167,7 +180,6 @@ func (p *Ping) Gather(acc telegraf.Accumulator) error { // Combine go err + stderr output pendingError = errors.New(strings.TrimSpace(out) + ", " + err.Error()) } - tags := map[string]string{"url": u} trans, recReply, receivePacket, avg, min, max, err := processPingOutput(out) if err != nil { // fatal error @@ -175,24 +187,20 @@ func (p *Ping) Gather(acc telegraf.Accumulator) error { errorChannel <- pendingError } errorChannel <- err - fields := map[string]interface{}{ - "errors": 100.0, - } + fields["errors"] = 100.0 acc.AddFields("ping", fields, tags) - return } // Calculate packet loss percentage lossReply := float64(trans-recReply) / float64(trans) * 100.0 lossPackets := float64(trans-receivePacket) / float64(trans) * 100.0 - fields := map[string]interface{}{ - "packets_transmitted": trans, - "reply_received": recReply, - "packets_received": receivePacket, - "percent_packet_loss": lossPackets, - "percent_reply_loss": lossReply, - } + + fields["packets_transmitted"] = trans + fields["reply_received"] = recReply + fields["packets_received"] = receivePacket + fields["percent_packet_loss"] = lossPackets + fields["percent_reply_loss"] = lossReply if avg > 0 { fields["average_response_ms"] = float64(avg) } diff --git a/plugins/inputs/ping/ping_windows_test.go b/plugins/inputs/ping/ping_windows_test.go index aa7bc064b..178e42fcb 100644 --- a/plugins/inputs/ping/ping_windows_test.go +++ b/plugins/inputs/ping/ping_windows_test.go @@ -4,9 +4,10 @@ package ping import ( "errors" + "testing" + "github.com/influxdata/telegraf/testutil" "github.com/stretchr/testify/assert" - "testing" ) // Windows ping format ( should support multilanguage ?) @@ -81,6 +82,7 @@ func TestPingGather(t *testing.T) { "average_response_ms": 50.0, "minimum_response_ms": 50.0, "maximum_response_ms": 52.0, + "result_code": 0, } acc.AssertContainsTaggedFields(t, "ping", fields, tags) @@ -121,6 +123,7 @@ func TestBadPingGather(t *testing.T) { "reply_received": 0, "percent_packet_loss": 100.0, "percent_reply_loss": 100.0, + "result_code": 0, } acc.AssertContainsTaggedFields(t, "ping", fields, tags) } @@ -167,6 +170,7 @@ func TestLossyPingGather(t *testing.T) { "average_response_ms": 115.0, "minimum_response_ms": 114.0, "maximum_response_ms": 119.0, + "result_code": 0, } acc.AssertContainsTaggedFields(t, "ping", fields, tags) } @@ -269,6 +273,7 @@ func TestUnreachablePingGather(t *testing.T) { "reply_received": 0, "percent_packet_loss": 75.0, "percent_reply_loss": 100.0, + "result_code": 0, } acc.AssertContainsTaggedFields(t, "ping", fields, tags) @@ -315,6 +320,7 @@ func TestTTLExpiredPingGather(t *testing.T) { "reply_received": 0, "percent_packet_loss": 75.0, "percent_reply_loss": 100.0, + "result_code": 0, } acc.AssertContainsTaggedFields(t, "ping", fields, tags)