[Git][NTPsec/ntpsec][master] First crude version of ntpmon lands. Needs work and polishing.

Eric S. Raymond gitlab at mg.gitlab.com
Thu Dec 8 01:29:59 UTC 2016


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


Commits:
1f54b798 by Eric S. Raymond at 2016-12-07T20:28:59-05:00
First crude version of ntpmon lands.  Needs work and polishing.

- - - - -


8 changed files:

- NEWS
- docs/includes/manual.txt
- + docs/includes/ntpmon-body.txt
- + docs/ntpmon.txt
- + docs/pic/looking.jpg
- + ntpclients/ntpmon
- + ntpclients/ntpmon-man.txt
- wscript


Changes:

=====================================
NEWS
=====================================
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,9 @@ ntpkeygen has been moved from C to Python.  This is not a functional
 change, just another move to improve maintainability and reduce attack
 surface by decreasing line count.
 
+A new tool for time-=service operators, ntpmon, supports real-time
+monitoring of your NTP installation's status.
+
 == 2016-11-23: 0.9.5 ==
 
 This release includes a substantial refactoring of the core protocol


=====================================
docs/includes/manual.txt
=====================================
--- a/docs/includes/manual.txt
+++ b/docs/includes/manual.txt
@@ -2,6 +2,7 @@
 * link:ntpd.html[+ntpd+ - Network Time Protocol (NTP) daemon]
 * link:ntpdig.html[+ntpdig+ - Simple Network Time Protocol (SNTP) client]
 * link:ntpq.html[+ntpq+ - standard NTP query program]
+* link:ntpmon.html[+ntpq+ - real-time NTP status monitor]
 * link:ntpfrob.html[+ntpfrob+ - frob the local clock hardware]
 * link:ntpkeygen.html[+ntpkeygen+ - generate public and private keys]
 * link:ntpleapfetch.html[+ntpleapfetch+ fetch and manage leap-offset file]


=====================================
docs/includes/ntpmon-body.txt
=====================================
--- /dev/null
+++ b/docs/includes/ntpmon-body.txt
@@ -0,0 +1,21 @@
+// This is the body of the manual page for ntmon.
+// It's included in two places: once for the docs/ HTML
+// tree, and once to make an individual man page.
+
+== Synopsis ==
+
++ntpmon+
+
+== Description ==
+
+This program is a real-time status monitor for NTP.  It presents the
+same informartion as the 'peers' and 'mrulist' commands of {ntpqman},
+but using a split-window display that also includes a status summary
+bar, and updates at intervals guaranteed to show status changes as
+soon as they occur.
+
+(Specifically, the display begins updating once per seconds and
+adjusts itself to poll at twice the frequency of the shortest
+polling interval reported in the last peers response.)
+
+// end


=====================================
docs/ntpmon.txt
=====================================
--- /dev/null
+++ b/docs/ntpmon.txt
@@ -0,0 +1,27 @@
+= ntpmon - standard NTP query program =
+
+[cols="10%,90%",frame="none",grid="none",style="verse"]
+|==============================
+|image:pic/looking.jpg[]|
+{millshome}pictures.html[from 'Pogo', Walt Kelly]
+
+Words of wisdom.
+
+|==============================
+
+== More Help ==
+
+include::includes/manual.txt[]
+
+'''''
+
+include::includes/ntpmon-body.txt[]
+
+== Mode 6 Protocol ==
+
+The Mode 6 protocol used by ntpmon to communicate with {ntpdman}
+is described link:mode6.html[here].
+
+'''''
+
+include::includes/footer.txt[]


=====================================
docs/pic/looking.jpg
=====================================
Binary files /dev/null and b/docs/pic/looking.jpg differ


=====================================
ntpclients/ntpmon
=====================================
--- /dev/null
+++ b/ntpclients/ntpmon
@@ -0,0 +1,111 @@
+#!/usr/bin/env python
+#
+# ntpmon - real-time peerstats/MRU monitor
+#
+# SPDX-License-Identifier: BSD-2-clause
+from __future__ import print_function, division
+
+import os, sys, curses, time
+
+try:
+    import ntp.packet
+    import ntp.util
+    import ntp.ntpc
+    import ntp.version
+    import ntp.control
+    import ntp.magic
+except ImportError:
+    sys.stderr.write("ntpmon: can't find Python NTP library -- check PYTHONPATH.\n")
+    sys.exit(1)
+
+try:
+    import curses
+except ImportError:
+    sys.stderr.write("ntpmon: can't find Python curses library -- check PYTHONPATH.\n")
+    sys.exit(1)
+
+pktversion = ntp.magic.NTP_VERSION
+showhostnames = True
+wideremote = False
+showall = False
+
+stdscr = None
+
+class Fatal(Exception):
+    "Unrecoverable error."
+    def __init__(self, msg):
+        Exception.__init__(self)
+        self.msg = msg
+
+class OutputContext:
+    def __enter__(self):
+        "Begin critical region."
+        global stdscr
+        stdscr = curses.initscr()
+    def __exit__(self, extype_unused, value_unused, traceback_unused):
+        curses.endwin()
+
+if __name__ == '__main__':
+    poll_interval = 1
+    peer_report = ntp.util.PeerSummary(displaymode="peers",
+                                       pktversion=pktversion,
+                                       showhostnames=showhostnames,
+                                       wideremote=wideremote,
+                                       termwidth=80,
+                                       debug=0)
+    mru_report = ntp.util.MRUSummary(showhostnames)
+    try:
+        session = ntp.packet.ControlSession()
+        session.openhost("localhost")
+        with OutputContext() as ctx:
+            while True:
+                try:
+                    peers = session.readstat()
+                except ntp.packet.ControlException as e:
+                    raise Fatal(e.message)
+                except IOError as e:
+                    raise Fatal(e.strerror)
+                stdscr.clear()
+                stdscr.addstr(0, 0, "")
+                stdscr.addstr(peer_report.header() + "\n", curses.A_BOLD)
+                if len(peers) == 0:
+                    raise Fatal("no peers reported")
+                hpolls = []
+                for peer in peers:
+                    if not showall and \
+                            not (ntp.control.CTL_PEER_STATVAL(peer.status)
+                              & (ntp.control.CTL_PST_CONFIG|ntp.control.CTL_PST_REACH)):
+                        continue
+                    try:
+                        variables = session.readvar(peer.associd)
+                        hpolls.append(variables['hpoll'])
+                    except ntp.packet.ControlException as e:
+                        raise Fatal(e.message + "\n")
+                    except IOError as e:
+                        raise Fatal(e.strerror)
+                    except IndexError:
+                        raise Fatal("no 'hpoll' variabe in peer response")
+                    if not variables:
+                        continue
+                    stdscr.addstr(peer_report.summary(session.rstatus,
+                                            variables, peer.associd))
+                # The status line
+                stdscr.addstr(ntp.util.stdversion() + "\n",
+                              curses.A_REVERSE|curses.A_DIM)
+                # Now the MRU report
+                span = session.mrulist()
+                if span.entries:
+                    stdscr.addstr(ntp.util.MRUSummary.header + "\n",
+                                  curses.A_BOLD)
+                    for entry in span.entries:
+                        stdscr.addstr(mru_report.summary(entry) + "\n")
+                # Display all
+                stdscr.refresh()
+                # Nyquist-interval sampling
+                time.sleep(min(hpolls) / 2)
+    except KeyboardInterrupt:
+        print("")
+    except IOError:
+        print("Bailing out...")
+
+# end


=====================================
ntpclients/ntpmon-man.txt
=====================================
--- /dev/null
+++ b/ntpclients/ntpmon-man.txt
@@ -0,0 +1,13 @@
+= ntpmon(1) =
+:doctype: manpage
+
+== NAME ==
+ntpmon - real-time NTP status monitor
+
+include::../docs/includes/ntpmon-body.txt[]
+
+== EXIT STATUS ==
+
+Always returns 0.
+
+// end


=====================================
wscript
=====================================
--- a/wscript
+++ b/wscript
@@ -138,6 +138,7 @@ def afterparty(ctx):
 python_scripts = [
         "ntpclients/ntpdig",
         "ntpclients/ntpkeygen",
+        "ntpclients/ntpmon",
         "ntpclients/ntpq",
         "ntpclients/ntpsweep",
         "ntpclients/ntptrace",
@@ -199,6 +200,7 @@ def build(ctx):
         ctx.manpage(8, "ntpclients/ntpleapfetch-man.txt")
         ctx.manpage(1, "ntpclients/ntpdig-man.txt")
         ctx.manpage(8, "ntpclients/ntpkeygen-man.txt")
+        ctx.manpage(1, "ntpclients/ntpmon-man.txt")
         ctx.manpage(1, "ntpclients/ntpq-man.txt")
         ctx.manpage(1, "ntpclients/ntpsweep-man.txt")
         ctx.manpage(1, "ntpclients/ntptrace-man.txt")



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/1f54b7989f84375a93093b3debd4ee0a59075956
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ntpsec.org/pipermail/vc/attachments/20161208/e2372a67/attachment.html>


More information about the vc mailing list