#1469074 Any Juniper's patch (against outliers) added

This commit is contained in:
Stephane Bortzmeyer 2007-03-07 21:01:55 +00:00
parent 43876de96e
commit d6dc37c4f9
3 changed files with 93 additions and 6 deletions

View File

@ -26,11 +26,12 @@ char *progname;
int return_code = 0;
int rc;
unsigned int number = 1;
struct timeval max, min, total, median, stddev, temp;
struct timeval max, min, total, median, stddev, temp, measured;
struct timeval conntv, connectedtv, sendtv, recvtv;
unsigned int successes, attempts = 0;
unsigned int size = DEFLINE;
unsigned int j = 0;
int n_stddev = 0;
int family = PF_UNSPEC;
@ -99,6 +100,7 @@ main(argc, argv)
boolean timeout_requested = 0;
boolean size_requested = 0;
char *url = "";
boolean measure_data_transfer_only = FALSE;
#if USE_SIGACTION
struct sigaction mysigaction;
#endif
@ -188,6 +190,9 @@ main(argc, argv)
{"ipv6", '6', POPT_ARG_NONE, NULL, '6'},
{"module", 'm', POPT_ARG_STRING, &plugin_name, 'm',
"Loads the given plugin"},
{"dataonly", 'D', POPT_ARG_NONE, NULL, 'D'},
{"numstddev", 'N', POPT_ARG_INT, &n_stddev, 'N',
"Number of stddeviations to classify outliers"},
POPT_TABLEEND
};
poptContext poptcon;
@ -291,6 +296,12 @@ main(argc, argv)
strcpy(port_name, "smtp");
port_to_use = USE_SMTP;
break;
case 'D':
measure_data_transfer_only = TRUE;
break;
case 'N':
remaining--;
break;
case 'p':
remaining--;
priority_requested = 1;
@ -905,6 +916,14 @@ main(argc, argv)
alarm(timeout);
}
(void) gettimeofday(&oldtv, (struct timezone *) NULL);
/* work out the time it took... */
if (measure_data_transfer_only) {
measured = recvtv;
tvsub(&measured, &sendtv);
} else {
measured = newtv;
tvsub(&measured, &oldtv);
}
if (plugin) {
plugin_result = plugin_execute();
if (plugin_result == -2)
@ -1392,7 +1411,10 @@ main(argc, argv)
}
#endif
results[i - 1].valid = 1;
results[i - 1].timevalue = newtv;
if (measure_data_transfer_only)
results[i - 1].timevalue = measured;
else
results[i - 1].timevalue = newtv;
successes++;
}
if (number > 1) {
@ -1497,6 +1519,13 @@ printstats()
printf("Median time: %d.%06d seconds (%.0f bytes per sec.)\n",
(int) median.tv_sec, (int) median.tv_usec,
(double) size / tv2double(median));
if (n_stddev) {
tvstddevavg(&stddev, successes, total, results,
(double) n_stddev);
printf
("Average of values within %d standard deviations: %d.%06d\n",
n_stddev, (int) stddev.tv_sec, (int) stddev.tv_usec);
}
}
}

View File

@ -206,6 +206,7 @@ void tvmin ();
void tvmax ();
int tvcmp ();
void tvstddev ();
void tvstddevavg ();
double tv2double ();
struct timeval double2tv ();
/* http.c */

View File

@ -102,7 +102,8 @@ tvstddev(out, number, average, results)
{
int i;
struct timeval result, avg, var = null_timeval;
struct timeval square, large, small;
struct timeval large, small;
double d_offset, d_square, d_variance = 0;
*out = null_timeval;
for (i = 0; i < number; i++) {
if (results[i].valid == 1) {
@ -119,16 +120,72 @@ tvstddev(out, number, average, results)
}
tvsub(&large, &small);
/* printf ("abs offset is %f\n", tv2double (large)); */
square = double2tv(pow(tv2double(large), 2));
tvadd(&var, &square);
d_offset = tv2double(large);
d_square = d_offset * d_offset;
d_variance += d_square;
/* printf ("variance is now %f\n", tv2double (var)); */
}
}
result = double2tv(sqrt(tv2double(var) / number));
result = double2tv(sqrt(d_variance / (double) number));
out->tv_sec = result.tv_sec;
out->tv_usec = result.tv_usec;
}
/* tvstddevavg -- Computes the average of values within a set of results where the
* sample is within the given number of standard deviations from the average */
void
tvstddevavg(out, number, average, results, n_stddev)
struct timeval *out; /* contains std dev on entry */
int number;
struct timeval average;
struct result *results;
double n_stddev;
{
int i, valid = 0;
struct timeval result; /* working value */
struct timeval var = null_timeval; /* result accumulator */
double x;
double maxdev = tv2double(*out) * n_stddev;
if (tvcmp(out, &null_timeval) == 0) {
/* if the SD is 0 then we just return the average */
*out = average;
return;
}
for (i = 0; i < number; i++) {
if (results[i].valid == 1) {
result = results[i].timevalue;
tvsub(&result, &average);
/* printf ("value is %f (stddev is %f)\n", tv2double
* (result), tv2double (stddev)); */
/* ensure that result (difference to average) is absolute
* value */
if (tvcmp(&result, &null_timeval) == -1) {
result = average;
tvsub(&result, &results[i].timevalue);
}
x = tv2double(result);
/* printf("value is %g maxdev %g\n",x,maxdev); */
if (x <= maxdev) {
/* deviation is less than stddev */
tvadd(&var, &results[i].timevalue);
valid++;
} else {
/* printf("dropped\n"); */
}
}
}
/* printf ("total is %f in %d samples\n", tv2double (var), valid); */
if (valid > 0) {
*out = double2tv(tv2double(var) / valid);
} else {
*out = null_timeval;
}
}
/* tvcmp -- Compares two timeval structs */
int
tvcmp(left, right)