[ntpsec commit] Add JSON mode output to ntpdig, and document it.
Eric S. Raymond
esr at ntpsec.org
Wed Oct 14 18:59:49 UTC 2015
Module: ntpsec
Branch: master
Commit: 10051fd8ae545e87e75cd0a11955690121742c99
Changeset: http://git.ntpsec.org/ntpsec/commit/?id=10051fd8ae545e87e75cd0a11955690121742c99
Author: Eric S. Raymond <esr at thyrsus.com>
Date: Wed Oct 14 14:59:12 2015 -0400
Add JSON mode output to ntpdig, and document it.
---
devel-docs/TODO | 3 +++
docs/includes/ntpdig-body.txt | 32 +++++++++++++++++++++++++-------
ntpdig/kod_management.c | 2 +-
ntpdig/main.c | 39 +++++++++++++++++++++++++++------------
ntpdig/utilities.c | 7 +++++--
ntpdig/utilities.h | 2 +-
6 files changed, 62 insertions(+), 23 deletions(-)
diff --git a/devel-docs/TODO b/devel-docs/TODO
index e5e9115..cc6bb65 100644
--- a/devel-docs/TODO
+++ b/devel-docs/TODO
@@ -52,6 +52,9 @@ None right now. (Sep-22 2015)
* systime.c needs patching to put ntpdsim's hook back in place.
+* ntpfrob -c behaves mysteriously. Someone with domain knowledge (probably Hal)
+ should review the code.
+
* Fixup copyright notices.
See Mark's message of Oct-13th.
Subject: FLOSS license policy and copyright marking policy
diff --git a/docs/includes/ntpdig-body.txt b/docs/includes/ntpdig-body.txt
index 23e5a45..8d470ec 100644
--- a/docs/includes/ntpdig-body.txt
+++ b/docs/includes/ntpdig-body.txt
@@ -6,7 +6,7 @@
{ntpdig}
[--help | -?] [-4 | -6] [-a keynum] [-b bcaddress] [-B bctimeout]
- [-c] [-d] [-D debug-level] [-g delay] [-K kodfile] [-k keyfile]
+ [-c] [-d] [-D debug-level] [-g delay] [-j] [-K kodfile] [-k keyfile]
[-l logfile] [-M steplimit] [-o ntpver] [-r] [-S] [-s]
[-u uctimeout] [--wait] [--version] [address...]`
@@ -22,15 +22,15 @@ The default is to write the estimated correct local date and time (i.e.
not UTC) to the standard output in a format like:
-----------------------------------------------------
-1996-10-15 20:17:25.123 (+0800) +4.567 +/- 0.089 secs
+2015-10-14 13:46:04.534916 (+0500) -0.000007 +/- 0.084075 localhost 127.0.0.1 s2 no-leap
-----------------------------------------------------
-where the `(+0800)` means that to get to UTC from the reported local
-time one must add 8 hours and 0 minutes, the `4.567` indicates the
-local clock is 4.567 seconds behind the correct time (so 4.567 seconds
-must be added to the local clock to get it to be correct). Note that
+where the `(+0500)` means that to get to UTC from the reported local
+time one must add 5 hours and 0 minutes, the `-0.000007` indicates the
+local clock is 0.000007 seconds ahead of correct time (so 0.000007 seconds
+must be subtracted from the local clock to get it to be correct). Note that
the number of decimals printed for this value will change based on the
-reported precision of the server.`+/- 0.089` is the reported
+reported precision of the server.`+/- 0.084075` is the reported
_synchronization_ _distance_ (in seconds), which represents the
maximum error due to all causes. If the server does not report valid
data needed to calculate the synchronization distance, this will be
@@ -41,6 +41,21 @@ displayed. Otherwise, only the _IP_ is displayed. Finally, the
_stratum_ of the host is reported and the leap indicator is decoded
and displayed.
+With the -j (JSON) option, the output format becomes a self-describing
+JSON record:
+
+---------------------------------------------------------------------------------
+{"time":"2015-10-14T13:46:04.534916+0500",
+ "offset":-0.000007,"precision":"0.084075",
+ "host":"localhost",ip:"127.0.0.1",
+ "stratum":2,"leap":"noleap","adjusted":false}
+---------------------------------------------------------------------------------
+
+In the JSON format, time is in ISO8601 format; precision is the synch
+distance, with an unknown synch distance is reported as 0. Host and
+IP are always emitted even if duplicate. The "adjusted" boolean
+reports whether ntpdig adusted the time.
+
== OPTIONS ==
//`-?, --help`::
@@ -112,6 +127,9 @@ milliseconds. A larger _delay_ reduces the query load on the time
sources, iat the cost of ncreasing the time to receive a valid
response if the first source attempted is slow or unreachable.
+`-j`::
+ Output to stdout in JSON, suppressing syslog messages.
+
`-K` file-name, `--kod`=_file-name_::
KoD history filename. The default _file-name_ for this option is:
`/var/db/ntp-kod`.
diff --git a/ntpdig/kod_management.c b/ntpdig/kod_management.c
index 19536fd..d75c978 100644
--- a/ntpdig/kod_management.c
+++ b/ntpdig/kod_management.c
@@ -151,7 +151,7 @@ write_kod_db(void)
}
if (NULL == db_s) {
- msyslog(LOG_WARNING, "Can't open KOD db file %s for writing: %m",
+ msyslog(LOG_WARNING, "Can't open KoD db file %s for writing: %m",
kod_db_file);
return false;
diff --git a/ntpdig/main.c b/ntpdig/main.c
index bc77f83..78440e0 100644
--- a/ntpdig/main.c
+++ b/ntpdig/main.c
@@ -121,7 +121,7 @@ int gettimeofday_cached(struct event_base *b, struct timeval *tv);
#define EXIT_SOFTWARE 70
-#define ALL_OPTIONS "46a:b:c:dD:g:K:k:l:M:o:rSst:VwW"
+#define ALL_OPTIONS "46a:b:c:dD:g:jK:k:l:M:o:rSst:VwW"
static const struct option longoptions[] = {
{ "ipv4", 0, 0, '4' },
{ "ipv6", 0, 0, '6' },
@@ -132,6 +132,7 @@ static const struct option longoptions[] = {
{ "set-debug-level", 1, 0, 'D' },
{ "gap", 1, 0, 'g' },
{ "kod", 1, 0, 'K' },
+ { "json", 1, 0, 'j' },
{ "keyfile", 1, 0, 'k' },
{ "logfile", 1, 0, 'l' },
{ "steplimit", 1, 0, 'M' },
@@ -151,6 +152,7 @@ static char *opt_authkey = NULL;
static char *opt_broadcast = NULL;
static char *opt_concurrent = NULL;
static int opt_gap;
+static bool opt_json;
static char *opt_kodfile = "/var/db/ntp-kod";
static char *opt_keyfile = NULL;
static char *opt_logfile = NULL;
@@ -222,6 +224,10 @@ ntpdig_main (
exit(1);
}
break;
+ case 'j':
+ opt_json = true;
+ syslogit = false;
+ break;
case 'K':
opt_kodfile = ntp_optarg;
break;
@@ -284,7 +290,7 @@ ntpdig_main (
if (opt_logfile)
open_logfile(opt_logfile);
- msyslog(LOG_INFO, "ntpdig %s", ntpdigVersion);
+ //msyslog(LOG_INFO, "ntpdig %s", ntpdigVersion);
if (0 == argc && !opt_broadcast && !opt_concurrent) {
printf("%s: Must supply at least one of -b hostname, -c hostname, or hostname.\n",
@@ -1007,7 +1013,7 @@ sock_cb(
/* If the packet is good, set the time and we're all done */
rc = handle_pkt(rpktl, &r_pkt, &spkt->addr, spkt->dctx->name);
- if (0 != rc)
+ if (EXIT_SUCCESS != rc)
TRACE(1, ("sock_cb: handle_pkt() returned %d\n", rc));
check_exit_conditions();
}
@@ -1311,7 +1317,7 @@ handle_pkt(
if (digits > 6)
digits = 6;
- ts_str = tv_to_str(&tv_dst);
+ ts_str = tv_to_str(&tv_dst, opt_json);
stratum = rpkt->stratum;
if (0 == stratum)
stratum = 16;
@@ -1345,13 +1351,22 @@ handle_pkt(
break;
}
- msyslog(LOG_INFO, "%s %+.*f%s %s s%d %s%s", ts_str,
- digits, offset, disptxt,
- hostnameaddr(hostname, host), stratum,
- leaptxt,
- (time_adjusted)
- ? " [excess]"
- : "");
+ if (opt_json) {
+ printf("{\"time\"\"%s\",\"offset\":%f,\"precision\":%f,",
+ ts_str, offset, synch_distance);
+ printf("\"host\":\"%s\",\"ip\":\"%s\",",
+ hostname, stoa(host));
+ printf("\"stratum\":%d,\"leap\":\"%s\",\"adjusted\":%s}\n",
+ stratum,
+ leaptxt,
+ time_adjusted ? "true" : "false");
+ }
+ else
+ msyslog(LOG_INFO, "%s %+.*f%s %s s%d %s%s", ts_str,
+ digits, offset, disptxt,
+ hostnameaddr(hostname, host), stratum,
+ leaptxt,
+ time_adjusted ? " [excess]" : "");
free(ts_str);
if (p_NTPDIG_PRETEND_TIME)
@@ -1363,7 +1378,7 @@ handle_pkt(
return EXIT_SUCCESS;
}
- return 1;
+ return EXIT_FAILURE;
}
diff --git a/ntpdig/utilities.c b/ntpdig/utilities.c
index 0f763fc..193b6f4 100644
--- a/ntpdig/utilities.c
+++ b/ntpdig/utilities.c
@@ -134,7 +134,8 @@ ss_to_str(
*/
char *
tv_to_str(
- const struct timeval *tv
+ const struct timeval *tv,
+ const bool json
)
{
const size_t bufsize = 48;
@@ -142,6 +143,8 @@ tv_to_str(
time_t gmt_time, local_time;
struct tm tmbuf, tmbuf2, *p_tm_local;
int hh, mm, lto;
+ const char *oldstyle = "%d-%.2d-%.2d %.2d:%.2d:%.2d.%.6d (%+03d%02d)";
+ const char *jsonstyle = "%d-%.2d-%.2dT%.2d:%.2d:%.2d.%.6d%+03d%02d";
/*
* convert to struct tm in UTC, then intentionally feed
@@ -160,7 +163,7 @@ tv_to_str(
buf = emalloc(bufsize);
snprintf(buf, bufsize,
- "%d-%.2d-%.2d %.2d:%.2d:%.2d.%.6d (%+03d%02d)",
+ json ? jsonstyle : oldstyle,
p_tm_local->tm_year + 1900,
p_tm_local->tm_mon + 1,
p_tm_local->tm_mday,
diff --git a/ntpdig/utilities.h b/ntpdig/utilities.h
index bba6ffe..772f370 100644
--- a/ntpdig/utilities.h
+++ b/ntpdig/utilities.h
@@ -21,7 +21,7 @@ void l_fp_output_dec(l_fp *ts, FILE *output);
char *addrinfo_to_str(const struct addrinfo *addr);
char *ss_to_str(sockaddr_u *saddr);
-char *tv_to_str(const struct timeval *tv);
+char *tv_to_str(const struct timeval *tv, const bool json);
const char * hostnameaddr(const char *, const sockaddr_u *);
#endif /* GUARD_UTILITIES_H */
More information about the vc
mailing list