[Git][NTPsec/ntpsec][master] Various improvements to ntpviz.

Eric S. Raymond gitlab at mg.gitlab.com
Tue Aug 16 12:20:52 UTC 2016


Eric S. Raymond pushed to branch master at NTPsec / ntpsec


Commits:
9861a337 by Eric S. Raymond at 2016-08-16T08:20:14-04:00
Various improvements to ntpviz.

- - - - -


4 changed files:

- NEWS
- docs/includes/ntpviz-body.txt
- ntpstats/ntpstats.py
- ntpstats/ntpviz


Changes:

=====================================
NEWS
=====================================
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,8 @@ on user-visible changes.
 == Repository head ==
 
 A new visualization tool, ntpviz, generates graphical summaries of
-logfile data that can be helpful 
+logfile data that can be helpful for identifying problems such as
+misconfigured servers.
 
 usestats has been added to the statistics collection to record
 system resource usage statistics.


=====================================
docs/includes/ntpviz-body.txt
=====================================
--- a/docs/includes/ntpviz-body.txt
+++ b/docs/includes/ntpviz-body.txt
@@ -17,7 +17,7 @@
 This utility analyzes files in an NTP log directory and generates
 statistical plots from them.  It can report either PNG images or
 the GNUPLOT programs to generate them to standard output.  In its
-default mode it generates an HTML directory containing all polots
+default mode it generates an HTML directory containing all plots
 and an index page.
 
 The most basic option is -d, which specifies a logfile directory to
@@ -78,8 +78,10 @@ The following plots are available:
    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.
+are generated into a new output directory.  Normally this directory is
+named 'ntpgraphs', but the name can be changed with the -o option.
+Warning: existing PNG files and index.html in this directory will be
+clobbered.
 
 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
@@ -115,11 +115,15 @@ class NTPStats:
                 pass
         return key	# Someday, be smarter than this.
 
-def isotime(s):
+def iso_to_posix(s):
     "Accept timestamps in ISO8661 format or numeric POSIX time."
     if s.isdigit(s):
         return int(s)
     else:
         return time.mktime(time.strptime(date, "%Y-%m-%dT%H:%M:%S"))
 
+def posix_to_iso(t):
+    "ISO8601 string from Unix time."
+    return time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime(t))
+
 # end


=====================================
ntpstats/ntpviz
=====================================
--- a/ntpstats/ntpviz
+++ b/ntpstats/ntpviz
@@ -16,11 +16,13 @@ Python by ESR, concept and GNUPLOT code by Dan Drown.
 #SPDX-License-Identifier: BSD-2-Clause
 from __future__ import print_function, division
 
-import os, sys, getopt, socket
+import os, sys, getopt, socket, binascii
 from ntpstats import *
 
 # RMS frequency jitter - Deviation from a root-mean-square linear approximation?
 # Investigate.
+#
+# TO-DO: Embed Dan Drown's glossary and notes file in the HTML.
 
 def gnuplot(template, outfile=None):
     "Run a specified GNUPLOT program."
@@ -166,7 +168,9 @@ plot \
         plot_template += data + "\ne\n"	+ data + "\ne\n" + data
         return plot_template
 
-
+ntpsec_logo = """
+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
+"""
 
 if __name__ == '__main__':
     try:
@@ -192,7 +196,7 @@ if __name__ == '__main__':
         if switch == "-d":
             statsdirs = val.split(",")
         elif switch == "-e":
-            endtime = isotime(val)
+            endtime = iso_to_posix(val)
         elif switch == "-g":
             generate = True
         elif switch == "-h":
@@ -203,7 +207,7 @@ if __name__ == '__main__':
         elif switch == "-p":
             period = int(val)	# Denominated in days
         elif switch == "-s":
-            starttime = isotime(val)
+            starttime = iso_to_posix(val)
         elif switch == "-o":
             outdir = val
         elif switch == "--local-offset":
@@ -285,14 +289,14 @@ if __name__ == '__main__':
             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)
+        if not os.path.isdir(outdir):
+            try:
+                os.mkdir(outdir)
+            except SystemError:
+                sys.stderr.write("ntpviz: %s can't be created.\n" % outdir)
+                raise SystemExit(1)
+        with open(os.path.join(outdir, "ntpsec-logo.png", "w")) as wp:
+            wp.write(binascii.a2b_base64(ntpsec_logo))
         index_header = '''\
 <!DOCTYPE html>
 <html>
@@ -301,18 +305,26 @@ if __name__ == '__main__':
 <title>ntpviz plot</title>
 </head>
 <body>
+<img sec="ntpsec-logo.png"/>
 '''
         index_trailer = '''\
 </body>
 </html>
 '''
-        imagepairs = (
+        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 key in stats.peersplit().keys():
+            imagepairs.append(("peer-offset-" + key,
+                           lambda: stats.peer_offsets_gnuplot([key])))
+        imagepairs.append(("peer-jitters",
+                           lambda: stats.peer_jitters_gnuplot(None)))
+        for key in stats.peersplit().keys():
+            imagepairs.append(("peer-jitter-" + key,
+                           lambda: stats.peer_jitters_gnuplot([key])))
         for (imagename, generator) in imagepairs:
             gnuplot(generator(), os.path.join(outdir, imagename + ".png"))
             with open(os.path.join(outdir, "index.html"), "w") as ifile:



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/9861a3373df835bec1fe6cbca4152d6e36f2118f
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ntpsec.org/pipermail/vc/attachments/20160816/28d350ff/attachment.html>


More information about the vc mailing list