[ntpsec commit] Implement and document JSON reporting in ntpfrob.
Eric S. Raymond
esr at ntpsec.org
Wed Oct 14 13:33:26 UTC 2015
Module: ntpsec
Branch: master
Commit: 57172eea4b6c834ac597410a234a88008d117635
Changeset: http://git.ntpsec.org/ntpsec/commit/?id=57172eea4b6c834ac597410a234a88008d117635
Author: Eric S. Raymond <esr at thyrsus.com>
Date: Wed Oct 14 09:05:52 2015 -0400
Implement and document JSON reporting in ntpfrob.
---
docs/includes/ntpfrob-body.txt | 28 +++++++++++++++++++++++++---
ntpfrob/jitter.c | 39 +++++++++++++++++++++++++++++++--------
ntpfrob/main.c | 27 ++++++++++++++++++++-------
ntpfrob/precision.c | 31 +++++++++++++++++++------------
ntpfrob/tickadj.c | 14 +++++++++++---
5 files changed, 106 insertions(+), 33 deletions(-)
diff --git a/docs/includes/ntpfrob-body.txt b/docs/includes/ntpfrob-body.txt
index 8daa2bd..971917a 100644
--- a/docs/includes/ntpfrob-body.txt
+++ b/docs/includes/ntpfrob-body.txt
@@ -27,16 +27,34 @@ Portions of it formerly traveled as `tickadj` and `ntptime`.
Measure clock precision.
`-s`::
Check for stepback bug.
+`-j`::
+ Report in self-describing JSON.
== Modes of operation ==
-Documentation for some of these functions is scanty. If you suspect
-you may need to use them, reading the source code may be wise.
+Documentation for some of these functions is scanty; this is a problem
+inherited from ancient days along with their code. If you suspect
+you may need to use them, reading the source code may be wise. If
+you believe you understand the code in more detail than any of
+these descriptions, please explain it to the {project-shortname}
+maintainers.
+
+Normally this tool reports in an eyeball-friendly unstructured text
+format. With the -j option (where applicable) it reports JSON records.
+Note that the -j option should be given before any mode option.
+
+The reporting formats of this tool should be considered unstable;
+they may change as diagnostics are added or improved. JSON
+reports will be kept forward-compatible through changes.
=== Clock tick adjustment ===
The -A function reads your clock's tick rate in microseconds. The -a
-function sets it. Both rely on the adjtimex(2) system call.
+function sets it. Both rely on the adjtimex(2) system call. This
+mode finishes by tereporting the tick value and (if available) the
+tick adjustment value.
+
+The -j option is applicable to this mode.
Tweaking your tick rate is almost never necessary on hardware new
enough to have a fully POSIX.1-2001-conformant Unix.
@@ -50,6 +68,8 @@ hardware interrupt, usually in the range 10 us-1 ms. For those systems
with microsecond counters the jitter is dominated only by the
operating system.
+The -j option is applicable to this mode.
+
=== Pulse-per-second check ==
The -p option shows whether the PPS-API (RFC 2783 kernel
@@ -60,6 +80,8 @@ PPS interface) finds PPS on a specified device.
The -e option measure the resolution of the system clock, watching how
the current time changes as we read it repeatedly.
+The -j option is applicable to this mode.
+
=== Stepback bug check ===
The -s option checks for a bug originally seen on IBM RS/6000 AIX
diff --git a/ntpfrob/jitter.c b/ntpfrob/jitter.c
index ba1e8b4..4ec5730 100644
--- a/ntpfrob/jitter.c
+++ b/ntpfrob/jitter.c
@@ -15,10 +15,13 @@
#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>
+#include <stdbool.h>
+
#include "ntp_fp.h"
#define NBUF 800002
#define JAN_1970 2208988800UL /* Unix base epoch */
+#define NSAMPLES 10
char progname[10];
double sys_residual;
@@ -58,7 +61,7 @@ get_clocktime(
now->l_uf = (uint32_t)dtemp;
}
-void jitter(void)
+void jitter(const bool json)
{
l_fp tr;
int i, j;
@@ -101,13 +104,33 @@ void jitter(void)
}
}
average = average / (NBUF - 2);
- fprintf(stderr, "Average %13.9f\n", average);
- fprintf(stderr, "First rank\n");
- for (i = 0; i < 10; i++)
- fprintf(stderr, "%2d %13.9f\n", i, gtod[i]);
- fprintf(stderr, "Last rank\n");
- for (i = NBUF - 12; i < NBUF - 2; i++)
- fprintf(stderr, "%2d %13.9f\n", i, gtod[i]);
+ if (json) {
+ fprintf(stdout, "{\"Average\":%13.9f,", average);
+ fprintf(stdout, "\"First rank\":[");
+ for (i = 0; i < NSAMPLES; i++) {
+ fprintf(stdout, "%13.9f", gtod[i]);
+ if (i < NSAMPLES - 1)
+ fputc(',', stdout);
+ fputs("],", stdout);
+ }
+ fprintf(stdout, "\"Last rank\":");
+ for (i = NBUF - 12; i < NBUF - 2; i++) {
+ fprintf(stdout, "%13.9f\n", gtod[i]);
+ if (i < NSAMPLES - 1)
+ fputc(',', stdout);
+ fputs("]}\n", stdout);
+ }
+ }
+ else
+ {
+ fprintf(stdout, "Average %13.9f\n", average);
+ fprintf(stdout, "First rank\n");
+ for (i = 0; i < NSAMPLES; i++)
+ fprintf(stdout, "%2d %13.9f\n", i, gtod[i]);
+ fprintf(stdout, "Last rank\n");
+ for (i = NBUF - 12; i < NBUF - 2; i++)
+ fprintf(stdout, "%2d %13.9f\n", i, gtod[i]);
+ }
}
/* end */
diff --git a/ntpfrob/main.c b/ntpfrob/main.c
index 3073b9a..5785553 100644
--- a/ntpfrob/main.c
+++ b/ntpfrob/main.c
@@ -5,6 +5,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
+#include <stdbool.h>
#include "config.h"
@@ -12,20 +13,21 @@
* Our methods, one per linked module
*/
extern void ppscheck(char *device);
-extern void tickadj(const int tick);
-extern void jitter(void);
+extern void tickadj(const bool json, const int tick);
+extern void jitter(const bool json);
extern void stepback(void);
-extern void precision(void);
+extern void precision(const bool json);
int
main(int argc, char **argv)
{
int ch;
- while ((ch = getopt(argc, argv, "aA:cp:")) != EOF) {
+ bool json = false;
+ while ((ch = getopt(argc, argv, "a:Acejp:")) != EOF) {
switch (ch) {
case 'A':
#ifdef HAVE_ADJTIMEX
- tickadj(0);
+ tickadj(json, 0);
#else
fputs("ntpfrob: no adjtimex(2) call.\n", stderr);
exit(0);
@@ -33,16 +35,23 @@ main(int argc, char **argv)
break;
case 'a':
#ifdef HAVE_ADJTIMEX
- tickadj(atoi(optarg));
+ tickadj(json, atoi(optarg));
#else
fputs("ntpfrob: no adjtimex(2) call.\n", stderr);
exit(0);
#endif
break;
case 'c':
- jitter();
+ jitter(json);
exit(0);
break;
+ case 'e':
+ precision(json);
+ exit(0);
+ break;
+ case 'j':
+ json = true;
+ break;
case 'p':
#ifdef HAVE_SYS_TIMEPPS_H
ppscheck(optarg);
@@ -51,6 +60,10 @@ main(int argc, char **argv)
exit(0);
#endif
break;
+ default:
+ fputs("ntpfrob: no mode option specified.\n", stderr);
+ exit(1);
+ break;
}
}
diff --git a/ntpfrob/precision.c b/ntpfrob/precision.c
index 470cb4e..29d01f2 100644
--- a/ntpfrob/precision.c
+++ b/ntpfrob/precision.c
@@ -6,17 +6,23 @@
#include "ntp_unixtime.h"
#include <stdio.h>
+#include <stdbool.h>
#define DEFAULT_SYS_PRECISION -99
-int default_get_resolution();
-int default_get_precision();
+int default_get_resolution(void);
+int default_get_precision(void);
-void precision(void)
+void precision(const bool json)
{
- printf("log2(resolution) = %d, log2(precision) = %d\n",
- default_get_resolution(),
- default_get_precision());
+ if (json)
+ printf("{\"log2 of resolution\":%d, \"log2 of precision\":%d}\n",
+ default_get_resolution(),
+ default_get_precision());
+ else
+ printf("log2(resolution) = %d, log2(precision) = %d\n",
+ default_get_resolution(),
+ default_get_precision());
}
/* Find the resolution of the system clock by watching how the current time
@@ -80,23 +86,24 @@ default_get_resolution(void)
last = tp.tv_usec;
}
- printf("resolution = %ld usec after %d loop%s\n",
+ fprintf(stderr, "resolution = %ld usec after %d loop%s\n",
diff, i, (i==1) ? "" : "s");
diff = (diff *3)/2;
if (i >= MAXLOOPS) {
- printf(
+ fprintf(stderr,
" (Boy this machine is fast ! %d loops without a step)\n",
MAXLOOPS);
diff = 1; /* No STEP, so FAST machine */
}
if (i == 0) {
- printf(
+ fprintf(stderr,
" (The resolution is less than the time to read the clock -- Assume 1us)\n");
diff = 1; /* time to read clock >= resolution */
}
for (i=0, val=HUSECS; val>0; i--, val >>= 1) if (diff >= val) return i;
- printf(" (Oh dear -- that wasn't expected ! I'll guess !)\n");
+ fprintf(stderr,
+ " (Oh dear -- that wasn't expected ! I'll guess !)\n");
return DEFAULT_SYS_PRECISION /* Something's BUST, so lie ! */;
}
@@ -157,10 +164,10 @@ default_get_precision(void)
val = diff;
}
}
- printf("precision = %ld usec after %d loop%s\n",
+ fprintf(stderr, "precision = %ld usec after %d loop%s\n",
val, i, (i == 1) ? "" : "s");
if (usec >= HUSECS) {
- printf(" (Boy this machine is fast ! usec was %ld)\n",
+ fprintf(stderr, " (Boy this machine is fast ! usec was %ld)\n",
usec);
val = MINSTEP; /* val <= MINSTEP; fast machine */
}
diff --git a/ntpfrob/tickadj.c b/ntpfrob/tickadj.c
index 11f6f57..c61f06b 100644
--- a/ntpfrob/tickadj.c
+++ b/ntpfrob/tickadj.c
@@ -25,7 +25,7 @@
static struct timex txc;
-void tickadj(const int newtick)
+void tickadj(const bool json, const int newtick)
{
if (newtick != 0)
{
@@ -68,9 +68,17 @@ void tickadj(const int newtick)
else
{
#ifdef STRUCT_TIMEX_HAS_TIME_TICK
- printf("tick = %ld\ntick_adj = %ld\n", txc.time_tick, txc.tickadj);
+ if (json)
+ printf("{\"tick\":%ld,\"tick_adj\":%ld}\n",
+ txc.time_tick, txc.tickadj);
+ else
+ printf("tick = %ld\ntick_adj = %ld\n",
+ txc.time_tick, txc.tickadj);
#else
- printf("tick = %ld\n", txc.tick);
+ if (json)
+ printf("{\"tick\":%ld}\n", txc.tick);
+ else
+ printf("tick = %ld\n", txc.tick);
#endif
}
More information about the vc
mailing list