Annotation of embedaddon/ntp/scripts/plot_summary.in, revision 1.1.1.1

1.1       misho       1: #! @PATH_PERL@ -w
                      2: # $Id$
                      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>