]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/ntp/scripts/stats/clock.awk
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / ntp / scripts / stats / clock.awk
1 # awk program to scan clockstat files and report errors/statistics
2 #
3 # usage: awk -f check.awk clockstats
4 #
5 # This program works for the following radios:
6 # PST/Traconex 1020 WWV reciever
7 # Arbiter 1088 GPS receiver
8 # Spectracom 8170/Netclock-2 WWVB receiver
9 # IRIG audio decoder
10 # Austron 2200A/2201A GPS receiver (see README.austron file)
11 #
12 BEGIN {
13         etf_min = osc_vmin = osc_tmin = 1e9
14         etf_max = osc_vmax = osc_tmax = -1e9
15 }
16 #
17 # scan all records in file
18 #
19 {
20         #
21         # select PST/Traconex WWV records
22         # 00:00:37.234  96/07/08/190 O6@0:5281825C07510394
23         #
24         if (NF >= 4 && $3 == "127.127.3.1") {
25                 if (substr($6, 14, 4) > "0010")
26                         wwv_sync++
27                 if (substr($6, 13, 1) == "C")
28                         wwv_wwv++
29                 if (substr($6, 13, 1) == "H")
30                         wwv_wwvh++
31                 x = substr($6, 12, 1)
32                 if (x == "1")
33                         wwv_2.5++
34                 else if (x == "2")
35                         wwv_5++
36                 else if (x == "3")
37                         wwv_10++
38                 else if (x == "4")
39                         wwv_15++
40                 else if (x == "5")
41                         wwv_20++
42                 continue
43         }
44         #
45         # select Arbiter GPS records
46         # 96 190 00:00:37.000 0 V=08 S=44 T=3 P=10.6 E=00
47         # N39:42:00.951 W075:46:54.880 210.55      2.50 0.00
48         #
49         if (NF >= 4 && $3 == "127.127.11.1") {
50                 if (NF > 8) {
51                         arb_count++
52                         if ($7 != 0)
53                                 arb_sync++
54                         x = substr($10, 3, 1)
55                         if (x == "0")
56                                 arb_0++
57                         else if (x == "1")
58                                 arb_1++
59                         else if (x == "2")
60                                 arb_2++
61                         else if (x == "3")
62                                 arb_3++
63                         else if (x == "4")
64                                 arb_4++
65                         else if (x == "5")
66                                 arb_5++
67                         else if (x == "6")
68                         arb_6++
69                 } else if (NF == 8) {
70                         arbn++
71                         arb_mean += $7
72                         arb_rms += $7 * $7
73                         if (arbn > 0) {
74                                 x = $7 - arb_val
75                                 arb_var += x * x
76                         }
77                         arb_val = $7
78                 }
79                 continue
80         }
81         #
82         # select Spectracom WWVB records
83         # see summary for decode
84         #   96 189 23:59:32.248  D
85         #
86         if (NF >= 4 && $3 == "127.127.4.1") {
87                 if ($4 == "SIGNAL" || NF > 7)
88                         printf "%s\n", $0
89                 else {
90                         wwvb_count++
91                         if ($4 ~ /\?/)
92                                 wwvb_x++
93                         else if ($4 ~ /A/)
94                                 wwvb_a++
95                         else if ($4 ~ /B/)
96                                 wwvb_b++
97                         else if ($4 ~ /C/)
98                                 wwvb_c++
99                         else if ($4 ~ /D/)
100                                 wwvb_d++
101                 }
102                 continue
103         }
104         #
105         # select IRIG audio decoder records
106         # see summary for decode
107         #
108         if (NF >= 4 && $3 == "127.127.6.0") {
109                 irig_count++
110                 if ($5 ~ /\?/)
111                         irig_error++
112                 continue
113         }
114         #
115         # select Austron GPS LORAN ENSEMBLE records
116         # see summary for decode
117         #
118         else if (NF >= 13 && $6 == "ENSEMBLE") {
119                 ensemble_count++
120                 if ($9 <= 0)
121                         ensemble_badgps++
122                 else if ($12 <= 0)
123                         ensemble_badloran++
124                 else {
125                         if ($13 > 200e-9 || $13 < -200e-9)
126                                 ensemble_200++
127                         else if ($13 > 100e-9 || $13 < -100e-9)
128                                 ensemble_100++
129                         ensemble_mean += $13
130                         ensemble_rms += $13 * $13
131                 }
132                 continue
133         }
134         #
135         # select Austron LORAN TDATA records
136         # see summary for decode; note that signal quality log is simply
137         # copied to output
138         #
139         else if (NF >= 7 && $6 == "TDATA") {
140                 tdata_count++
141                 for (i = 7; i < NF; i++) {
142                         if ($i == "M" && $(i+1) == "OK") {
143                                 i += 5
144                                 m += $i
145                                 tdata_m++
146                         }
147                         else if ($i == "W" && $(i+1) == "OK") {
148                                 i += 5
149                                 w += $i
150                                 tdata_w++
151                         }
152                         else if ($i == "X" && $(i+1) == "OK") {
153                                 i += 5
154                                 x += $i
155                                 tdata_x++
156                         }
157                         else if ($i == "Y" && $(i+1) == "OK") {
158                                 i += 5
159                                 y += $i
160                                 tdata_y++
161                         }
162                         else if ($i == "Z" && $(i+1) == "OK") {
163                                 i += 5
164                                 z += $i
165                                 tdata_z++
166                         }
167                 }       
168                 continue
169         }
170         #
171         # select Austron ITF records
172         # see summary for decode
173         #
174         else if (NF >= 13 && $5 == "ITF" && $12 >= 100) {
175                 itf_count++
176                 if ($9 > 200e-9 || $9 < -200e-9)
177                         itf_200++
178                 else if ($9 > 100e-9 || $9 < -100e-9)
179                         itf_100++
180                 itf_mean += $9
181                 itf_rms += $9 * $9
182                 itf_var += $10 * $10
183                 continue
184         }
185         #
186         # select Austron ETF records
187         # see summary for decode
188         #
189         else if (NF >= 13 && $5 == "ETF" && $13 >= 100) {
190                 etf_count++
191                 if ($6 > etf_max)
192                         etf_max = $6
193                 else if ($6 < etf_min)
194                         etf_min = $6
195                 etf_mean += $6
196                 etf_rms += $6 * $6
197                 etf_var += $9 * $9
198                 continue
199         }
200         #
201         # select Austron TRSTAT records
202         # see summary for decode
203         #
204         else if (NF >= 5 && $5 == "TRSTAT") {
205                 trstat_count++
206                 j = 0
207                 for (i = 6; i <= NF; i++)
208                         if ($i == "T")
209                                 j++
210                 trstat_sat[j]++
211                 continue
212         }
213         #
214         # select Austron ID;OPT;VER records
215         #
216         # config GPS 2201A TTY1 TC1 LORAN IN OUT1 B.00 B.00 28-Apr-93
217         #
218         # GPS 2201A     receiver model
219         # TTY1          rs232 moduel
220         # TC1           IRIG module
221         # LORAN         LORAN assist module
222         # IN            input module
223         # OUT1          output module
224         # B.00 B.00     firmware revision
225         # 28-Apr-9      firmware date3
226         #
227         else if (NF >= 5 && $5 == "ID;OPT;VER") {
228                 id_count++
229                 id_temp = ""
230                 for (i = 6; i <= NF; i++)
231                         id_temp = id_temp " " $i
232                 if (id_string != id_temp)
233                         printf "config%s\n", id_temp
234                 id_string = id_temp
235                 continue        
236         }
237         #
238         # select Austron POS;PPS;PPSOFF records
239         #
240         # position +39:40:48.425 -075:45:02.392 +74.09 Stored UTC 0 200 0
241         #
242         # +39:40:48.425 position north latitude
243         # -075:45:02.392 position east longitude
244         # +74.09        elevation (meters)
245         # Stored        position is stored
246         # UTC           time is relative to UTC
247         # 0 200 0       PPS offsets
248         #
249         else if (NF >= 5 && $5 == "POS;PPS;PPSOFF") {
250                 pos_count++
251                 pos_temp = ""
252                 for (i = 6; i <= NF; i++)
253                         pos_temp = pos_temp " " $i
254                 if (pos_string != pos_temp)
255                         printf "position%s\n", pos_temp
256                 pos_string = pos_temp
257         continue
258         }
259         #
260         # select Austron OSC;ET;TEMP records
261         #
262         # loop 1121 Software Control Locked
263         #
264         # 1121          oscillator type
265         # Software Control loop is under software control
266         # Locked        loop is locked
267         #
268         else if (NF >= 5 && $5 == "OSC;ET;TEMP") {
269                 osc_count++
270                 osc_temp = $6 " " $7 " " $8 " " $9
271                 if (osc_status != osc_temp)
272                         printf "loop %s\n", osc_temp
273                 osc_status = osc_temp
274                 if ($10 > osc_vmax)
275                         osc_vmax = $10
276                 if ($10 < osc_vmin)
277                         osc_vmin = $10
278                 if ($11 > osc_tmax)
279                         osc_tmax = $11
280                 if ($11 < osc_tmin)
281                         osc_tmin = $11
282         continue
283         }
284         #
285         # select Austron UTC records
286         # these ain't ready yet
287         #
288         else if (NF >= 5 && $5 == "UTC") {
289                 utc_count++
290                 utc_temp = ""
291                 for (i = 6; i <= NF; i++)
292                         utc_temp = utc_temp " " $i
293                 if (utc_string != utc_temp)
294 #                       printf "utc%s\n", utc_temp
295                 utc_string = utc_temp
296         continue
297         }
298 } END {
299 #
300 # PST/Traconex WWV summary data
301 #
302         if (wwv_wwv + wwv_wwvh > 0)
303                 printf "wwv %d, wwvh %d, err %d, MHz (2.5) %d, (5) %d, (10) %d, (15) %d, (20) %d\n", wwv_wwv, wwv_wwvh, wwv_sync, wwv_2.5, wwv_5, wwv_10, wwv_15, wwv_20
304 #
305 # Arbiter 1088 summary data
306 #
307 # gps           record count
308 # err           error count
309 # sats(0-6)     satellites tracked
310 # mean          1 PPS mean (us)
311 # rms           1 PPS rms error (us)
312 # var           1 PPS Allan variance
313 #
314         if (arb_count > 0) {
315                 printf "gps %d, err %d, sats(0-6) %d %d %d %d %d %d %d", arb_count, arb_sync, arb_0, arb_1, arb_2, arb_3, arb_4, arb_5, arb_6
316                 if (arbn > 1) {
317                         arb_mean /= arbn
318                         arb_rms = sqrt(arb_rms / arbn - arb_mean * arb_mean)
319                         arb_var = sqrt(arb_var / (2 * (arbn - 1)))
320                         printf ", mean %.2f, rms %.2f, var %.2e\n", arb_mean, arb_rms, arb_var * 1e-6
321                 } else {
322                         printf "\n"
323                 }
324         }
325 #
326 # ensemble summary data
327 #
328 # ensemble      record count
329 # badgps        gps data unavailable
330 # badloran      loran data unavailable
331 # rms           ensemble rms error (ns)
332 # >200          ensemble error >200 ns
333 # >100          100 ns < ensemble error < 200 ns
334 #
335         if (ensemble_count > 0) {
336                 ensemble_mean /= ensemble_count
337                 ensemble_rms = sqrt(ensemble_rms / ensemble_count - ensemble_mean * ensemble_mean) * 1e9 
338                 printf "ensemble %d, badgps %d, badloran %d, rms %.1f, >200 %d, >100 %d\n", ensemble_count, ensemble_badgps, ensemble_badloran, ensemble_rms, ensemble_200, ensemble_100
339         }
340 #
341 # wwvb summary data
342 #
343 # wwvb          record count
344 # ?             unsynchronized
345 # >1            error > 1 ms
346 # >10           error > 10 ms
347 # >100          error > 100 ms
348 # >500          error > 500 ms
349 #
350         if (wwvb_count > 0)
351                 printf "wwvb %d, ? %d, >1 %d, >10 %d, >100 %d, >500 %d\n", wwvb_count, wwvb_x, wwvb_a, wwvb_b, wwvb_c, wwvb_d
352 #
353 # irig summary data
354 #
355 # irig          record count
356 # err           error count
357 #
358         if (irig_count > 0)
359                 printf "irig %d, err %d\n", irig_count, irig_error
360 #
361 # tdata summary data
362 #
363 # tdata         record count
364 # m             M master OK-count, mean level (dB)
365 # w             W slave OK-count, mean level (dB)
366 # x             X slave OK-count, mean level (dB)
367 # y             Y slave OK-count, mean level (dB)
368 # z             Z slave OK-count, mean level (dB)
369 #
370         if (tdata_count > 0 ) {
371                 if (tdata_m > 0)
372                         m /= tdata_count
373                 if (tdata_x > 0)
374                         w /= tdata_count
375                 if (tdata_x > 0)
376                         x /= tdata_count
377                 if (tdata_y > 0)
378                         y /= tdata_count
379                 if (tdata_z > 0)
380                         z /= tdata_count
381                 printf "tdata %d, m %d %.1f, w %d %.1f, x %d %.1f, y %d %.1f, z %d %.1f\n", tdata_count, tdata_m, m, tdata_w, w, tdata_x, x, tdata_y, y, tdata_z, z
382         }
383 #
384 # itf summary data
385 #
386 # itf           record count
387 # rms           itf rms error (ns)
388 # >200          itf error > 200 ns
389 # >100          itf error > 100 ns
390 # var           Allan variance
391 #
392         if (itf_count > 1) { 
393                 itf_mean /= itf_count
394                 itf_rms = sqrt(itf_rms / itf_count - itf_mean * itf_mean) * 1e9
395                 itf_var = sqrt(itf_var / (2 * (itf_count - 1)))
396                 printf "itf %d, rms %.1f, >200 %d, >100 %d, var %.2e\n", itf_count, itf_rms, itf_200, itf_100, itf_var
397         }
398 #
399 # etf summary data
400 #
401 # etf           record count
402 # mean          etf mean (ns)
403 # rms           etf rms error (ns)
404 # max           etf maximum (ns)
405 # min           etf minimum (ns)
406 # var           Allan variance
407 #
408         if (etf_count > 0) {
409                 etf_mean /= etf_count
410                 etf_rms = sqrt(etf_rms / etf_count - etf_mean * etf_mean)
411                 etf_var = sqrt(etf_var / (2 * (etf_count - 1)))
412                 printf "etf %d, mean %.1f, rms %.1f, max %d, min %d, var %.2e\n", etf_count, etf_mean, etf_rms, etf_max, etf_min, etf_var
413         }
414 #
415 # trstat summary data
416 #
417 # trstat        record count
418 # sat           histogram of tracked satellites (0 - 7)
419 #
420         if (trstat_count > 0)
421                 printf "trstat %d, sat %d %d %d %d %d %d %d %d\n", trstat_count, trstat_sat[0], trstat_sat[1], trstat_sat[2], trstat_sat[2], trstat_sat[3], trstat_sat[4], trstat_sat[5], trstat_sat[6], trstat_sat[7]
422 #
423 # osc summary data
424 #
425 # osc           record count
426 # control       control midrange (V) +/- deviation (mV)
427 # temp          oven temperature midrange +/- deviation (deg C)
428 #
429         if (osc_count > 0)
430                 printf "osc %d, control %.3f+/-%.3f, temp %.1f+/-%.2f\n", osc_count, (osc_vmax + osc_vmin) / 2, (osc_vmax - osc_vmin) / 2 * 1e3, (osc_tmax + osc_tmin) / 2, (osc_tmax - osc_tmin) / 2
431 }