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 *congestion; /* -C option */
|
||||||
char *pidfile; /* -P option */
|
char *pidfile; /* -P option */
|
||||||
|
|
||||||
|
char *logfile; /* --logfile option */
|
||||||
|
FILE *outfile;
|
||||||
|
|
||||||
int ctrl_sck;
|
int ctrl_sck;
|
||||||
int listener;
|
int listener;
|
||||||
int prot_listener;
|
int prot_listener;
|
||||||
|
@ -55,6 +55,9 @@ give more detailed output
|
|||||||
.BR -J ", " --json " "
|
.BR -J ", " --json " "
|
||||||
output in JSON format
|
output in JSON format
|
||||||
.TP
|
.TP
|
||||||
|
.BR --logfile " \fIfile\fR"
|
||||||
|
send output to a log file.
|
||||||
|
.TP
|
||||||
.BR -d ", " --debug " "
|
.BR -d ", " --debug " "
|
||||||
emit debugging output.
|
emit debugging output.
|
||||||
Primarily (perhaps exclusively) of use to developers.
|
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},
|
{"sctp", no_argument, NULL, OPT_SCTP},
|
||||||
#endif
|
#endif
|
||||||
{"pidfile", required_argument, NULL, 'I'},
|
{"pidfile", required_argument, NULL, 'I'},
|
||||||
|
{"logfile", required_argument, NULL, OPT_LOGFILE},
|
||||||
{"debug", no_argument, NULL, 'd'},
|
{"debug", no_argument, NULL, 'd'},
|
||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
{NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0}
|
||||||
@ -791,6 +792,9 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
|||||||
test->pidfile = strdup(optarg);
|
test->pidfile = strdup(optarg);
|
||||||
server_flag = 1;
|
server_flag = 1;
|
||||||
break;
|
break;
|
||||||
|
case OPT_LOGFILE:
|
||||||
|
test->logfile = strdup(optarg);
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
default:
|
default:
|
||||||
usage_long();
|
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. */
|
/* Check flag / role compatibility. */
|
||||||
if (test->role == 'c' && server_flag) {
|
if (test->role == 'c' && server_flag) {
|
||||||
i_errno = IESERVERONLY;
|
i_errno = IESERVERONLY;
|
||||||
@ -2524,9 +2540,8 @@ iperf_json_finish(struct iperf_test *test)
|
|||||||
str = cJSON_Print(test->json_top);
|
str = cJSON_Print(test->json_top);
|
||||||
if (str == NULL)
|
if (str == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
fputs(str, stdout);
|
fprintf(test->outfile, "%s\n", str);
|
||||||
putchar('\n');
|
iflush(test);
|
||||||
fflush(stdout);
|
|
||||||
free(str);
|
free(str);
|
||||||
cJSON_Delete(test->json_top);
|
cJSON_Delete(test->json_top);
|
||||||
test->json_top = test->json_start = test->json_intervals = test->json_end = NULL;
|
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;
|
int r;
|
||||||
|
|
||||||
if (test->title)
|
if (test->title)
|
||||||
printf("%s: ", test->title);
|
fprintf(test->outfile, "%s: ", test->title);
|
||||||
va_start(argp, format);
|
va_start(argp, format);
|
||||||
r = vprintf(format, argp);
|
r = vfprintf(test->outfile, format, argp);
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
return r;
|
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 */
|
/* short option equivalents, used to support options that only have long form */
|
||||||
#define OPT_SCTP 1
|
#define OPT_SCTP 1
|
||||||
|
#define OPT_LOGFILE 2
|
||||||
|
|
||||||
/* states */
|
/* states */
|
||||||
#define TEST_START 1
|
#define TEST_START 1
|
||||||
@ -225,7 +226,7 @@ int iperf_clearaffinity(struct iperf_test *);
|
|||||||
|
|
||||||
/* Custom printf routine. */
|
/* Custom printf routine. */
|
||||||
int iprintf(struct iperf_test *test, const char *format, ...) __attribute__ ((format(printf,2,3)));
|
int iprintf(struct iperf_test *test, const char *format, ...) __attribute__ ((format(printf,2,3)));
|
||||||
|
int iflush(struct iperf_test *test);
|
||||||
|
|
||||||
/* Error routines. */
|
/* Error routines. */
|
||||||
void iperf_err(struct iperf_test *test, const char *format, ...) __attribute__ ((format(printf,2,3)));
|
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
|
IEFILE = 14, // -F file couldn't be opened
|
||||||
IEBURST = 15, // Invalid burst count. Maximum value = %dMAX_BURST
|
IEBURST = 15, // Invalid burst count. Maximum value = %dMAX_BURST
|
||||||
IEENDCONDITIONS = 16, // Only one test end condition (-t, -n, -k) may be specified
|
IEENDCONDITIONS = 16, // Only one test end condition (-t, -n, -k) may be specified
|
||||||
|
IELOGFILE = 17, // Can't open log file
|
||||||
/* Test errors */
|
/* Test errors */
|
||||||
IENEWTEST = 100, // Unable to create a new test (check perror)
|
IENEWTEST = 100, // Unable to create a new test (check perror)
|
||||||
IEINITTEST = 101, // Test initialization failed (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\n", version);
|
||||||
iprintf(test, "%s", "");
|
iprintf(test, "%s", "");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
printf("%s\n", get_system_info());
|
iprintf("%s\n", get_system_info());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start the client and connect to the server */
|
/* Start the client and connect to the server */
|
||||||
@ -479,5 +479,7 @@ iperf_run_client(struct iperf_test * test)
|
|||||||
iprintf(test, "%s", report_done);
|
iprintf(test, "%s", report_done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iflush(test);
|
||||||
|
|
||||||
return 0;
|
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)
|
if (test != NULL && test->json_output && test->json_top != NULL)
|
||||||
cJSON_AddStringToObject(test->json_top, "error", str);
|
cJSON_AddStringToObject(test->json_top, "error", str);
|
||||||
else
|
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);
|
va_end(argp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do a printf to stderr, then exit. */
|
/* Do a printf to stderr or log file as appropriate, then exit. */
|
||||||
void
|
void
|
||||||
iperf_errexit(struct iperf_test *test, const char *format, ...)
|
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);
|
cJSON_AddStringToObject(test->json_top, "error", str);
|
||||||
iperf_json_finish(test);
|
iperf_json_finish(test);
|
||||||
} else
|
} 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);
|
va_end(argp);
|
||||||
iperf_delete_pidfile(test);
|
iperf_delete_pidfile(test);
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -116,6 +126,10 @@ iperf_strerror(int i_errno)
|
|||||||
case IEENDCONDITIONS:
|
case IEENDCONDITIONS:
|
||||||
snprintf(errstr, len, "only one test end condition (-t, -n, -k) may be specified");
|
snprintf(errstr, len, "only one test end condition (-t, -n, -k) may be specified");
|
||||||
break;
|
break;
|
||||||
|
case IELOGFILE:
|
||||||
|
snprintf(errstr, len, "unable to open log file");
|
||||||
|
perr = 1;
|
||||||
|
break;
|
||||||
case IENEWTEST:
|
case IENEWTEST:
|
||||||
snprintf(errstr, len, "unable to create a new test");
|
snprintf(errstr, len, "unable to create a new test");
|
||||||
perr = 1;
|
perr = 1;
|
||||||
|
@ -65,8 +65,8 @@ iperf_server_listen(struct iperf_test *test)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!test->json_output) {
|
if (!test->json_output) {
|
||||||
printf("-----------------------------------------------------------\n");
|
iprintf(test, "-----------------------------------------------------------\n");
|
||||||
printf("Server listening on %d\n", test->server_port);
|
iprintf(test, "Server listening on %d\n", test->server_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This needs to be changed to reflect if client has different window size
|
// 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\n", version);
|
||||||
iprintf(test, "%s", "");
|
iprintf(test, "%s", "");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
printf("%s\n", get_system_info());
|
iprintf(test, "%s\n", get_system_info());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open socket and listen
|
// Open socket and listen
|
||||||
@ -602,6 +602,8 @@ iperf_run_server(struct iperf_test *test)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iflush(test);
|
||||||
|
|
||||||
if (test->server_affinity != -1)
|
if (test->server_affinity != -1)
|
||||||
if (iperf_clearaffinity(test) != 0)
|
if (iperf_clearaffinity(test) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -78,6 +78,7 @@ const char usage_longstr[] = "Usage: iperf [-s|-c host] [options]\n"
|
|||||||
#endif
|
#endif
|
||||||
" -V, --verbose more detailed output\n"
|
" -V, --verbose more detailed output\n"
|
||||||
" -J, --json output in JSON format\n"
|
" -J, --json output in JSON format\n"
|
||||||
|
" --logfile f send output to a log file\n"
|
||||||
" -d, --debug emit debugging output\n"
|
" -d, --debug emit debugging output\n"
|
||||||
" -v, --version show version information and quit\n"
|
" -v, --version show version information and quit\n"
|
||||||
" -h, --help show this message and quit\n"
|
" -h, --help show this message and quit\n"
|
||||||
|
Загрузка…
Ссылка в новой задаче
Block a user