This is based on the equivalent code for XML.
case DisplayTXT:
txt_open();
break;
+ case DisplayJSON:
+ json_open();
+ break;
case DisplayXML:
xml_open();
break;
case DisplayTXT:
txt_close();
break;
+ case DisplayJSON:
+ json_close();
+ break;
case DisplayXML:
xml_close();
break;
switch(DisplayMode) {
case DisplayReport:
case DisplayTXT:
+ case DisplayJSON:
case DisplayXML:
case DisplayCSV:
case DisplaySplit:
switch(DisplayMode) {
case DisplayReport:
case DisplayTXT:
+ case DisplayJSON:
case DisplayXML:
case DisplayCSV:
case DisplaySplit:
switch(DisplayMode) {
case DisplayReport:
case DisplayTXT:
+ case DisplayJSON:
case DisplayXML:
case DisplayCSV:
case DisplaySplit:
break;
case DisplayReport:
case DisplayTXT:
+ case DisplayJSON:
case DisplayXML:
case DisplayCSV:
case DisplaySplit:
#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);
.B \-\-csv\c
]
[\c
+.B \-\-json\c
+]
+[\c
.B \-\-split\c
]
[\c
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
{ "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' */
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;
case 'C':
DisplayMode = DisplayCSV;
break;
+ case 'j':
+ DisplayMode = DisplayJSON;
+ break;
case 'x':
DisplayMode = DisplayXML;
break;
if (DisplayMode == DisplayReport ||
DisplayMode == DisplayTXT ||
+ DisplayMode == DisplayJSON ||
DisplayMode == DisplayXML ||
DisplayMode == DisplayRaw ||
DisplayMode == DisplayCSV)
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"
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)
{
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);