From 90ad83fbd077ed1b11c647cf3e305c0103b017d5 Mon Sep 17 00:00:00 2001 From: Erik Auerswald Date: Tue, 30 Apr 2024 17:55:30 +0200 Subject: [PATCH] Print cumulative stats with -Q SECS,cumulative With -Q SECS, fping emits information for the just finished interval. This is good for long-running fping processes where one would like to get an update on recent results, ignoring missing responses from older intervals. This seems appropriate for use with other software like netdata or smokeping. But for short(er)-running fping processes, e.g., during a change window, it may be more interesting to get a status update since the beginning of the change window, i.e., the start of fping. Adding a comma followed by the keyword "cumulative" to -Q SECS (i.e., -Q SECS,cumulative) changes the interim reports to output the current per system overall statistics, unless -N is used, too. The new syntax is documented in fping.pod and added to fping -h output. Four tests are added: 1. Characters after SECS are ignored as before. 2. Unknown keywords are ignored as before. 2. Adding ",cumulative" changes -Q output. 3. Adding ",cumulative" also affects the additional -o output. This addresses issue #243. --- ci/test-08-options-n-q.pl | 54 ++++++++++++++++++++++++++++++++++++++- doc/fping.pod | 5 ++-- src/fping.c | 16 ++++++++++-- 3 files changed, 70 insertions(+), 5 deletions(-) diff --git a/ci/test-08-options-n-q.pl b/ci/test-08-options-n-q.pl index a201162..32630d0 100755 --- a/ci/test-08-options-n-q.pl +++ b/ci/test-08-options-n-q.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl -w -use Test::Command tests => 24; +use Test::Command tests => 36; # -n show targets by name (-d is equivalent) # -O n set the type of service (tos) flag on the ICMP packets @@ -81,6 +81,45 @@ $cmd->stderr_like(qr{\[\d+:\d+:\d+\] }); } +# fping -Q n ignores non-number characters after the number, except for keywords +{ +my $cmd = Test::Command->new(cmd => "fping -Q 1whatever -p 550 -c 5 127.0.0.1"); +$cmd->exit_is_num(0); +$cmd->stdout_is_eq(""); +$cmd->stderr_like(qr{\[\d+:\d+:\d+\] +127\.0\.0\.1 : xmt/rcv/%loss = 2/2/0%, min/avg/max = \d\.\d+/\d\.\d+/\d\.\d+ +\[\d+:\d+:\d+\] +127\.0\.0\.1 : xmt/rcv/%loss = 2/2/0%, min/avg/max = \d\.\d+/\d\.\d+/\d\.\d+ +127\.0\.0\.1 : xmt/rcv/%loss = 5/5/0%, min/avg/max = \d\.\d+/\d\.\d+/\d\.\d+ +}); +} + +# fping -Q n ignores unknown keywords +{ +my $cmd = Test::Command->new(cmd => "fping -Q 1,not_a_keyword -p 550 -c 5 127.0.0.1"); +$cmd->exit_is_num(0); +$cmd->stdout_is_eq(""); +$cmd->stderr_like(qr{\[\d+:\d+:\d+\] +127\.0\.0\.1 : xmt/rcv/%loss = 2/2/0%, min/avg/max = \d\.\d+/\d\.\d+/\d\.\d+ +\[\d+:\d+:\d+\] +127\.0\.0\.1 : xmt/rcv/%loss = 2/2/0%, min/avg/max = \d\.\d+/\d\.\d+/\d\.\d+ +127\.0\.0\.1 : xmt/rcv/%loss = 5/5/0%, min/avg/max = \d\.\d+/\d\.\d+/\d\.\d+ +}); +} + +# fping -Q n,cumulative +{ +my $cmd = Test::Command->new(cmd => "fping -Q 1,cumulative -p 550 -c 5 127.0.0.1"); +$cmd->exit_is_num(0); +$cmd->stdout_is_eq(""); +$cmd->stderr_like(qr{\[\d+:\d+:\d+\] +127\.0\.0\.1 : xmt/rcv/%loss = 2/2/0%, min/avg/max = \d\.\d+/\d\.\d+/\d\.\d+ +\[\d+:\d+:\d+\] +127\.0\.0\.1 : xmt/rcv/%loss = 4/4/0%, min/avg/max = \d\.\d+/\d\.\d+/\d\.\d+ +127\.0\.0\.1 : xmt/rcv/%loss = 5/5/0%, min/avg/max = \d\.\d+/\d\.\d+/\d\.\d+ +}); +} + # fping -Q -o { my $cmd = Test::Command->new(cmd => "fping -c4 -Q1 -p550 -o 8.8.8.7"); @@ -94,3 +133,16 @@ $cmd->stderr_like(qr{\[\d+:\d+:\d+\] }); } +# fping -Q n,cumulative -o +{ +my $cmd = Test::Command->new(cmd => "fping -c4 -Q1,cumulative -p550 -o 8.8.8.7"); +$cmd->exit_is_num(1); +$cmd->stdout_is_eq(""); +$cmd->stderr_like(qr{\[\d+:\d+:\d+\] +8\.8\.8\.7 : xmt/rcv/%loss = 1/0/100%, outage\(ms\) = 55\d +\[\d+:\d+:\d+\] +8\.8\.8\.7 : xmt/rcv/%loss = 3/0/100%, outage\(ms\) = 165\d +8\.8\.8\.7 : xmt/rcv/%loss = 4/0/100%, outage\(ms\) = 220\d +}); +} + diff --git a/doc/fping.pod b/doc/fping.pod index d293fcd..efb1410 100644 --- a/doc/fping.pod +++ b/doc/fping.pod @@ -180,10 +180,11 @@ an individual target. Default is 1000 and minimum is 10. Quiet. Don't show per-probe results, but only the final summary. Also don't show ICMP error messages. -=item B<-Q>, B<--squiet>=I +=item B<-Q>, B<--squiet>=I Like B<-q>, but additionally show interval summary results every I -seconds. +seconds. With I, show summary results since start instead of +for the last interval, unless option B<-N> is used, too. =item B<-r>, B<--retry>=I diff --git a/src/fping.c b/src/fping.c index 779836a..c58e20c 100644 --- a/src/fping.c +++ b/src/fping.c @@ -358,6 +358,7 @@ int multif_flag, timeout_flag, fast_reachable; int outage_flag = 0; int timestamp_flag = 0; int random_data_flag = 0; +int cumulative_stats_flag = 0; #if defined(DEBUG) || defined(_DEBUG) int randomly_lose_flag, trace_flag, print_per_system_flag; int lose_factor; @@ -677,6 +678,14 @@ int main(int argc, char **argv) } report_interval = opt_value_float * 1e9; + /* recognize keyword(s) after number, ignore everything else */ + { + char *comma = strchr(optparse_state.optarg, ','); + if ((comma != NULL) && (strcmp(++comma, "cumulative") == 0)) { + cumulative_stats_flag = 1; + } + } + break; case 'e': @@ -1813,7 +1822,9 @@ void print_per_system_splits(void) } fprintf(stderr, "\n"); - stats_reset_interval(h); + if (!cumulative_stats_flag) { + stats_reset_interval(h); + } } } @@ -2986,7 +2997,8 @@ void usage(int is_error) fprintf(out, " -N, --netdata output compatible for netdata (-l -Q are required)\n"); fprintf(out, " -o, --outage show the accumulated outage time (lost packets * packet interval)\n"); fprintf(out, " -q, --quiet quiet (don't show per-target/per-ping results)\n"); - fprintf(out, " -Q, --squiet=SECS same as -q, but add interval summary every SECS seconds\n"); + fprintf(out, " -Q, --squiet=SECS[,cumulative] same as -q, but add interval summary every SECS seconds,\n"); + fprintf(out, " with 'cumulative', print stats since beginning\n"); fprintf(out, " -s, --stats print final stats\n"); fprintf(out, " -u, --unreach show targets that are unreachable\n"); fprintf(out, " -v, --version show version\n");