Start development on 386BSD 0.0
[unix-history] / .ref-BSD-4_3_Net_2 / usr / src / contrib / isode / others / ntp / stat.pl
CommitLineData
9e8e5516
C
1#!/usr/bin/perl
2# $Source: /f/osi/others/ntp/RCS/stat.pl,v $ $Revision: 7.1 $ $Date: 91/02/22 09:34:10 $
3#
4# Make plots from ntpd syslog messages. Invoked as:
5#
6# stat.pl [-o outputfile] [-i interval] [-t termtype] [-S] [-l] < logmessages
7#
8# Where interval is the number of hours per plot, default is all data on
9# on set of plots.
10#
11# termtype is the terminal type passed to gnuplot. Default is postscript,
12# other useful alternative include 'tek', or 'unixplot'
13#
14# output file is the name of the file which will receive plot data. The
15# default is "stats.plot".
16#
17# The -l option will also create log scale plots.
18#
19# The -S option will "save" the intermedite data files, which are normally
20# deleted.
21#
22# Louis A. Mamakos <louie@TRANTOR.UMD.EDU>
23# with many thanks to Larry Wall for `perl', a wonderful tool for hacking
24# up things like this so easily.
25#
26
27#
28# Mar 7 18:46:58 trantor ntpd[20838]: adjust: SLEW 192.41.177.92 st 2
29# off -0.015756 drft 0.000000 cmpl 0.000000
30# Mar 10 08:56:19 trantor ntpd[27755]: clock: select peer 128.8.10.1 stratum 1
31# was 130.126.174.40 stratum 1
32# Mar 31 16:55:19 trantor ntpd[2195]: /usr/local/etc/ntpd version $Revision:
33# 3.4.1.5 $#
34#
35$scriptfile = $0;
36
37$month{'Jan'} = 0; $month{'Feb'} = 1; $month{'Mar'} = 2; $month{'Apr'} = 3;
38$month{'May'} = 4; $month{'Jun'} = 5; $month{'Jul'} = 6; $month{'Aug'} = 7;
39$month{'Sep'} = 8; $month{'Oct'} = 9; $month{'Nov'} = 10; $month{'Dec'} = 11;
40
41#
42# Currently, the year is not included in the syslog messages. We'll have to
43# assume that the log files be processed were written this year.
44#
45($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
46
47if ($year % 4) {
48 # not leap year
49 $days[0] = 0; $days[1] = 31; $days[2] = 59; $days[3] = 90;
50 $days[4] = 120; $days[5] = 151; $days[6] = 181; $days[7] = 212;
51 $days[8] = 243; $days[9] = 273; $days[10] = 304; $days[11] = 334;
52} else {
53 # leap year
54 $days[0] = 0; $days[1] = 31; $days[2] = 60; $days[3] = 91;
55 $days[4] = 121; $days[5] = 152; $days[6] = 182; $days[7] = 213;
56 $days[8] = 244; $days[9] = 274; $days[10] = 305; $days[11] = 335;
57}
58
59die "Can't open drift compansation file\n" unless open(DRIFT, ">stats.drift");
60die "Can't open offset file\n" unless open(OFF, ">stats.off");
61die "Can't open compliance file\n" unless open(COMP, ">stats.comp");
62die "Can't open clock file\n" unless open(CLK, ">stats.clk");
63
64$# = '%.6g';
65$plottype = "postscript";
66$recs = 0;
67$start = 0;
68$clocks = 1;
69$clk{'UNSYNCED'} = 0;
70
71do Getopt('tio');
72
73if ($opt_h) {
74 die "Usage: $scriptfile [-o outputfile] [-i interval] [-t termtype] [-l] [-S] < logmessages\n";
75}
76
77if ($opt_t) {
78 $plottype = $opt_t;
79}
80
81if ($opt_i) {
82 $interval = $opt_i;
83} else {
84 $interval = 99999999;
85}
86
87while (<>) {
88 if (/.* ntpd\[[0-9]*\]: (.*\/ntpd) version \$Revision: \b(.*)\b/) {
89 chop;
90 @in = split;
91 $recs++;
92 $revision = $1 . " " . $2;
93
94 print "Revision $revision\n";
95
96 @time = split(/:/,$in[2]);
97 $t = $in[1]*24 + $time[0] + $time[1]/60 + $time[2]/3600 +
98 $days[$month{$in[0]}]*24;
99
100 if (!$start) {
101 $start = $t;
102 printf "Start time is %s %s %s\n",$in[0],$in[1],$in[2];
103 }
104 }
105 if (/.* ntpd\[[0-9]*\]: clock:/) {
106 chop;
107 @in = split;
108 @time = split(/:/,$in[2]);
109 $t = $in[1]*24 + $time[0] + $time[1]/60 + $time[2]/3600 +
110 $days[$month{$in[0]}]*24;
111
112 if (!$start) {
113 $start = $t;
114 printf "Start time is %s %s %s\n",$in[0],$in[1],$in[2];
115 }
116 if (!$clk{$in[8]}) {
117 printf "Clock %d is %s\n", $clocks, $in[8];
118 $clk{$in[8]} = $clocks++;
119 }
120 $t = $t - $start;
121 print CLK $t," ",$clk{$in[8]},"\n";
122
123 }
124 if (/.* ntpd\[[0-9]*\]: adjust:/) {
125 chop;
126 @in = split;
127 $recs++;
128
129 @time = split(/:/,$in[2]);
130 $t = $in[1]*24 + $time[0] + $time[1]/60 + $time[2]/3600 +
131 $days[$month{$in[0]}]*24;
132 if (!$start) {
133 $start = $t;
134 printf "Start time is %s %s %s\n",$in[0],$in[1],$in[2];
135 }
136
137 $t = $t - $start;
138
139 # offset=11 drift=13 compliance=15
140
141 print OFF $t, " ", $in[11],"\n";
142 #
143 # Scale the drift compensation by 256.0 to convert to PPM.
144 #
145 print DRIFT $t," ", $in[13]/256.0, "\n";
146
147 #
148 # Scale compliance by T (2**18)
149 #
150 if ( $in[15] < 0 ) {
151 $in[15] = -$in[15];
152 }
153 print COMP $t," ",$in[15] * 2**18, "\n";
154 }
155}
156
157if ($t = int($t)) {
158 $last = int($t) + 1;
159} else {
160 $last = int($t);
161}
162print "$recs records spanning $t hours.\n";
163
164close OFF;
165close DRIFT;
166close COMP;
167close CLK;
168
169if ($last == $start) {
170 unlink "stats.script";
171 unlink "stats.drift";
172 unlink "stats.off";
173 unlink "stats.comp";
174 unlink "stats.clk";
175 die "No statistics records found\n";
176}
177
178die "Can't open script file\n" unless open(TMP, ">stats.script");
179#
180# Write script file for GNU plot. Generate multiple sets of plots, each set
181# displaying the data over a specified interval.
182#
183print TMP "set samples ",$recs,"\n";
184print TMP "set term $plottype\n";
185
186if ($opt_o) {
187 printf TMP 'set output "%s"', $opt_o; print TMP "\n";
188} else {
189 print TMP 'set output "stats.plot"'; print TMP "\n";
190}
191
192if ($interval > $last) {
193 if ($interval != 99999999) {
194 print "Interval truncated to available data ($last)\n";
195 }
196 $interval = $last;
197}
198#
199# Plot multiple sets of plots, each set of which covers the specified number
200# of hours.
201#
202$start = 0;
203$end = $interval;
204while (($start < $last)) {
205 print TMP "set autoscale\n";
206 print TMP "plot [$start:$end] ",'"stats.drift"'," with lines\n";
207 print TMP "plot [$start:$end] ",'"stats.comp"'," with lines\n";
208 if ($opt_l) {
209 print TMP "set logscale y\n";
210 print TMP "plot [$start:$end] ",'"stats.comp"'," with lines\n";
211 print TMP "set nologscale\n";
212 }
213 print TMP "plot [$start:$end] [-0.1:0.1] ",
214 '"stats.off"'," with lines\n";
215 print TMP "plot [$start:$end] [0:$clocks]",
216 '"stats.clk"'," with impulse\n";
217 $start = $end;
218 $end += $interval;
219}
220close TMP;
221
222#
223# Now, run gnuplot on the script file.
224#
225system "gnuplot < stats.script > /dev/null 2>&1" ||
226 die "gnuplot croaked: exit=" . $? . "\n";
227
228if (!$opt_S) {
229 unlink "stats.script";
230 unlink "stats.drift";
231 unlink "stats.off";
232 unlink "stats.comp";
233 unlink "stats.clk";
234}
235\f
236;# Process single-character switches with switch clustering. Pass one argument
237;# which is a string containing all switches that take an argument. For each
238;# switch found, sets $opt_x (where x is the switch name) to the value of the
239;# argument, or 1 if no argument. Switches which take an argument don't care
240;# whether there is a space between the switch and the argument.
241
242;# Usage:
243;# do Getopt('oDI'); # -o, -D & -I take arg. Sets opt_* as a side effect.
244
245sub Getopt {
246 local($argumentative) = @_;
247 local($_,$first,$rest);
248
249 while (($_ = $ARGV[0]) =~ /^-(.)(.*)/) {
250 ($first,$rest) = ($1,$2);
251 if (index($argumentative,$first) >= $[) {
252 if ($rest ne '') {
253 shift;
254 }
255 else {
256 shift;
257 $rest = shift;
258 }
259 eval "\$opt_$first = \$rest;";
260 }
261 else {
262 eval "\$opt_$first = 1;";
263 if ($rest ne '') {
264 $ARGV[0] = "-$rest";
265 }
266 else {
267 shift;
268 }
269 }
270 }
271}
272
273#
274# Local Variables:
275# mode: text
276# End: