Support --logfile argument to make all output go to a file.

This works for both client and server side (in the case of the server,
either for daemon or non-daemon mode).

Consistifies a few places that were using printf instead of iprintf.

Fixes Issue 119.
This commit is contained in:
Bruce A. Mah 2014-03-14 14:23:38 -07:00
parent 3f5f7f7591
commit aeb6938d5a
No known key found for this signature in database
GPG Key ID: 4984910A8CAAEE8A
8 changed files with 61 additions and 13 deletions

View File

@ -174,6 +174,9 @@ struct iperf_test
char *congestion; /* -C option */
char *pidfile; /* -P option */
char *logfile; /* --logfile option */
FILE *outfile;
int ctrl_sck;
int listener;
int prot_listener;

View File

@ -55,6 +55,9 @@ give more detailed output
.BR -J ", " --json " "
output in JSON format
.TP
.BR --logfile " \fIfile\fR"
send output to a log file.
.TP
.BR -d ", " --debug " "
emit debugging output.
Primarily (perhaps exclusively) of use to developers.

View File

@ -562,6 +562,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
{"sctp", no_argument, NULL, OPT_SCTP},
#endif
{"pidfile", required_argument, NULL, 'I'},
{"logfile", required_argument, NULL, OPT_LOGFILE},
{"debug", no_argument, NULL, 'd'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
@ -791,6 +792,9 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
test->pidfile = strdup(optarg);
server_flag = 1;
break;
case OPT_LOGFILE:
test->logfile = strdup(optarg);
break;
case 'h':
default:
usage_long();
@ -798,6 +802,18 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
}
}
/* Set logging to a file if specified, otherwise stdout*/
if (test->logfile) {
test->outfile = fopen(test->logfile, "a+");
if (test->outfile == NULL) {
i_errno = IELOGFILE;
return -1;
}
}
else {
test->outfile = stdout;
}
/* Check flag / role compatibility. */
if (test->role == 'c' && server_flag) {
i_errno = IESERVERONLY;
@ -2524,9 +2540,8 @@ iperf_json_finish(struct iperf_test *test)
str = cJSON_Print(test->json_top);
if (str == NULL)
return -1;
fputs(str, stdout);
putchar('\n');
fflush(stdout);
fprintf(test->outfile, "%s\n", str);
iflush(test);
free(str);
cJSON_Delete(test->json_top);
test->json_top = test->json_start = test->json_intervals = test->json_end = NULL;
@ -2608,9 +2623,15 @@ iprintf(struct iperf_test *test, const char* format, ...)
int r;
if (test->title)
printf("%s: ", test->title);
fprintf(test->outfile, "%s: ", test->title);
va_start(argp, format);
r = vprintf(format, argp);
r = vfprintf(test->outfile, format, argp);
va_end(argp);
return r;
}
int
iflush(struct iperf_test *test)
{
return fflush(test->outfile);
}

View File

@ -27,6 +27,7 @@ struct iperf_stream;
/* short option equivalents, used to support options that only have long form */
#define OPT_SCTP 1
#define OPT_LOGFILE 2
/* states */
#define TEST_START 1
@ -225,7 +226,7 @@ int iperf_clearaffinity(struct iperf_test *);
/* Custom printf routine. */
int iprintf(struct iperf_test *test, const char *format, ...) __attribute__ ((format(printf,2,3)));
int iflush(struct iperf_test *test);
/* Error routines. */
void iperf_err(struct iperf_test *test, const char *format, ...) __attribute__ ((format(printf,2,3)));
@ -251,6 +252,7 @@ enum {
IEFILE = 14, // -F file couldn't be opened
IEBURST = 15, // Invalid burst count. Maximum value = %dMAX_BURST
IEENDCONDITIONS = 16, // Only one test end condition (-t, -n, -k) may be specified
IELOGFILE = 17, // Can't open log file
/* Test errors */
IENEWTEST = 100, // Unable to create a new test (check perror)
IEINITTEST = 101, // Test initialization failed (check perror)

View File

@ -356,7 +356,7 @@ iperf_run_client(struct iperf_test * test)
iprintf(test, "%s\n", version);
iprintf(test, "%s", "");
fflush(stdout);
printf("%s\n", get_system_info());
iprintf("%s\n", get_system_info());
}
/* Start the client and connect to the server */
@ -479,5 +479,7 @@ iperf_run_client(struct iperf_test * test)
iprintf(test, "%s", report_done);
}
iflush(test);
return 0;
}

View File

@ -28,11 +28,16 @@ iperf_err(struct iperf_test *test, const char *format, ...)
if (test != NULL && test->json_output && test->json_top != NULL)
cJSON_AddStringToObject(test->json_top, "error", str);
else
fprintf(stderr, "iperf3: %s\n", str);
if (test && test->outfile) {
fprintf(test->outfile, "iperf3: %s\n", str);
}
else {
fprintf(stderr, "iperf3: %s\n", str);
}
va_end(argp);
}
/* Do a printf to stderr, then exit. */
/* Do a printf to stderr or log file as appropriate, then exit. */
void
iperf_errexit(struct iperf_test *test, const char *format, ...)
{
@ -45,7 +50,12 @@ iperf_errexit(struct iperf_test *test, const char *format, ...)
cJSON_AddStringToObject(test->json_top, "error", str);
iperf_json_finish(test);
} else
fprintf(stderr, "iperf3: %s\n", str);
if (test && test->outfile) {
fprintf(test->outfile, "iperf3: %s\n", str);
}
else {
fprintf(stderr, "iperf3: %s\n", str);
}
va_end(argp);
iperf_delete_pidfile(test);
exit(1);
@ -116,6 +126,10 @@ iperf_strerror(int i_errno)
case IEENDCONDITIONS:
snprintf(errstr, len, "only one test end condition (-t, -n, -k) may be specified");
break;
case IELOGFILE:
snprintf(errstr, len, "unable to open log file");
perr = 1;
break;
case IENEWTEST:
snprintf(errstr, len, "unable to create a new test");
perr = 1;

View File

@ -65,8 +65,8 @@ iperf_server_listen(struct iperf_test *test)
}
if (!test->json_output) {
printf("-----------------------------------------------------------\n");
printf("Server listening on %d\n", test->server_port);
iprintf(test, "-----------------------------------------------------------\n");
iprintf(test, "Server listening on %d\n", test->server_port);
}
// This needs to be changed to reflect if client has different window size
@ -450,7 +450,7 @@ iperf_run_server(struct iperf_test *test)
iprintf(test, "%s\n", version);
iprintf(test, "%s", "");
fflush(stdout);
printf("%s\n", get_system_info());
iprintf(test, "%s\n", get_system_info());
}
// Open socket and listen
@ -602,6 +602,8 @@ iperf_run_server(struct iperf_test *test)
return -1;
}
iflush(test);
if (test->server_affinity != -1)
if (iperf_clearaffinity(test) != 0)
return -1;

View File

@ -78,6 +78,7 @@ const char usage_longstr[] = "Usage: iperf [-s|-c host] [options]\n"
#endif
" -V, --verbose more detailed output\n"
" -J, --json output in JSON format\n"
" --logfile f send output to a log file\n"
" -d, --debug emit debugging output\n"
" -v, --version show version information and quit\n"
" -h, --help show this message and quit\n"