From 87adbb213b8569e49928bccaa389c0ffed597586 Mon Sep 17 00:00:00 2001 From: Nikolai R Kristiansen Date: Fri, 29 Jul 2016 17:31:14 +0200 Subject: [PATCH] Add support for JSON as report output format This is based on the equivalent code for XML. --- display.c | 10 ++++++ display.h | 2 +- mtr.8 | 9 ++++++ mtr.c | 9 ++++-- report.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- report.h | 2 ++ 6 files changed, 123 insertions(+), 4 deletions(-) diff --git a/display.c b/display.c index d98863d..584c7a0 100644 --- a/display.c +++ b/display.c @@ -88,6 +88,9 @@ void display_open(void) case DisplayTXT: txt_open(); break; + case DisplayJSON: + json_open(); + break; case DisplayXML: xml_open(); break; @@ -124,6 +127,9 @@ void display_close(time_t now) case DisplayTXT: txt_close(); break; + case DisplayJSON: + json_close(); + break; case DisplayXML: xml_close(); break; @@ -197,6 +203,7 @@ void display_rawping(int host, int msec, int seq) switch(DisplayMode) { case DisplayReport: case DisplayTXT: + case DisplayJSON: case DisplayXML: case DisplayCSV: case DisplaySplit: @@ -215,6 +222,7 @@ void display_rawhost(int host, ip_t *ip_addr) switch(DisplayMode) { case DisplayReport: case DisplayTXT: + case DisplayJSON: case DisplayXML: case DisplayCSV: case DisplaySplit: @@ -233,6 +241,7 @@ void display_loop(void) switch(DisplayMode) { case DisplayReport: case DisplayTXT: + case DisplayJSON: case DisplayXML: case DisplayCSV: case DisplaySplit: @@ -255,6 +264,7 @@ void display_clear(void) break; case DisplayReport: case DisplayTXT: + case DisplayJSON: case DisplayXML: case DisplayCSV: case DisplaySplit: diff --git a/display.h b/display.h index eb821ea..294f618 100644 --- a/display.h +++ b/display.h @@ -27,7 +27,7 @@ enum { ActionNone, ActionQuit, ActionReset, ActionDisplay, #endif ActionScrollDown, ActionScrollUp }; enum { DisplayReport, DisplayCurses, DisplayGTK, DisplaySplit, - DisplayRaw, DisplayXML, DisplayCSV, DisplayTXT}; + DisplayRaw, DisplayXML, DisplayCSV, DisplayTXT, DisplayJSON}; /* Prototypes for display.c */ void display_detect(int *argc, char ***argv); diff --git a/mtr.8 b/mtr.8 index 03af3af..8e41b8c 100644 --- a/mtr.8 +++ b/mtr.8 @@ -35,6 +35,9 @@ mtr \- a network diagnostic tool .B \-\-csv\c ] [\c +.B \-\-json\c +] +[\c .B \-\-split\c ] [\c @@ -242,6 +245,12 @@ MTR.0.86+git:16e39fc0;1435562787;OK;nic.is;6;rix-k2-gw.isnic.is;1654 MTR.0.86+git:16e39fc0;1435562787;OK;nic.is;7;www.isnic.is;1036 .fi .TP +.B \-j\fR, \fB\-\-json +Use this option to tell +.B mtr +to use the JSON output format. This format is better suited for +automated processing of the measurement results. +.TP .B \-p\fR, \fB\-\-split Use this option to set .B mtr diff --git a/mtr.c b/mtr.c index 88aea6c..d748412 100644 --- a/mtr.c +++ b/mtr.c @@ -285,6 +285,7 @@ void parse_arg (int argc, char **argv) { "gtk", 0, NULL, 'g' }, { "raw", 0, NULL, 'l' }, { "csv", 0, NULL, 'C' }, + { "json", 0, NULL, 'j' }, { "displaymode", 1, NULL, 'd' }, { "split", 0, NULL, 'p' }, /* BL */ /* maybe above should change to -d 'x' */ @@ -323,7 +324,7 @@ void parse_arg (int argc, char **argv) opt = 0; while(1) { opt = getopt_long(argc, argv, - "hv46F:rwxtglCpnbo:y:zi:c:s:B:Q:ea:f:m:U:uTSP:L:Z:G:M:", long_options, NULL); + "hv46F:rwxtglCjpnbo:y:zi:c:s:B:Q:ea:f:m:U:uTSP:L:Z:G:M:", long_options, NULL); if(opt == -1) break; @@ -357,6 +358,9 @@ void parse_arg (int argc, char **argv) case 'C': DisplayMode = DisplayCSV; break; + case 'j': + DisplayMode = DisplayJSON; + break; case 'x': DisplayMode = DisplayXML; break; @@ -546,6 +550,7 @@ void parse_arg (int argc, char **argv) if (DisplayMode == DisplayReport || DisplayMode == DisplayTXT || + DisplayMode == DisplayJSON || DisplayMode == DisplayXML || DisplayMode == DisplayRaw || DisplayMode == DisplayCSV) @@ -645,7 +650,7 @@ int main(int argc, char **argv) if (PrintHelp) { printf("usage: %s [--help] [--version] [-4|-6] [-F FILENAME]\n" "\t\t[--report] [--report-wide] [--displaymode MODE]\n" - "\t\t[--xml] [--gtk] [--curses] [--raw] [--csv] [--split]\n" + "\t\t[--xml] [--gtk] [--curses] [--raw] [--csv] [--json] [--split]\n" "\t\t[--no-dns] [--show-ips] [-o FIELDS] [-y IPINFO] [--aslookup]\n" "\t\t[-i INTERVAL] [-c COUNT] [-s PACKETSIZE] [-B BITPATTERN]\n" "\t\t[-Q TOS] [--mpls]\n" diff --git a/report.c b/report.c index e0a9548..b47a855 100644 --- a/report.c +++ b/report.c @@ -253,11 +253,104 @@ void txt_open(void) void txt_close(void) -{ +{ report_close(); } +void json_open(void) +{ +} + + +void json_close(void) +{ + int i, j, at, first, max; + ip_t *addr; + char name[81]; + + printf("{\n"); + printf(" \"report\": {\n"); + printf(" \"mtr\": {\n"); + printf(" \"src\": \"%s\",\n", LocalHostname); + printf(" \"dst\": \"%s\",\n", Hostname); + printf(" \"tos\": \"0x%X\",\n", tos); + if(cpacketsize >= 0) { + printf(" \"psize\": \"%d\",\n", cpacketsize); + } else { + printf(" \"psize\": \"rand(%d-%d)\",\n",MINPACKET, -cpacketsize); + } + if( bitpattern>=0 ) { + printf(" \"bitpattern\": \"0x%02X\",\n", (unsigned char)(bitpattern)); + } else { + printf(" \"bitpattern\": \"rand(0x00-FF)\",\n"); + } + printf(" \"tests\": \"%d\"\n", MaxPing); + printf(" },\n"); + + printf(" \"hubs\": ["); + + max = net_max(); + at = first = net_min(); + for(; at < max; at++) { + addr = net_addr(at); + snprint_addr(name, sizeof(name), addr); + + if(at == first) { + printf("{\n"); + } else { + printf(" {\n"); + } + printf(" \"count\": \"%d\",\n", at+1); + printf(" \"host\": \"%s\",\n", name); + for( i=0; i 0 && i != 0) { + printf(",\n"); + } + + if (j <= 0) continue; // Field nr 0, " " shouldn't be printed in this method. + + /* Format value */ + const char *format; + format = data_fields[j].format; + if( index(format, 'f') ) { + format = "%.2f"; + } else { + format = "%d"; + } + + /* Format json line */ + strcpy(name, " \"%s\": "); + strcat(name, format); + + /* Output json line */ + if(index(data_fields[j].format, 'f')) { + /* 1000.0 is a temporay hack for stats usec to ms, impacted net_loss. */ + printf(name, + data_fields[j].title, + data_fields[j].net_xxx(at) / 1000.0); + } else { + printf(name, + data_fields[j].title, + data_fields[j].net_xxx(at)); + } + } + if(at+1 == max) { + printf(" }]\n"); + } else { + printf(" },\n"); + } + } + printf(" }\n"); + printf("}\n"); +} + + void xml_open(void) { diff --git a/report.h b/report.h index 81c2d81..566be3e 100644 --- a/report.h +++ b/report.h @@ -22,6 +22,8 @@ void report_open(void); void report_close(void); void txt_open(void); void txt_close(void); +void json_open(void); +void json_close(void); void xml_open(void); void xml_close(void); void csv_open(void); -- 2.47.2