File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / scripts / plot_summary.in
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:38 2012 UTC (12 years, 1 month ago) by misho
Branches: ntp, MAIN
CVS tags: v4_2_6p5p0, v4_2_6p5, HEAD
ntp 4.2.6p5

    1: #! @PATH_PERL@ -w
    2: # $Id: plot_summary.in,v 1.1.1.1 2012/05/29 12:08:38 misho Exp $
    3: #
    4: # Use Gnuplot to display data in summary files produced by summary.pl.
    5: # This script requires GNUPLOT 3.7!
    6: #
    7: # Copyright (c) 1997, 1999 by Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de>
    8: #
    9: # This program is free software; you can redistribute it and/or modify
   10: # it under the terms of the GNU General Public License as published by
   11: # the Free Software Foundation; either version 2 of the License, or
   12: # (at your option) any later version.
   13: #
   14: # This program is distributed in the hope that it will be useful, but
   15: # WITHOUT ANY WARRANTY; without even the implied warranty of
   16: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   17: # General Public License for more details.
   18: #
   19: # You should have received a copy of the GNU General Public License
   20: # along with this program; if not, write to the Free Software
   21: # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   22: 
   23: require 5.003; # "never tested with any other version of Perl"
   24: use strict;
   25: 
   26: use Time::Local;
   27: use Getopt::Long;
   28: 
   29: # parse command line
   30: my $summary_dir = "/tmp";
   31: my $identifier = "host " . `hostname`;	# origin of these data
   32: chomp $identifier;			# remove newline
   33: my $offset_limit = 0.128;		# limit of absolute offset
   34: my $output_file = "";			# output file defaults to stdout
   35: my $output_file_number = 1;		# numbering of output files
   36: my $gnuplot_terminal = $ENV{DISPLAY} ? "x11" : "dumb";
   37: my $wait_after_plot = 1;
   38: my @peer_list = ();
   39: 
   40: my %options = ("directory|input-directory=s" => \$summary_dir,
   41: 	       "identifier=s" => \$identifier,
   42: 	       "offset-limit=f" => \$offset_limit,
   43: 	       "output-file=s" => \$output_file,
   44: 	       "peer=s@" => \@peer_list,
   45: 	       "plot-term|gnuplot-term=s" => \$gnuplot_terminal,
   46: 	       "wait-after-plot!" => \$wait_after_plot,
   47: 	       );
   48: 
   49: if ( !GetOptions(%options) )
   50: {
   51:     print STDERR "valid options for $0 are:\n";
   52:     my $opt;
   53:     foreach $opt (sort(keys %options)) {
   54: 	print STDERR "\t--$opt\t(default is ";
   55: 	if ( ref($options{$opt}) eq "ARRAY" ) {
   56: 	    print STDERR join(", ",  map { "'$_'" } @{$options{$opt}});
   57: 	} else {
   58: 	    print STDERR "'${$options{$opt}}'";
   59: 	}
   60: 	print STDERR ")\n";
   61:     }
   62:     print STDERR "\n";
   63:     die;
   64: }
   65: 
   66: chomp $identifier;
   67: die "illegal offset-limit: $offset_limit" unless $offset_limit > 0.0;
   68: $offset_limit *= 1e6;			# scale to microseconds
   69: 
   70: # return the smallest value in the given list
   71: sub min
   72: {
   73:     my ($result, @rest) = @_;
   74:     map { $result = $_ if ($_ < $result) } @rest;
   75:     return($result);
   76: }
   77: 
   78: # return the largest value in the given list
   79: sub max
   80: {
   81:     my ($result, @rest) = @_;
   82:     map { $result = $_ if ($_ > $result) } @rest;
   83:     return($result);
   84: }
   85: 
   86: # maybe open alternate output file
   87: sub open_output
   88: {
   89:     my $file;
   90:     if ($output_file) {
   91: 	while ( -r ($file = "$output_file$output_file_number") ) {
   92: 	    ++$output_file_number;
   93: 	}
   94: 	open TOUCH, ">$file" and close TOUCH or die "$file: $!";
   95: 	print "set output \"$file\"\n";
   96:     }
   97: }
   98: 
   99: # make Gnuplot wait
  100: sub maybe_add_pause
  101: {
  102:     print "pause -1 \"Press key to continue...\"\n" if $wait_after_plot;
  103: }
  104: 
  105: # plot data from loop summary
  106: sub do_loop
  107: {
  108:     my $fname = shift;
  109:     my $line;
  110:     my $out_file = "/tmp/tempdata$$";
  111:     my $cmd_file = "/tmp/tempcmd$$";
  112:     my ($first_day, $day_out) = ("", 0);
  113:     my ($lower_bound, $upper_bound, $rms);
  114:     my ($min_offs, $max_offs) = (1e9, -1e9);
  115:     my ($min_rms, $max_rms) = (1e9, -1e9);
  116:     open INPUT, "$fname" or die "$fname: $!";
  117:     open OUTPUT, ">$out_file" or die "$out_file: $!";
  118:     my @Fld;
  119:     while (<INPUT>) {
  120: 	chop;	# strip record separator
  121: 	@Fld = split;
  122: 	if ($#Fld == 0) {
  123: # loops.19960405
  124: 	    $_ = $Fld[0]; s/.*([12]\d{3}[01]\d[0-3]\d)$/$1/;
  125: 	    m/(\d{4})(\d{2})(\d{2})/;
  126: 	    $line = timegm(59, 59, 23, $3, $2 - 1, $1 - 1900, 0, 0, 0);
  127: 	    $line = int $line / 86400;	# days relative to 1970
  128: 	    $first_day = "$1-$2-$3 ($line)" unless $day_out;
  129: 	    next;
  130: 	}
  131: 	if ($#Fld != 8) {
  132: 	    warn "Illegal number of fields in file $fname, line $.";
  133: 	    next;
  134: 	}
  135: # loop 216, 856106+/-874041.5, rms 117239.8, freq 67.52+/-10.335, var 4.850
  136: 	$_ = $Fld[1]; s/,/ /; $line .= " $_";
  137: 	$_ = $Fld[2]; m:(.+?)\+/-(.+),:;
  138: 	$lower_bound = $1 - $2;
  139: 	$upper_bound = $1 + $2;
  140: 	$line .= "$1 $lower_bound $upper_bound";
  141: 	$min_offs = min($min_offs, $lower_bound);
  142: 	$max_offs = max($max_offs, $upper_bound);
  143: 	$_ = $Fld[4]; s/,/ /; $rms = $_;
  144: 	$min_rms = min($min_rms, $rms);
  145: 	$max_rms = max($max_rms, $rms);
  146: 	$line .= " $rms";
  147: 	$_ = $Fld[6]; m:(.+?)\+/-(.+),:;
  148: 	$line .= " $1 " . ($1-$2) . " " . ($1+$2);
  149: 	$line .= " $Fld[8]";
  150: 	print OUTPUT "$line\n";
  151: 	$day_out = 1;
  152: # 9621 216 856106 -17935.5 1730147.5 117239.8  67.52 57.185 77.855 4.850
  153:     }
  154:     close INPUT;
  155:     close OUTPUT or die "close failed on $out_file: $!";
  156:     my $ylimit = "[";
  157:     if ($min_offs < -$offset_limit) {
  158: 	$ylimit .= "-$offset_limit";
  159:     }
  160:     $ylimit .= ":";
  161:     if ($max_offs > $offset_limit) {
  162: 	$ylimit .= "$offset_limit";
  163:     }
  164:     if ( $ylimit eq "[:" ) {
  165: 	$ylimit = "";
  166:     } else {
  167: 	$ylimit = "[] $ylimit]";
  168:     }
  169: # build command file for GNUplot
  170:     open OUTPUT, "> $cmd_file" or die "$cmd_file: $!";
  171:     my $oldfh = select OUTPUT;
  172:     print "set term $gnuplot_terminal\n";
  173:     open_output;
  174:     print "set grid\n";
  175:     print "set title \"Loop Summary for $identifier: " .
  176: 	"Daily mean values since $first_day\\n" .
  177: 	"(Offset limit is $offset_limit microseconds)\"\n";
  178:     print "set ylabel \"[us]\"\n";
  179:     print "set data style yerrorbars\n";
  180:     print "set multiplot\n";
  181:     print "set size 1, 0.5\n";
  182:     print "set lmargin 8\n";
  183:     print "set origin 0, 0.5\n";
  184:     print "plot $ylimit \"$out_file\"" .
  185: 	" using 1:3:4:5 title \"mean offset\", ";
  186:     print "\"$out_file\" using 1:(\$3-\$6/2) " .
  187: 	"title \"(sigma low)\" with lines, ";
  188:     print "\"$out_file\" using 1:3 smooth bezier " .
  189: 	"title \"(Bezier med)\" with lines, ";
  190:     print "\"$out_file\" using 1:(\$3+\$6/2) " .
  191: 	"title \"(sigma high)\" with lines\n";
  192:     print "set ylabel \"[ppm]\"\n";
  193:     print "set origin 0, 0.0\n";
  194:     print "set title\n";
  195:     print "set xlabel \"Days relative to 1970\"\n";
  196:     print "plot \"$out_file\" using 1:7:8:9 title \"mean frequency\", ";
  197:     print "\"$out_file\" using 1:(\$7-\$10/2) " .
  198: 	"title \"(sigma low)\" with lines, ";
  199:     print "\"$out_file\" using 1:7 smooth bezier " .
  200: 	"title \"(Bezier med)\" with lines, ";
  201:     print "\"$out_file\" using 1:(\$7+\$10/2) " .
  202: 	"title \"(sigma high)\" with lines\n";
  203:     print "set nomultiplot\n";
  204:     maybe_add_pause;
  205: 
  206:     $ylimit = "[";
  207:     if ($min_rms < -$offset_limit) {
  208: 	$ylimit .= "-$offset_limit";
  209:     }
  210:     $ylimit .= ":";
  211:     if ($max_rms > $offset_limit) {
  212: 	$ylimit .= "$offset_limit";
  213:     }
  214:     if ( $ylimit eq "[:" ) {
  215: 	$ylimit ="";
  216:     } else {
  217: 	$ylimit = "[] $ylimit]";
  218:     }
  219: 
  220:     open_output;
  221:     print "set title \"Loop Summary for $identifier: " .
  222: 	"Standard deviation since $first_day\\n" .
  223: 	"(Offset limit is $offset_limit microseconds)\"\n";
  224:     print "set xlabel\n";
  225:     print "set ylabel \"[us]\"\n";
  226:     print "set origin 0, 0.5\n";
  227:     print "set data style linespoints\n";
  228:     print "set multiplot\n";
  229:     print "plot $ylimit \"$out_file\" using 1:6 title \"Offset\", ";
  230:     print "\"$out_file\" using 1:6 smooth bezier " .
  231: 	"title \"(Bezier)\" with lines\n";
  232:     print "set title\n";
  233:     print "set origin 0, 0.0\n";
  234:     print "set xlabel \"Days relative to 1970\"\n";
  235:     print "set ylabel \"[ppm]\"\n";
  236:     print "plot \"$out_file\" using 1:10 title \"Frequency\", ";
  237:     print "\"$out_file\" using 1:10 smooth bezier " .
  238: 	"title \"(Bezier)\" with lines\n";
  239:     print "set nomultiplot\n";
  240:     maybe_add_pause;
  241: 
  242:     close OUTPUT or die "close failed on $cmd_file: $!";
  243:     select $oldfh;
  244:     print `gnuplot $cmd_file`;
  245:     unlink $cmd_file;
  246:     unlink $out_file;
  247: }
  248: 
  249: # plot data form peer summary
  250: sub do_peer
  251: {
  252:     my $fname = shift;
  253:     my $peer = shift;
  254:     my $out_file = "/tmp/tempdata$$";
  255:     my $cmd_file = "/tmp/tempcmd$$";
  256:     my $line;
  257:     my ($first_day, $day_out) = ("", 0);
  258:     open INPUT, "$fname" or die "$fname: $!";
  259:     open OUTPUT, ">$out_file" or die "$out_file: $!";
  260:     my @Fld;
  261:     while (<INPUT>) {
  262: 	chop;	# strip record separator
  263: 	@Fld = split;
  264: 	if ($#Fld == 0) {
  265: # peers.19960405
  266: 	    $_ = $Fld[0]; s/.*([12]\d{3}[01]\d[0-3]\d)$/$1/;
  267: 	    m/(\d{4})(\d{2})(\d{2})/ or next;
  268: 	    $line = timegm(59, 59, 23, $3, $2 - 1, $1 - 1900, 0, 0, 0);
  269: 	    $line = int $line / 86400;	# days relative to 1970
  270: 	    $first_day = "$1-$2-$3 ($line)" unless $day_out;
  271: 	    next;
  272: 	}
  273: 	if ($#Fld != 7) {
  274: 	    warn "Illegal number of fields in file $fname, line $.";
  275: 	    next;
  276: 	}
  277: 	next if ($Fld[0] ne $peer);
  278: #       ident     cnt     mean     rms      max     delay     dist     disp
  279: # 127.127.8.1       38   30.972  189.867 1154.607    0.000  879.760  111.037
  280: 	$Fld[0] = $line;
  281: 	print OUTPUT join(' ', @Fld) . "\n";
  282: # 9969 38 30.972 189.867 1154.607 0.000 879.760 111.037
  283: 	$day_out = 1;
  284:     }
  285:     close INPUT;
  286:     close OUTPUT or die "close failed on $out_file: $!";
  287:     die "no data found for peer $peer" if !$day_out;
  288:     open OUTPUT, "> $cmd_file" or die "$cmd_file: $!";
  289:     my $oldfh = select OUTPUT;
  290:     print "set term $gnuplot_terminal\n";
  291:     open_output;
  292:     print "set grid\n";
  293:     print "set multiplot\n";
  294:     print "set lmargin 8\n";
  295:     print "set size 1, 0.34\n";
  296:     print "set origin 0, 0.66\n";
  297:     print "set title " .
  298: 	"\"Peer Summary for $peer on $identifier since $first_day\"\n";
  299:     print "set data style linespoints\n";
  300:     print "set ylabel \"[us]\"\n";
  301:     print "plot \"$out_file\" using 1:3 title \"mean offset\", ";
  302:     print "\"$out_file\" using 1:3 smooth bezier " .
  303: 	"title \"(Bezier)\" with lines, ";
  304:     print "\"$out_file\" using 1:(\$3-\$7/2) " .
  305: 	"title \"(sigma low)\" with lines, ";
  306:     print "\"$out_file\" using 1:(\$3+\$7/2) " .
  307: 	"title \"(sigma high)\" with lines\n";
  308:     print "set title\n";
  309:     print "set origin 0, 0.34\n";
  310:     print "set size 1, 0.32\n";
  311:     print "set ylabel\n";
  312:     print "plot \"$out_file\" using 1:7 title \"dist\", ";
  313:     print "\"$out_file\" using 1:7 smooth bezier " .
  314: 	"title \"(Bezier)\" with lines\n";
  315:     print "set origin 0, 0.00\n";
  316:     print "set size 1, 0.35\n";
  317:     print "set xlabel \"Days relative to 1970\"\n";
  318:     print "plot \"$out_file\" using 1:8 title \"disp\", ";
  319:     print "\"$out_file\" using 1:8 smooth bezier " .
  320: 	"title \"(Bezier)\" with lines\n";
  321:     print "set nomultiplot\n";
  322:     maybe_add_pause;
  323: 
  324:     select $oldfh;
  325:     close OUTPUT or die "close failed on $cmd_file: $!";
  326:     print `gnuplot $cmd_file`;
  327:     unlink $cmd_file;
  328:     unlink $out_file;
  329: }
  330: 
  331: 
  332: my $loop_summary ="$summary_dir/loop_summary";
  333: my $peer_summary ="$summary_dir/peer_summary";
  334: my $clock_summary="$summary_dir/clock_summary";
  335: 
  336: do_loop $loop_summary;
  337: map { do_peer $peer_summary, $_ } @peer_list;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>