Skip to content

Commit

Permalink
feat: Add a --timestamps flag to prepend a timestamp to every output …
Browse files Browse the repository at this point in the history
…line.

Towards #909, inspired by suggestions by @davidBar-On.
  • Loading branch information
bmah888 committed Jul 15, 2020
1 parent d5d2e24 commit 15281f6
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/iperf.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* iperf, Copyright (c) 2014-2019, The Regents of the University of
* iperf, Copyright (c) 2014-2020, The Regents of the University of
* California, through Lawrence Berkeley National Laboratory (subject
* to receipt of any required approvals from the U.S. Dept. of
* Energy). All rights reserved.
Expand Down Expand Up @@ -301,6 +301,7 @@ struct iperf_test
int forceflush; /* --forceflush - flushing output at every interval */
int multisend;
int repeating_payload; /* --repeating-payload */
int timestamps; /* --timestamps */

char *json_output_string; /* rendered JSON output if json_output is set */
/* Select related parameters */
Expand Down
5 changes: 5 additions & 0 deletions src/iperf3.1
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ send output to a log file.
force flushing output at every interval.
Used to avoid buffering when sending output to pipe.
.TP
.BR --timestamps " "
prepend a timestamp at the start of each output line.
Timestamps have the format emitted by
.BR ctime ( 1 ).
.TP
.BR -d ", " --debug " "
emit debugging output.
Primarily (perhaps exclusively) of use to developers.
Expand Down
26 changes: 25 additions & 1 deletion src/iperf_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
{"omit", required_argument, NULL, 'O'},
{"file", required_argument, NULL, 'F'},
{"repeating-payload", no_argument, NULL, OPT_REPEATING_PAYLOAD},
{"timestamps", no_argument, NULL, OPT_TIMESTAMPS},
#if defined(HAVE_CPU_AFFINITY)
{"affinity", required_argument, NULL, 'A'},
#endif /* HAVE_CPU_AFFINITY */
Expand Down Expand Up @@ -1202,6 +1203,9 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
test->repeating_payload = 1;
client_flag = 1;
break;
case OPT_TIMESTAMPS:
test->timestamps = 1;
break;
case 'O':
test->omit = atoi(optarg);
if (test->omit < 0 || test->omit > 60) {
Expand Down Expand Up @@ -4269,11 +4273,24 @@ iperf_clearaffinity(struct iperf_test *test)
#endif /* neither HAVE_SCHED_SETAFFINITY nor HAVE_CPUSET_SETAFFINITY nor HAVE_SETPROCESSAFFINITYMASK */
}

char iperf_timestr[100];

int
iperf_printf(struct iperf_test *test, const char* format, ...)
{
va_list argp;
int r = -1;
time_t now;
struct tm *ltm = NULL;
char *ct = NULL;

/* Timestamp if requested */
if (test->timestamps) {
time(&now);
ltm = localtime(&now);
strftime(iperf_timestr, sizeof(iperf_timestr), "%c ", ltm);
ct = iperf_timestr;
}

/*
* There are roughly two use cases here. If we're the client,
Expand All @@ -4288,6 +4305,9 @@ iperf_printf(struct iperf_test *test, const char* format, ...)
* to be buffered up anyway.
*/
if (test->role == 'c') {
if (ct) {
fprintf(test->outfile, "%s", ct);
}
if (test->title)
fprintf(test->outfile, "%s: ", test->title);
va_start(argp, format);
Expand All @@ -4296,8 +4316,12 @@ iperf_printf(struct iperf_test *test, const char* format, ...)
}
else if (test->role == 's') {
char linebuffer[1024];
int i = 0;
if (ct) {
i = sprintf(linebuffer, "%s", ct);
}
va_start(argp, format);
r = vsnprintf(linebuffer, sizeof(linebuffer), format, argp);
r = vsnprintf(linebuffer + i, sizeof(linebuffer), format, argp);
va_end(argp);
fprintf(test->outfile, "%s", linebuffer);

Expand Down
3 changes: 3 additions & 0 deletions src/iperf_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ typedef uint64_t iperf_size_t;
#define OPT_EXTRA_DATA 19
#define OPT_BIDIRECTIONAL 20
#define OPT_SERVER_BITRATE_LIMIT 21
#define OPT_TIMESTAMPS 22

/* states */
#define TEST_START 1
Expand Down Expand Up @@ -116,6 +117,7 @@ double iperf_get_test_reporter_interval( struct iperf_test* ipt );
double iperf_get_test_stats_interval( struct iperf_test* ipt );
int iperf_get_test_num_streams( struct iperf_test* ipt );
int iperf_get_test_repeating_payload( struct iperf_test* ipt );
int iperf_get_test_timestamps( struct iperf_test* ipt );
int iperf_get_test_server_port( struct iperf_test* ipt );
char* iperf_get_test_server_hostname( struct iperf_test* ipt );
char* iperf_get_test_template( struct iperf_test* ipt );
Expand Down Expand Up @@ -152,6 +154,7 @@ void iperf_set_test_server_port( struct iperf_test* ipt, int server_port );
void iperf_set_test_socket_bufsize( struct iperf_test* ipt, int socket_bufsize );
void iperf_set_test_num_streams( struct iperf_test* ipt, int num_streams );
void iperf_set_test_repeating_payload( struct iperf_test* ipt, int repeating_payload );
void iperf_set_test_timestamps( struct iperf_test* ipt, int timestamps );
void iperf_set_test_role( struct iperf_test* ipt, char role );
void iperf_set_test_server_hostname( struct iperf_test* ipt, const char* server_hostname );
void iperf_set_test_template( struct iperf_test *ipt, const char *tmp_template );
Expand Down
36 changes: 36 additions & 0 deletions src/iperf_error.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,41 @@

int gerror;

char iperf_timestrerr[100];

/* Do a printf to stderr. */
void
iperf_err(struct iperf_test *test, const char *format, ...)
{
va_list argp;
char str[1000];
time_t now;
struct tm *ltm = NULL;
char *ct = NULL;

/* Timestamp if requested */
if (test != NULL && test->timestamps) {
time(&now);
ltm = localtime(&now);
strftime(iperf_timestrerr, sizeof(iperf_timestrerr), "%c ", ltm);
ct = iperf_timestrerr;
}

va_start(argp, format);
vsnprintf(str, sizeof(str), format, argp);
if (test != NULL && test->json_output && test->json_top != NULL)
cJSON_AddStringToObject(test->json_top, "error", str);
else
if (test && test->outfile && test->outfile != stdout) {
if (ct) {
fprintf(test->outfile, "%s", ct);
}
fprintf(test->outfile, "iperf3: %s\n", str);
}
else {
if (ct) {
fprintf(stderr, "%s", ct);
}
fprintf(stderr, "iperf3: %s\n", str);
}
va_end(argp);
Expand All @@ -62,6 +81,17 @@ iperf_errexit(struct iperf_test *test, const char *format, ...)
{
va_list argp;
char str[1000];
time_t now;
struct tm *ltm = NULL;
char *ct = NULL;

/* Timestamp if requested */
if (test != NULL && test->timestamps) {
time(&now);
ltm = localtime(&now);
strftime(iperf_timestrerr, sizeof(iperf_timestrerr), "%c ", ltm);
ct = iperf_timestrerr;
}

va_start(argp, format);
vsnprintf(str, sizeof(str), format, argp);
Expand All @@ -70,9 +100,15 @@ iperf_errexit(struct iperf_test *test, const char *format, ...)
iperf_json_finish(test);
} else
if (test && test->outfile && test->outfile != stdout) {
if (ct) {
fprintf(test->outfile, "%s", ct);
}
fprintf(test->outfile, "iperf3: %s\n", str);
}
else {
if (ct) {
fprintf(stderr, "%s", ct);
}
fprintf(stderr, "iperf3: %s\n", str);
}
va_end(argp);
Expand Down
1 change: 1 addition & 0 deletions src/iperf_locale.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n"
" -J, --json output in JSON format\n"
" --logfile f send output to a log file\n"
" --forceflush force flushing output at every interval\n"
" --timestamps emit a timestamp at the start of each output line\n"
" -d, --debug emit debugging output\n"
" -v, --version show version information and quit\n"
" -h, --help show this message and quit\n"
Expand Down

0 comments on commit 15281f6

Please sign in to comment.