forked from TheBlueMatt/chrony_ntp_logconv
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchrony_ntp_logconv.sh
97 lines (85 loc) · 3.72 KB
/
chrony_ntp_logconv.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/env python3
# Convert chrony's tracking and statistics logs to something ntpsec's ntpviz can graph
# Assumes chrony's logs are in /var/log/chrony and outputs to /var/log/ntpstats
# See below and fill in an adapter from your local refid names for refclocks to NTPd style
# IPs for refclocks.
import shutil, os, math
from datetime import datetime, timezone
try:
shutil.rmtree("/var/log/ntpstats/conv")
except:
pass
os.mkdir("/var/log/ntpstats/conv")
# Chrony can sometimes print times out of order, which on day boundaries can result
# in us clearing logs completely, so we track which days we've covered and append
# if we see a day for a second time.
suffixes = {}
suffixes["loopstats"] = set()
suffixes["peerstats"] = set()
out = None
for f in os.listdir("/var/log/chrony"):
if f.startswith("tracking.log"):
out_ty = "loopstats"
elif f.startswith("statistics.log"):
out_ty = "peerstats"
else:
continue
with open("/var/log/chrony/" + f) as fd:
line = fd.readline()
f = ""
while line:
if line.startswith(" ") or line.startswith("====="):
line = fd.readline()
continue
s = line.split()
t = datetime.fromisoformat(s[0] + " " + s[1])
d = datetime.fromisoformat(s[0])
mjs = (d.timestamp() + 3506716800)
mjd = math.floor(mjs / 86400)
secs = ((t.timestamp() - d.timestamp()))
logsuf = d.strftime("%Y%m%d")
if f != logsuf:
f = logsuf
if out is not None:
out.close()
if f in suffixes[out_ty]:
out = open("/var/log/ntpstats/conv/" + out_ty + "." + logsuf, "a")
else:
out = open("/var/log/ntpstats/conv/" + out_ty + "." + logsuf, "w")
suffixes[out_ty].add(f)
if out_ty == "loopstats":
# Bogus "clock discipline time constant"
# Note that we don't have Allan Devitaion for freq, only "error bounds on the frequency", but we use that anyway
out.write("%d %d %.9f %.3f %.9f %.9f 6\n" % (mjd, secs, -float(s[6]), -float(s[4]), float(s[9]), float(s[5])))
elif out_ty == "peerstats":
src = s[2]
# These are my refclocks. You should fill in your own conversions here.
if src == "NME0":
src = "127.127.20.0"
elif src == "NME1":
src = "127.127.20.1"
elif src == "NME2":
src = "127.127.20.2"
elif src == "NME2":
src = "127.127.20.3"
elif src == "GPS0":
src = "127.127.46.0"
elif src == "GPS1":
src = "127.127.46.1"
elif src == "GPS2":
src = "127.127.46.2"
elif src == "PPS0":
src = "127.127.22.0"
elif src == "PPS1":
src = "127.127.22.1"
elif src == "PPS2":
src = "127.127.22.2"
# Bogus "status" and, sadly, missing "delay" (which is 0 here, its only in rawstats)
out.write("%d %d %s 9014 %.9f 0 %.9f %.9f\n" % (mjd, secs, src, -float(s[4]), float(s[5]), float(s[3])))
line = fd.readline()
out.close()
shutil.copyfile("/var/log/ntpstats/conv/peerstats." + logsuf, "/var/log/ntpstats/peerstats")
shutil.copyfile("/var/log/ntpstats/conv/loopstats." + logsuf, "/var/log/ntpstats/loopstats")
for f in os.listdir("/var/log/ntpstats/conv"):
os.rename("/var/log/ntpstats/conv/" + f, "/var/log/ntpstats/" + f)
shutil.rmtree("/var/log/ntpstats/conv")