]> git.ipfire.org Git - thirdparty/mtr.git/commitdiff
Add support for JSON as report output format 127/head
authorNikolai R Kristiansen <nikolaik@gmail.com>
Fri, 29 Jul 2016 15:31:14 +0000 (17:31 +0200)
committerNikolai R Kristiansen <nikolaik@gmail.com>
Fri, 29 Jul 2016 15:31:14 +0000 (17:31 +0200)
This is based on the equivalent code for XML.

display.c
display.h
mtr.8
mtr.c
report.c
report.h

index d98863d87bf3f4c55d7b2ec042b9815c1a4b04ec..584c7a0af0a99e8e721b2af326942322708eb7da 100644 (file)
--- 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:
index eb821ea475960404e0d83e43147dd6ca73c19513..294f6184fb5cfb5b5abb1ca2d6d633b1fa55c4eb 100644 (file)
--- 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 03af3af1ed56c7ffd02c414868cd0884f2cff5dc..8e41b8c535c02a1eecad9f1c992d0628b930b324 100644 (file)
--- 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 88aea6c9f24927aeab3f4237912f170cf80ba9a9..d748412597d8a5770f4f1c1f74a4bf79385b12bd 100644 (file)
--- 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"
index e0a9548a60c647640afd9f217d6c2725945b92bf..b47a85504a8fd4718072535e2555ccc3806aeefa 100644 (file)
--- 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<MAXFLD; i++ ) {
+      j = fld_index[fld_active[i]];
+
+      /* Commas */
+      if(i + 1 == MAXFLD) {
+        printf("\n");
+      } else if (j > 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)
 {
index 81c2d81385828dc09092dcc7f3c28c6f8a095c98..566be3e4afbb82efaffedd557c2f9dbdc92bb323 100644 (file)
--- 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);