[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