Skip to content
Snippets Groups Projects
Commit 5d1efdbf authored by Heston Kan's avatar Heston Kan Committed by Daniel Nelson
Browse files

Add min/max response time on linux/darwin to ping (#2908)

parent e3ccd473
No related branches found
No related tags found
No related merge requests found
......@@ -83,7 +83,7 @@ func (p *Ping) Gather(acc telegraf.Accumulator) error {
strings.TrimSpace(out) + ", " + err.Error()))
}
tags := map[string]string{"url": u}
trans, rec, avg, stddev, err := processPingOutput(out)
trans, rec, min, avg, max, stddev, err := processPingOutput(out)
if err != nil {
// fatal error
acc.AddError(err)
......@@ -96,9 +96,15 @@ func (p *Ping) Gather(acc telegraf.Accumulator) error {
"packets_received": rec,
"percent_packet_loss": loss,
}
if min > 0 {
fields["minimum_response_ms"] = min
}
if avg > 0 {
fields["average_response_ms"] = avg
}
if max > 0 {
fields["maximum_response_ms"] = max
}
if stddev > 0 {
fields["standard_deviation_ms"] = stddev
}
......@@ -158,9 +164,9 @@ func (p *Ping) args(url string) []string {
// round-trip min/avg/max/stddev = 34.843/43.508/52.172/8.664 ms
//
// It returns (<transmitted packets>, <received packets>, <average response>)
func processPingOutput(out string) (int, int, float64, float64, error) {
func processPingOutput(out string) (int, int, float64, float64, float64, float64, error) {
var trans, recv int
var avg, stddev float64
var min, avg, max, stddev float64
// Set this error to nil if we find a 'transmitted' line
err := errors.New("Fatal error processing ping output")
lines := strings.Split(out, "\n")
......@@ -172,23 +178,25 @@ func processPingOutput(out string) (int, int, float64, float64, error) {
// Transmitted packets
trans, err = strconv.Atoi(strings.Split(stats[0], " ")[0])
if err != nil {
return trans, recv, avg, stddev, err
return trans, recv, min, avg, max, stddev, err
}
// Received packets
recv, err = strconv.Atoi(strings.Split(stats[1], " ")[0])
if err != nil {
return trans, recv, avg, stddev, err
return trans, recv, min, avg, max, stddev, err
}
} else if strings.Contains(line, "min/avg/max") {
stats := strings.Split(line, " ")[3]
min, err = strconv.ParseFloat(strings.Split(stats, "/")[0], 64)
avg, err = strconv.ParseFloat(strings.Split(stats, "/")[1], 64)
max, err = strconv.ParseFloat(strings.Split(stats, "/")[2], 64)
stddev, err = strconv.ParseFloat(strings.Split(stats, "/")[3], 64)
if err != nil {
return trans, recv, avg, stddev, err
return trans, recv, min, avg, max, stddev, err
}
}
}
return trans, recv, avg, stddev, err
return trans, recv, min, avg, max, stddev, err
}
func init() {
......
......@@ -48,25 +48,29 @@ ping: -i interval too short: Operation not permitted
// Test that ping command output is processed properly
func TestProcessPingOutput(t *testing.T) {
trans, rec, avg, stddev, err := processPingOutput(bsdPingOutput)
trans, rec, min, avg, max, stddev, err := processPingOutput(bsdPingOutput)
assert.NoError(t, err)
assert.Equal(t, 5, trans, "5 packets were transmitted")
assert.Equal(t, 5, rec, "5 packets were transmitted")
assert.InDelta(t, 15.087, min, 0.001)
assert.InDelta(t, 20.224, avg, 0.001)
assert.InDelta(t, 27.263, max, 0.001)
assert.InDelta(t, 4.076, stddev, 0.001)
trans, rec, avg, stddev, err = processPingOutput(linuxPingOutput)
trans, rec, min, avg, max, stddev, err = processPingOutput(linuxPingOutput)
assert.NoError(t, err)
assert.Equal(t, 5, trans, "5 packets were transmitted")
assert.Equal(t, 5, rec, "5 packets were transmitted")
assert.InDelta(t, 35.225, min, 0.001)
assert.InDelta(t, 43.628, avg, 0.001)
assert.InDelta(t, 51.806, max, 0.001)
assert.InDelta(t, 5.325, stddev, 0.001)
}
// Test that processPingOutput returns an error when 'ping' fails to run, such
// as when an invalid argument is provided
func TestErrorProcessPingOutput(t *testing.T) {
_, _, _, _, err := processPingOutput(fatalPingOutput)
_, _, _, _, _, _, err := processPingOutput(fatalPingOutput)
assert.Error(t, err, "Error was expected from processPingOutput")
}
......@@ -150,7 +154,9 @@ func TestPingGather(t *testing.T) {
"packets_transmitted": 5,
"packets_received": 5,
"percent_packet_loss": 0.0,
"minimum_response_ms": 35.225,
"average_response_ms": 43.628,
"maximum_response_ms": 51.806,
"standard_deviation_ms": 5.325,
}
acc.AssertContainsTaggedFields(t, "ping", fields, tags)
......@@ -188,7 +194,9 @@ func TestLossyPingGather(t *testing.T) {
"packets_transmitted": 5,
"packets_received": 3,
"percent_packet_loss": 40.0,
"minimum_response_ms": 35.225,
"average_response_ms": 44.033,
"maximum_response_ms": 51.806,
"standard_deviation_ms": 5.325,
}
acc.AssertContainsTaggedFields(t, "ping", fields, tags)
......@@ -244,6 +252,10 @@ func TestFatalPingGather(t *testing.T) {
"Fatal ping should not have packet measurements")
assert.False(t, acc.HasMeasurement("percent_packet_loss"),
"Fatal ping should not have packet measurements")
assert.False(t, acc.HasMeasurement("minimum_response_ms"),
"Fatal ping should not have packet measurements")
assert.False(t, acc.HasMeasurement("average_response_ms"),
"Fatal ping should not have packet measurements")
assert.False(t, acc.HasMeasurement("maximum_response_ms"),
"Fatal ping should not have packet measurements")
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment