Fix problem with metrics when ping return Destination net unreachable ( windows ) (#1561)
* Fix problem with metrics when ping return Destination net unreachable Add test case TestUnreachablePingGather Add percent_reply_loss Fix some other tests * Add errors measurment * fir problem with ping reply "TTL expired in transit" ( use regex for more specific condition - TTL in line but it's a not valid replay ) add test case for "TTL expired in transit" - TestTTLExpiredPingGather
This commit is contained in:
committed by
Cameron Sparr
parent
53e31cf1b5
commit
3853d0d065
@@ -65,16 +65,20 @@ func hostPinger(timeout float64, args ...string) (string, error) {
|
||||
|
||||
// processPingOutput takes in a string output from the ping command
|
||||
// based on linux implementation but using regex ( multilanguage support ) ( shouldn't affect the performance of the program )
|
||||
// It returns (<transmitted packets>, <received packets>, <average response>, <min response>, <max response>)
|
||||
func processPingOutput(out string) (int, int, int, int, int, error) {
|
||||
// It returns (<transmitted packets>, <received reply>, <received packet>, <average response>, <min response>, <max response>)
|
||||
func processPingOutput(out string) (int, int, int, int, int, int, error) {
|
||||
// So find a line contain 3 numbers except reply lines
|
||||
var stats, aproxs []string = nil, nil
|
||||
err := errors.New("Fatal error processing ping output")
|
||||
stat := regexp.MustCompile(`=\W*(\d+)\D*=\W*(\d+)\D*=\W*(\d+)`)
|
||||
aprox := regexp.MustCompile(`=\W*(\d+)\D*ms\D*=\W*(\d+)\D*ms\D*=\W*(\d+)\D*ms`)
|
||||
tttLine := regexp.MustCompile(`TTL=\d+`)
|
||||
lines := strings.Split(out, "\n")
|
||||
var receivedReply int = 0
|
||||
for _, line := range lines {
|
||||
if !strings.Contains(line, "TTL") {
|
||||
if tttLine.MatchString(line) {
|
||||
receivedReply++
|
||||
} else {
|
||||
if stats == nil {
|
||||
stats = stat.FindStringSubmatch(line)
|
||||
}
|
||||
@@ -86,35 +90,35 @@ func processPingOutput(out string) (int, int, int, int, int, error) {
|
||||
|
||||
// stats data should contain 4 members: entireExpression + ( Send, Receive, Lost )
|
||||
if len(stats) != 4 {
|
||||
return 0, 0, 0, 0, 0, err
|
||||
return 0, 0, 0, 0, 0, 0, err
|
||||
}
|
||||
trans, err := strconv.Atoi(stats[1])
|
||||
if err != nil {
|
||||
return 0, 0, 0, 0, 0, err
|
||||
return 0, 0, 0, 0, 0, 0, err
|
||||
}
|
||||
rec, err := strconv.Atoi(stats[2])
|
||||
receivedPacket, err := strconv.Atoi(stats[2])
|
||||
if err != nil {
|
||||
return 0, 0, 0, 0, 0, err
|
||||
return 0, 0, 0, 0, 0, 0, err
|
||||
}
|
||||
|
||||
// aproxs data should contain 4 members: entireExpression + ( min, max, avg )
|
||||
if len(aproxs) != 4 {
|
||||
return trans, rec, 0, 0, 0, err
|
||||
return trans, receivedReply, receivedPacket, 0, 0, 0, err
|
||||
}
|
||||
min, err := strconv.Atoi(aproxs[1])
|
||||
if err != nil {
|
||||
return trans, rec, 0, 0, 0, err
|
||||
return trans, receivedReply, receivedPacket, 0, 0, 0, err
|
||||
}
|
||||
max, err := strconv.Atoi(aproxs[2])
|
||||
if err != nil {
|
||||
return trans, rec, 0, 0, 0, err
|
||||
return trans, receivedReply, receivedPacket, 0, 0, 0, err
|
||||
}
|
||||
avg, err := strconv.Atoi(aproxs[3])
|
||||
if err != nil {
|
||||
return 0, 0, 0, 0, 0, err
|
||||
return 0, 0, 0, 0, 0, 0, err
|
||||
}
|
||||
|
||||
return trans, rec, avg, min, max, err
|
||||
return trans, receivedReply, receivedPacket, avg, min, max, err
|
||||
}
|
||||
|
||||
func (p *Ping) timeout() float64 {
|
||||
@@ -159,21 +163,30 @@ func (p *Ping) Gather(acc telegraf.Accumulator) error {
|
||||
pendingError = errors.New(strings.TrimSpace(out) + ", " + err.Error())
|
||||
}
|
||||
tags := map[string]string{"url": u}
|
||||
trans, rec, avg, min, max, err := processPingOutput(out)
|
||||
trans, recReply, receivePacket, avg, min, max, err := processPingOutput(out)
|
||||
if err != nil {
|
||||
// fatal error
|
||||
if pendingError != nil {
|
||||
errorChannel <- pendingError
|
||||
}
|
||||
errorChannel <- err
|
||||
fields := map[string]interface{}{
|
||||
"errors": 100.0,
|
||||
}
|
||||
|
||||
acc.AddFields("ping", fields, tags)
|
||||
|
||||
return
|
||||
}
|
||||
// Calculate packet loss percentage
|
||||
loss := float64(trans-rec) / float64(trans) * 100.0
|
||||
lossReply := float64(trans-recReply) / float64(trans) * 100.0
|
||||
lossPackets := float64(trans-receivePacket) / float64(trans) * 100.0
|
||||
fields := map[string]interface{}{
|
||||
"packets_transmitted": trans,
|
||||
"packets_received": rec,
|
||||
"percent_packet_loss": loss,
|
||||
"reply_received": recReply,
|
||||
"packets_received": receivePacket,
|
||||
"percent_packet_loss": lossPackets,
|
||||
"percent_reply_loss": lossReply,
|
||||
}
|
||||
if avg > 0 {
|
||||
fields["average_response_ms"] = avg
|
||||
|
||||
Reference in New Issue
Block a user