Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/iperf.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,8 @@ struct iperf_test
int json_output; /* -J option - JSON output */
int json_stream; /* --json-stream */
int json_stream_full_output; /* --json-stream-full-output */
int json_stream_sum_only; /* --json-stream-sum-only */
int json_output_stream; /* --json-output-stream - output final JSON as a single stream */
void (*json_callback) (struct iperf_test *, char *); /* allow user apps to receive the
JSON strings,instead of writing them to the output file */
int zerocopy; /* -Z option - use sendfile */
Expand Down
12 changes: 12 additions & 0 deletions src/iperf3.1
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,12 @@ Produce more detailed output.
Output in JSON format instead of the default human-readable
output.
.TP
.BR -J ", " --json-output-stream" "
Output in JSON format as a single string.This flag only takes effect
if the
.B --json
option is also specified
.TP
.BR --json-stream " "
Output in line-delimited JSON format instead of the default
human-readable output. This option overrides the
Expand All @@ -178,6 +184,12 @@ effect if the
.B --json-stream
option was also specified.
.TP
.BR --json-stream-sum-only " "
Output only the final sum data with JSON streams. This flag only takes
effect if the
.B --json-stream
option was also specified.
.TP
.BR --logfile " \fIfile\fR"
Send output to a log file.
.TP
Expand Down
70 changes: 43 additions & 27 deletions src/iperf_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,11 @@ iperf_get_test_json_stream(struct iperf_test *ipt)
{
return ipt->json_stream;
}

int
iperf_get_test_json_stream_sum_only(struct iperf_test *ipt)
{
return ipt->json_stream_sum_only;
}
int
iperf_get_test_zerocopy(struct iperf_test *ipt)
{
Expand Down Expand Up @@ -931,7 +935,7 @@ iperf_on_test_start(struct iperf_test *test)
iperf_printf(test, test_start_time, test->protocol->name, test->num_streams, test->settings->blksize, test->omit, test->duration, test->settings->tos);
}
}
if (test->json_stream) {
if (test->json_stream && !test->json_stream_sum_only) {
JSONStream_Output(test, "start", test->json_start);
}
}
Expand Down Expand Up @@ -1106,8 +1110,10 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
{"one-off", no_argument, NULL, '1'},
{"verbose", no_argument, NULL, 'V'},
{"json", no_argument, NULL, 'J'},
{"json-output-stream", no_argument, NULL, OPT_JSON_OUTPUT_STREAM},
{"json-stream", no_argument, NULL, OPT_JSON_STREAM},
{"json-stream-full-output", no_argument, NULL, OPT_JSON_STREAM_FULL_OUTPUT},
{"json-stream-sum-only", no_argument, NULL, OPT_JSON_STREAM_SUM_ONLY},
{"version", no_argument, NULL, 'v'},
{"server", no_argument, NULL, 's'},
{"client", required_argument, NULL, 'c'},
Expand Down Expand Up @@ -1270,13 +1276,19 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
case 'J':
test->json_output = 1;
break;
case OPT_JSON_OUTPUT_STREAM:
test->json_output_stream = 1;
break;
case OPT_JSON_STREAM:
test->json_output = 1;
test->json_stream = 1;
break;
case OPT_JSON_STREAM_FULL_OUTPUT:
test->json_stream_full_output = 1;
break;
case OPT_JSON_STREAM_SUM_ONLY:
test->json_stream_sum_only = 1;
break;
case 'v':
printf("%s (cJSON %s)\n%s\n%s\n", version, cJSON_Version(), get_system_info(),
get_optional_features());
Expand Down Expand Up @@ -3939,7 +3951,7 @@ iperf_print_intermediate(struct iperf_test *test)
}
}

if (test->json_stream)
if (test->json_stream && !test->json_stream_sum_only)
JSONStream_Output(test, "interval", json_interval);
if (discard_json)
cJSON_Delete(json_interval);
Expand Down Expand Up @@ -5176,7 +5188,6 @@ iperf_json_finish(struct iperf_test *test)
}

int print_full_json = 1;

/* --json-stream, so we print various individual objects */
if (test->json_stream) {
cJSON *error = iperf_cJSON_GetObjectItemType(test->json_top, "error", cJSON_String);
Expand All @@ -5196,32 +5207,37 @@ iperf_json_finish(struct iperf_test *test)
}
/* Original --json output, single monolithic object */
if (print_full_json) {
/*
* Get ASCII rendering of JSON structure. Then make our
* own copy of it and return the storage that cJSON
* allocated on our behalf. We keep our own copy
* around.
*/
char *str = cJSON_Print(test->json_top);
if (str == NULL) {
return -1;
}
test->json_output_string = strdup(str);
cJSON_free(str);
if (test->json_output_string == NULL) {
return -1;
if(test->json_output_stream){
JSONStream_Output(test, "full_json", test->json_top);
}
if (test->json_callback != NULL) {
(test->json_callback)(test, test->json_output_string);
} else {
if (pthread_mutex_lock(&(test->print_mutex)) != 0) {
perror("iperf_json_finish: pthread_mutex_lock");
else {
/*
* Get ASCII rendering of JSON structure. Then make our
* own copy of it and return the storage that cJSON
* allocated on our behalf. We keep our own copy
* around.
*/
char *str = cJSON_Print(test->json_top);
if (str == NULL) {
return -1;
}
fprintf(test->outfile, "%s\n", test->json_output_string);
if (pthread_mutex_unlock(&(test->print_mutex)) != 0) {
perror("iperf_json_finish: pthread_mutex_unlock");
test->json_output_string = strdup(str);
cJSON_free(str);
if (test->json_output_string == NULL) {
return -1;
}
if (test->json_callback != NULL) {
(test->json_callback)(test, test->json_output_string);
} else {
if (pthread_mutex_lock(&(test->print_mutex)) != 0) {
perror("iperf_json_finish: pthread_mutex_lock");
}
fprintf(test->outfile, "%s\n", test->json_output_string);
if (pthread_mutex_unlock(&(test->print_mutex)) != 0) {
perror("iperf_json_finish: pthread_mutex_unlock");
}
iflush(test);
}
iflush(test);
}
}
cJSON_Delete(test->json_top);
Expand Down
6 changes: 6 additions & 0 deletions src/iperf_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ typedef atomic_uint_fast64_t atomic_iperf_size_t;
#define OPT_CNTL_KA 31
#define OPT_SKIP_RX_COPY 32
#define OPT_JSON_STREAM_FULL_OUTPUT 33
#define OPT_JSON_STREAM_SUM_ONLY 34
#define OPT_JSON_OUTPUT_STREAM 35

/* states */
#define TEST_START 1
Expand Down Expand Up @@ -157,6 +159,8 @@ int iperf_get_test_json_output( struct iperf_test* ipt );
char* iperf_get_test_json_output_string ( struct iperf_test* ipt );
int iperf_get_test_json_stream( struct iperf_test* ipt );
int iperf_get_test_json_stream_full_output( struct iperf_test* ipt );
int iperf_get_test_json_stream_sum_only( struct iperf_test* ipt);
int iperf_get_test_json_output_stream( struct iperf_test* ipt);
int iperf_get_test_zerocopy( struct iperf_test* ipt );
int iperf_get_test_get_server_output( struct iperf_test* ipt );
char iperf_get_test_unit_format(struct iperf_test *ipt);
Expand Down Expand Up @@ -203,6 +207,8 @@ void iperf_set_test_reverse( struct iperf_test* ipt, int reverse );
void iperf_set_test_json_output( struct iperf_test* ipt, int json_output );
void iperf_set_test_json_stream( struct iperf_test* ipt, int json_stream );
void iperf_set_test_json_stream_full_output( struct iperf_test* ipt, int json_stream_full_output );
void iperf_set_test_json_stream_sum_only ( struct iperf_test* ipt, int json_stream_sum_only);
void iperf_set_test_json_output_stream( struct iperf_test* ipt, int json_output_stream);
void iperf_set_test_json_callback(struct iperf_test *ipt, void (*callback)(struct iperf_test *, char *));
int iperf_has_zerocopy( void );
void iperf_set_test_zerocopy( struct iperf_test* ipt, int zerocopy );
Expand Down
2 changes: 2 additions & 0 deletions src/iperf_locale.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,10 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n"
#endif /* HAVE_SO_BINDTODEVICE */
" -V, --verbose more detailed output\n"
" -J, --json output in JSON format\n"
" --json-output-stream output in JSON format as a single string\n"
" --json-stream output in line-delimited JSON format\n"
" --json-stream-full-output output in JSON format with JSON streams enabled\n"
" --json-stream-sum-only output only sum data with JSON streams enabled\n"
" --logfile f send output to a log file\n"
" --forceflush force flushing output at every interval\n"
" --timestamps<=format> emit a timestamp at the start of each output line\n"
Expand Down