[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