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.
Этот коммит содержится в:
родитель
3f5f7f7591
Коммит
aeb6938d5a
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
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
|
||||
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;
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user