Commit 5ee5ab8f authored by Olav Kvittem's avatar Olav Kvittem
Browse files

demper jitter rapportering hvis ikke endret. Mer effektiv historie med array...

demper jitter rapportering hvis ikke endret. Mer effektiv historie med array istedet for rescan av tekst-linjer.
parent a9d86dd8
......@@ -8,7 +8,7 @@ apt-get update
apt-get -y upgrade
package="mp-rude"
version="1.3.13"
version="1.3.14"
target="${package}_${version}_all"
......
......@@ -19,7 +19,7 @@ use constant JAN_1970 => 0x83aa7e80;
# use LWP::Protocol::https;
# date --date 'jan 1 2000' +%s
$version="0.9.9";
$version="0.1.1";
$min_tx=946681200;
$max_tx=1893452400; # 2030-01-01
$maxseqreorder=1000; #
......@@ -34,11 +34,16 @@ my %least_delay; # least delay observed
# parms for jitter report
my %n_normal=(); # count of normal packets for modulo
my $min_jit = 5; # jitter in ms
my $min_jit = 1; # jitter in ms
my $min_ddelay = 5;
my $min_slope=0.2;
my $jitter_delta={'jit'=> $min_jit/5, 'ddelay'=> $min_ddelay/5, 'slope'=>$min_slope/5};
my $jitter_period=60; # seconds between jitter reports
my %jitter_last=();
my %jitter_last=(); # last time jitter reported
my %jitter_values=(); # last jitter values reported
my %mindelay; # minimum delay last slep
my %minseq; # minimum delay last slep
$usage="$0 '[-title text] [-minloss n] [-win n] [-graph file] [max-small-graphs n] [-outdir dir] [-head|-rhead] [-id id] [-names file] [-json file] [-v] [-version] [-esmond url] [file]...
Analyse gaps in a crude packet log
......@@ -53,6 +58,7 @@ Parameters
-owamp url - get json owamp data from pscheduler
-json file - filename to store json event documents (intended for logstash ?)
-jitter secs - emit jitter stats with secs interval
-threshold - jitter,ddelay,slope - threshold values for reporting
";
my $opt_h, $opt_help, $opt_id, $opt_slep, $opt_minloss, $opt_win, $opt_max-small-graphs, $opt_head, $opt_rhead, $opt_graph, $opt_outdir, $opt_title, $opt_names, $opt_owamp, $opt_json, $opt_jitter, $opt_index, $opt_v, $opt_version;
......@@ -61,7 +67,8 @@ GetOptions( 'h' => \$opt_h, 'help' => \$opt_help, 'id=s' => \$opt_id, 'slep=s' =
'minloss=s' => \$opt_minloss, 'win=s' => \$opt_win, 'max-small-graphs=s' => \$opt_max-small-graphs,
'head' => \$opt_head, 'rhead' => \$opt_rhead, 'graph=s' => \$opt_graph, 'outdir=s' => \$opt_outdir,
'title=s' => \$opt_title, 'names=s' => \$opt_names, 'json=s' => \$opt_json, 'index=s' => \$opt_index,
'jitter=s' => \$opt_jitter, 'owamp=s' => \$opt_owamp, 'v' => \$opt_v, 'version' => \$opt_version )
'jitter=s' => \$opt_jitter, 'threshold' => \$opt_threshold, 'owamp=s' => \$opt_owamp,
'v' => \$opt_v, 'version' => \$opt_version )
or die $usage;
# &NGetOpt( 'h', 'help', 'id=s', 'slep=s', 'minloss=s', 'win=s', 'max-small-graphs=s', 'head', 'rhead', 'graph=s', 'outdir=s', 'title=s', 'names=s', 'json=s', 'index=s', 'v', 'version') || die "$!" . $usage ."\n";
......@@ -80,6 +87,9 @@ if ($opt_owamp){
# require perfSONAR_PS::Client::Esmond::ApiConnect;
}
if ($opt_threshold){
( $min_jit, $min_dddelay, $min_slope) = split(',', $opt_threshold);
}
$jitter_period= $opt_jitter if $opt_jitter;
......@@ -295,6 +305,7 @@ sub emit_json{
$to=$hostname{$dst_adr{$id}}
} else {
$to=`hostname`; chomp($to);
$hostname{$dst_adr{$id}}=$to;
}
my @gt=gmtime $tunix;
my $datems= sprintf "%s.%03d", strftime("%Y-%m-%dT%T", @gt), int( $tunix * 1000 ) % 1000 ;
......@@ -406,13 +417,13 @@ sub read_crude {
while(<>){
if ( /crude version 0.9.0/){
if ( $. <= 1 && /^crude version 0.9.0/){
# die "### Versjon med feil i Rx : $_";
}
my $seq;
if ( /crude version/){ # new file restart sequence control
undef %pseq, %selp, %gap_slep;
undef %pseq, %slep, %gap_slep, %slep_data, %gap_data;
} elsif ( ( ($rudeid,$seq, $src, $dst, $tx, $rx, $size) = /^ID=(\d+) SEQ=(\d+) SRC=([\w\:\.]+):\d+ DST=([\w\:\.]+):\d+.*Tx=([\d\.]+) .*Rx=([\d\.]+) .*SIZE=(\d+)/ )
|| ( ($seq, $tx, $ssync, $serr, $rx, $rsync, $rerr, $ttl) = /$owamp_fmt/ )
|| ( ($seq, $src, $tx, $rx) = /$bv_fmt/ )
......@@ -506,12 +517,14 @@ sub analyze_packet {
for ($lno=0; $lno <= $#{$gap_slep{$id}}; $lno++){
push( @{$slep{$id}}, $gap_slep{$id}[$lno] );
push( @{$slep_data{$id}}, $gap_data{$id}[$lno] );
$nslep{$id}++;
}
} else { # ignore when too many gaps
$dropped_gaps{$id}{$gap_type}++;
}
$gap_slep{$id}=[]; # copied - blank it.
$gap_data{$id}=[]; # copied - blank it.
$ntail_seq{$id}=0; #
}
......@@ -559,6 +572,7 @@ sub analyze_packet {
$ntail_seq{$id} = 1; # restart this if there are more holes
}
$gap_slep{$id}=[];
$gap_data{$id}=[];
$nbig_gaps{$id}++;
$big_gaps{$id}+=$dseq-1;
$big_time{$id}+=$tx-$ptx{$id};
......@@ -585,10 +599,13 @@ sub analyze_packet {
# if ( $dt == 0 || $dt <= $late_delay ){ # buffer lines
if ( $bufferit){
$data={'tx'=>$tx, 'rx'=>$rx,'delay'=>$dt,'seq'=>$seq};
if ( $in_gap{$id} > 0 ){ # during gap
push(@{$gap_slep{$id}}, $_);
push(@{$gap_data{$id}}, $data );
} else {
push(@{$slep{$id}},$_);
push(@{$slep_data{$id}}, $data );
$nslep{$id}++;
while ( $nslep{$id} > $maxslep){
shift @{$slep{$id}};
......@@ -613,7 +630,7 @@ sub analyze_packet {
if ($nbreak{$id} > 0 && ($ntail{$id}[0] >= $maxtail)){
my $head=shift(@{$head1{$id}});
push(@{$tail{$id}}, report_delay( $id, 'tail', \@slep{$id}), 0, 0);
push(@{$tail{$id}}, report_delay( $id, 'tail', \@slep_data{$id}), 0, 0);
$print_line.= sprintf "%s overlap %8d %2d ", $head, $head_seq{$id}, $#{$ntail{$id}}+1;
shift(@{$ntail{$id}});
&emit_stats($id);
......@@ -624,17 +641,51 @@ sub analyze_packet {
# }
}
################################################################################
# find minimum of a member var in an array of hashes
sub get_min {
my ( $var, $refd)=@_;
my $min;
my $rd=$$refd;
foreach $rd (@$rd ){
$min = $rd->{$var} if ! $rd->{$var} || $rd->{$var} < $min;
}
return $min;
}
################################################################################
# keep track of last jitter reports
sub jitter_change {
my ( $id, $jit, $ddelay, $slope)=@_;
if (! defined($jitter_values{$id})
|| val_change( $id, 'jit', $jit)
|| val_change( $id, 'ddelay', $ddelay)
|| val_change( $id, 'slope', $slope)
){
$jitter_values{$id}={'jit'=> $jit, 'ddelay'=> $ddelay, 'slope'=> $slope};
return 1;
}
return 0;
}
sub val_change{
my ($id, $var, $val)=@_;
if ( abs (abs $val - $jitter_values{$id}->{$var} ) > $jitter_delta->{$var} ){
return 1; # true
}
return 0; # false
}
################################################################################
sub check_jitter{
my $id = shift;
my $end=$#{$slep{$id}};
my $end=$#{$slep_data{$id}};
my $start = $end - $maxhead;
my $tstart;
if ( $start >= 0 ){
$tstart=$slep_data{$id}[$start]{tx};
if ( $start >= 0 && ( ($tstart) = $slep{$id}[$start] =~ /Tx=([\d\.]+)/ ) ) { # enough packets
my $l=report_delay( $id, 'stats', \@slep{$id}, NULL, 0);
my $l=report_delay( $id, 'stats', \@slep_data{$id}, NULL, 0);
$l=~s/^\s*//;
my ( $n, $jit, $ddelay, $delay, $min_d, $slope_10, $slope_20, $slope_30, $slope_40, $slope_50)
= split(/\s+/, $l );
......@@ -648,7 +699,7 @@ sub check_jitter{
$report_type='interval';
}
if ( $report_type eq 'interval' # periodic or by threshhold
if ( $report_type eq 'interval' && jitter_change( $id, $jit, $ddelay, $slope50) # periodic or by threshhold
|| ( abs $jit > $min_jit || $ddelay > $min_ddelay || abs $slope_50 > $min_slope ) ){ #
# emit_jitter_json(\$l);
my $json={
......@@ -702,7 +753,7 @@ sub emit_break_head {
$dseq-1, $dt*1000, $head_seq{$id}-$seq0{$id} );
push(@{$ntail{$id}}, 0); # remember this break
push(@{$head{$id}}, report_delay($id, 'head', \@slep{$id}, $tx1, $dt));
push(@{$head{$id}}, report_delay($id, 'head', \@slep_data{$id}, $tx1, $dt));
# @slep{$id}=();
# $nslep{$id}=0;
}
......@@ -774,25 +825,35 @@ sub emit_stats{
sub report_delay{ # jitter for one delay
my $id=shift;
my $type=shift; # head, tail
my $refl=shift; # array of lines
my $refd=shift; # array of data
my $txgap=shift;
my $dt=shift;
# my @l=@$$refl;
my $ptx=0, $prx=0, $sumjit=0, $njit=0, $ndelay=0, $sumdd=0, $sumdelay=0;
my $start=$#{$$refl}-$maxhead;
my $mindelay, $taildelay;
# my @l=@$$refd;
my $ptx=0, $prx=0, $sumjit=0, $njit=0, $sumdd=0, $sumdelay=0;
my $taildelay; # in tail/head
my @rdelay=(), @rtx=(), $tx0=0;
my @rrx=(), $rx0=0;
my $rudeid, $seq, $src, $dst, $tx, $rx, $size, $pseq;
foreach $i( 0 .. ($#$$refl - 0) ){ # skip the last one which might be after the gap
my $rline=\@$$refl[$i];
if ( ( ($rudeid, $seq, $src, $dst, $tx, $rx, $size)=
$$rline =~ /ID=(\d+)\s+SEQ=(\d+)\s+SRC=([\d.:]+)\s+DST=([\d.:]+)\s+Tx=([\d.,]+)\s+Rx=([\d.,]+).+SIZE=(\d+)/)
|| ( ($seq, $src, $tx, $rx) = $$rline =~ /$bv_fmt/ )
){
$delay=$rx-$tx;
$mindelay = $delay if !$mindelay || $delay < $mindelay;
my $start=$#{$$refd}-$maxhead;
foreach $i( $start .. ($#$$refd - 0) ){ # skip the last one which might be after the gap
my $rdata=\@$$refd[$i];
# if ( ( ($rudeid, $seq, $src, $dst, $tx, $rx, $size)=
# $$rline =~ /ID=(\d+)\s+SEQ=(\d+)\s+SRC=([\d.:]+)\s+DST=([\d.:]+)\s+Tx=([\d.,]+)\s+Rx=([\d.,]+).+SIZE=(\d+)/)
# || ( ($seq, $src, $tx, $rx) = $$rline =~ /$bv_fmt/ )
# ){
{
$delay=$$rdata->{delay};
$tx=$$rdata->{tx};
$rx=$$rdata->{rx};
$seq=$$rdata->{seq};
if ( !$mindelay{$id} || $delay < $mindelay{$id} ){ # minimum for slep
$mindelay{$id} = $delay;
$minseq{$id} = $seq;
}
if ( !$taildelay || $delay < $taildelay){
$taildelay = $delay;
}
......@@ -805,8 +866,6 @@ sub report_delay{ # jitter for one delay
$txgap=shift( @{$txgap{$id}} );
}
}
$sumdelay+=$delay;
$ndelay++;
if ($ptx && ($seq - $pseq) == 1){ # jitter for normal packets
$dtx=$tx-$ptx;
......@@ -814,6 +873,7 @@ sub report_delay{ # jitter for one delay
$jit=$drx-$dtx;
$sumjit += abs $jit;
$njit++;
$sumdelay+=$delay;
$sumdd+=$delay;
push(@rtx, ($tx-$tx0)*1000); #ms
push(@rrx, ($rx-$rx0)*1000); #ms
......@@ -826,13 +886,19 @@ sub report_delay{ # jitter for one delay
}
}
my $d=$$refd;
if ( $d->[0]{seq} > $minseq{$id} ){ # minimum of last maxslep packets
$mindelay{$id}=get_min('delay', $refd);
}
for ($i=0; $i<=$#rdelay; $i++){ # relative delay in ms
$rdelay[$i]=($rdelay[$i]-$mindelay)*1000;
$rdelay[$i]=($rdelay[$i]-$mindelay{$id})*1000;
}
$sumdd=$sumdd-$njit*$mindelay; # sum differences from minimum
$sumdd=$sumdd-$njit*$mindelay{$id}; # sum differences from minimum
if($njit> 0 && $ndelay > 0){
if($njit> 0 ){
$lineFit = Statistics::LineFit->new();
my @slope=(), $slopes=""; my $lr_start; my $lr_a; my $lr_b;
......@@ -879,7 +945,7 @@ sub report_delay{ # jitter for one delay
# virker ikke
# ($yfit, $coeffs) = fitpoly1d \@drtx, \@drdelay, 4; # Fit a cubi
if ($type eq 'stats' ){ # save on slope LR for jitter
if ($type eq 'stats' && 0 ){ # save on slope LR for jitter
$slope=$intercept=0;
} else {
$lineFit->setData ( \@drtx, \@drdelay );
......@@ -921,7 +987,7 @@ sub report_delay{ # jitter for one delay
$slopes=join(' ', @slope);
return sprintf "%3d %9.3f %9.3f %9.3f %9.3f %s", $njit, $sumjit/$njit*1000, $sumdd/$njit*1000,
$sumdelay/$ndelay*1000, $mindelay*1000, $slopes;
$sumdelay/$njit*1000, $mindelay{$id}*1000, $slopes;
} else {
return sprintf "%3d %5.3f %5.3f", 0, 0, 0;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment