diff --git a/LibreNMS/Data/Source/Fping.php b/LibreNMS/Data/Source/Fping.php index 79a4e5cd16..8c14afb9b8 100644 --- a/LibreNMS/Data/Source/Fping.php +++ b/LibreNMS/Data/Source/Fping.php @@ -117,7 +117,8 @@ class Fping $process->run(function ($type, $output) use ($callback, &$partial) { // stdout contains individual ping responses, stderr contains summaries if ($type == Process::ERR) { - foreach (explode(PHP_EOL, $output) as $line) { + $lines = explode(PHP_EOL, $output); + foreach ($lines as $index => $line) { if ($line) { Log::debug("Fping OUTPUT|$line PARTIAL|$partial"); try { @@ -125,8 +126,8 @@ class Fping call_user_func($callback, $response); $partial = ''; } catch (FpingUnparsableLine $e) { - // handle possible partial line - $partial = $e->unparsedLine; + // handle possible partial line (only save it if it is the last line of output) + $partial = $index === array_key_last($lines) ? $e->unparsedLine : ''; } } } diff --git a/tests/FpingTest.php b/tests/FpingTest.php index c7648bd195..b175b44333 100644 --- a/tests/FpingTest.php +++ b/tests/FpingTest.php @@ -154,6 +154,7 @@ OUT; $process->shouldReceive('getCommandLine'); $process->shouldReceive('run')->withArgs(function ($callback) { // simulate incremental output (not always one full line per callback) + call_user_func($callback, Process::ERR, "ICMP unreachable\n"); // this line should be ignored call_user_func($callback, Process::ERR, "192.168.1.4 : xmt/rcv/%loss = 3/3/0%, min/avg/max = 0.62/0.71/0.93\nhostname : xmt/rcv/%loss = 3/0/100%"); call_user_func($callback, Process::ERR, "invalid:characters!: Name or service not known\n\n1.1.1.1 : xmt/rcv/%loss = 3/2/33%"); call_user_func($callback, Process::ERR, ", min/avg/max = 0.024/0.037/0.054\n");