[Git][NTPsec/ntpsec][master] ntpviz: basic HTML generation.
Eric S. Raymond
gitlab at mg.gitlab.com
Mon Aug 15 16:33:02 UTC 2016
Eric S. Raymond pushed to branch master at NTPsec / ntpsec
Commits:
ebb83a8f by Eric S. Raymond at 2016-08-15T12:32:27-04:00
ntpviz: basic HTML generation.
- - - - -
3 changed files:
- docs/includes/ntpviz-body.txt
- ntpstats/ntpstats.py
- ntpstats/ntpviz
Changes:
=====================================
docs/includes/ntpviz-body.txt
=====================================
--- a/docs/includes/ntpviz-body.txt
+++ b/docs/includes/ntpviz-body.txt
@@ -10,6 +10,7 @@
[--local-offset | --local-jitter | --local-stability]
[--peer-offsets=hosts | --all-peer-offsets]
[--peer-jitters=hosts | --all-peer-jitters]
+ [-o outdir]
== DESCRIPTION ==
@@ -74,6 +75,10 @@ The following plots are available:
Show offset plus or minus round-trip-time (rtt) of a specified
peer. This graph combines fields 4 and 5 of loopstats.
+If no individual plot is specified, all plots and an index HTML page
+are generated into a new output directory. Normally this directory
+is named 'ntpgraphs', but the name can be changed with the -o option.
+
The code includes various sanity checks and will bail out with a message to
standard error on, for example, missing logfile data required for a plot.
=====================================
ntpstats/ntpstats.py
=====================================
--- a/ntpstats/ntpstats.py
+++ b/ntpstats/ntpstats.py
@@ -119,12 +119,4 @@ def isotime(s):
else:
return time.mktime(time.strptime(date, "%Y-%m-%dT%H:%M:%S"))
-def gnuplot(template):
- "Run a specified GNUPLOT program."
- proc = subprocess.Popen("gnuplot",
- shell=True, bufsize=4096, stdin=subprocess.PIPE)
- proc.stdin.write(template)
- proc.stdin.close()
- return proc.wait()
-
# end
=====================================
ntpstats/ntpviz
=====================================
--- a/ntpstats/ntpviz
+++ b/ntpstats/ntpviz
@@ -7,6 +7,7 @@ Usage: ntpviz [-d statsdir] [-g] [-n name] [-p period]
[--local-offset | --local-jitter | --local-stability]
[--peer-offsets=hosts | --all-peer-offsets]
[--peer-jitters=hosts | --all-peer-jitters]
+ [-o outdir]
See the manual page for details.
@@ -21,6 +22,19 @@ from ntpstats import *
# RMS frequency jitter - Deviation from a root-mean-square linear approximation?
# Investigate.
+def gnuplot(template, outfile=None):
+ "Run a specified GNUPLOT program."
+ if outfile is None:
+ out = None
+ else:
+ out = open(outfile, "w")
+ proc = subprocess.Popen("gnuplot",
+ shell=True, bufsize=4096,
+ stdin=subprocess.PIPE, stdout=out)
+ proc.stdin.write(template)
+ proc.stdin.close()
+ return proc.wait()
+
class NTPViz(NTPStats):
"Class for visualizing statistics from a single server."
Common = """\
@@ -38,7 +52,7 @@ set rmargin 12
NTPStats.__init__(self, sitename, statsdir)
if self.sitename is None:
self.sitename = os.path.basename(statsdir)
- def local_clock_gnuplot(self):
+ def local_offset_gnuplot(self):
"Generate GNUPLOT code graphing local clock loop statistics"
sitename = self.sitename
plot_template = NTPViz.Common + """\
@@ -82,10 +96,10 @@ plot \
%(one)s title "1st percentile"
""" % locals()
return plot_template.replace('@', '%') + self.dump("loopstats")
- def local_clock_jitter_gnuplot(self):
+ def local_offset_jitter_gnuplot(self):
"Generate GNUPLOT code of local clock loop standard deviation"
return self.loopstats_gnuplot(4, "RMS Time jitter", "Jitter")
- def local_clock_stability_gnuplot(self):
+ def local_offset_stability_gnuplot(self):
"Generate GNUPLOT code graphing local clock stability"
return self.loopstats_gnuplot(5, "RMS Frequency Jitter", "Stability")
def peerstats_gnuplot(self, peerlist, fld, title):
@@ -113,9 +127,13 @@ plot \\
plot_template = plot_template[:-4] + "\n"
for key in peerlist:
# Trickiness - we allow peerlist elements to be DNS names.
- # The socket.gethostbyname() call maps these to IP addresses,
- # passing through literal IP addresses unaltered.
- ip = socket.gethostbyname(key)
+ # The socket.gethostbyname() call maps DNS names to IP addresses,
+ # passing through literal IPv4 addresses unaltered. However,
+ # it barfs on either literal IPv6 addresses or refclock names.
+ if "(" in key or "::" in key:
+ ip = key
+ else:
+ ip = socket.gethostbyname(key)
if ip in peerdict:
plot_template += "\n".join(peerdict[ip]) + "\ne\n"
else:
@@ -152,7 +170,7 @@ plot \
if __name__ == '__main__':
try:
- (options, arguments) = getopt.getopt(sys.argv[1:], "d:e:ghn:p:s:", [
+ (options, arguments) = getopt.getopt(sys.argv[1:], "d:e:ghn:o:p:s:", [
"local-offset", "local-jitter", "local-stability",
"all-peer-offsets", "peer-offsets=",
"all-peer-jitters", "peer-jitters=",
@@ -169,6 +187,7 @@ if __name__ == '__main__':
show_local_offset = show_local_jitter = show_local_stability = False
show_peer_offsets = show_peer_jitters = None
show_peer_rtt = None
+ outdir = "ntpgraphs"
for (switch, val) in options:
if switch == "-d":
statsdirs = val.split(",")
@@ -185,6 +204,8 @@ if __name__ == '__main__':
period = int(val) # Denominated in days
elif switch == "-s":
starttime = isotime(val)
+ elif switch == "-o":
+ outdir = val
elif switch == "--local-offset":
show_local_offset = True
elif switch == "--local-jitter":
@@ -236,11 +257,11 @@ if __name__ == '__main__':
sys.stderr.write("ntpviz: clash of mode options\n")
raise SystemExit(1)
if show_local_offset:
- plot = stats.local_clock_gnuplot()
+ plot = stats.local_offset_gnuplot()
if show_local_jitter:
- plot = stats.local_clock_jitter_gnuplot()
+ plot = stats.local_offset_jitter_gnuplot()
if show_local_stability:
- plot = stats.local_clock_stability_gnuplot()
+ plot = stats.local_offset_stability_gnuplot()
if generate:
gnuplot(plot)
else:
@@ -263,4 +284,41 @@ if __name__ == '__main__':
sys.stdout.write(plot)
raise SystemExit(0)
+ # Fall through to HTML code generation
+ if os.path.isdir(outdir):
+ sys.stderr.write("ntpviz: %s already exists.\n" % outdir)
+ raise SystemExit(1)
+ try:
+ os.mkdir(outdir)
+ except SystemError:
+ sys.stderr.write("ntpviz: %s can't be created.\n" % outdir)
+ raise SystemExit(1)
+ index_header = '''\
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>ntpviz plot</title>
+</head>
+<body>
+'''
+ index_trailer = '''\
+</body>
+</html>
+'''
+ imagepairs = (
+ ("local-offset", stats.local_offset_gnuplot),
+ ("local-jitter", stats.local_offset_jitter_gnuplot),
+ ("local-stability", stats.local_offset_stability_gnuplot),
+ ("peer-offsets", lambda: stats.peer_offsets_gnuplot(None)),
+ ("peer-jitters", lambda: stats.peer_jitters_gnuplot(None)),
+ )
+ for (imagename, generator) in imagepairs:
+ gnuplot(generator(), os.path.join(outdir, imagename + ".png"))
+ with open(os.path.join(outdir, "index.html"), "w") as ifile:
+ ifile.write(index_header)
+ for (imagename, _) in imagepairs:
+ ifile.write("<img src='%s.png'/>\n" % imagename)
+ ifile.write(index_trailer)
+
# end
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/ebb83a8ff67351e5d6e06edc132ef51ec2d693e5
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ntpsec.org/pipermail/vc/attachments/20160815/a7746c00/attachment.html>
More information about the vc
mailing list