2
* This program is free software; you can redistribute it and/or modify
3
* it under the terms of the GNU General Public License as published by
4
* the Free Software Foundation; either version 2 of the License, or
5
* (at your option) any later version.
7
* This program is distributed in the hope that it will be useful,
8
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
* GNU General Public License for more details.
12
* You should have received a copy of the GNU General Public License
13
* along with this program; if not, write to the Free Software
14
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
* Authors : Benjamin GAUTHIER - 24 Mar 2004
20
* From Hewlett Packard Company.
28
#define TIME_LENGTH 64
29
#define DEFAULT_FILE_NAME (char*)"dumpFile"
30
#define DEFAULT_EXTENSION (char*)".csv"
32
#define MAX_CHAR_BUFFER_SIZE 1024
42
#include <gsl/gsl_rng.h>
43
#include <gsl/gsl_randist.h>
44
#include <gsl/gsl_cdf.h>
47
#include "variables.hpp"
52
__________________________________________________________________________
55
__________________________________________________________________________
59
* This class provides some means to compute and display statistics.
60
* This is a singleton class.
67
* This struct is used for repartition table
68
* border max is the max value allow for this range
69
* nbInThisBorder is the counter of value in this range
71
typedef struct _T_dynamicalRepartition
73
unsigned int borderMax;
74
unsigned long nbInThisBorder;
75
} T_dynamicalRepartition;
77
typedef struct _T_value_rtt
82
} T_value_rtt, *T_pValue_rtt ;
90
E_CREATE_OUTGOING_CALL,
91
E_CREATE_INCOMING_CALL,
93
E_CALL_SUCCESSFULLY_ENDED,
98
E_ADD_RESPONSE_TIME_DURATION,
99
E_FAILED_CANNOT_SEND_MSG,
100
E_FAILED_MAX_UDP_RETRANS,
101
E_FAILED_TCP_CONNECT,
103
E_FAILED_UNEXPECTED_MSG,
104
E_FAILED_CALL_REJECTED,
105
E_FAILED_CMD_NOT_SENT,
106
E_FAILED_REGEXP_DOESNT_MATCH,
107
E_FAILED_REGEXP_SHOULDNT_MATCH,
108
E_FAILED_REGEXP_HDR_NOT_FOUND,
109
E_FAILED_OUTBOUND_CONGESTION,
110
E_FAILED_TIMEOUT_ON_RECV,
111
E_FAILED_TIMEOUT_ON_SEND,
120
E_ADD_GENERIC_COUNTER
123
* Counters management
127
// Per-Scenario Counters
128
// Cumulative counters
129
CPT_C_IncomingCallCreated,
130
CPT_C_OutgoingCallCreated,
131
CPT_C_SuccessfulCall,
134
CPT_C_CurrentCallPeak,
135
CPT_C_CurrentCallPeakTime,
136
CPT_C_NbOfCallUsedForAverageCallLength,
137
CPT_C_AverageCallLength_Sum,
138
CPT_C_AverageCallLength_Squares,
139
CPT_C_FailedCallCannotSendMessage,
140
CPT_C_FailedCallMaxUdpRetrans,
141
CPT_C_FailedCallTcpConnect,
142
CPT_C_FailedCallTcpClosed,
143
CPT_C_FailedCallUnexpectedMessage,
144
CPT_C_FailedCallCallRejected,
145
CPT_C_FailedCallCmdNotSent,
146
CPT_C_FailedCallRegexpDoesntMatch,
147
CPT_C_FailedCallRegexpShouldntMatch,
148
CPT_C_FailedCallRegexpHdrNotFound,
149
CPT_C_FailedOutboundCongestion,
150
CPT_C_FailedTimeoutOnRecv,
151
CPT_C_FailedTimeoutOnSend,
152
CPT_C_Retransmissions,
154
// Periodic Display counter
155
CPT_PD_IncomingCallCreated, // must be first (RESET_PD_COUNTER macro)
156
CPT_PD_OutgoingCallCreated,
157
CPT_PD_SuccessfulCall,
159
CPT_PD_CurrentCallPeak,
160
CPT_PD_CurrentCallPeakTime,
161
CPT_PD_NbOfCallUsedForAverageCallLength,
162
CPT_PD_AverageCallLength_Sum,
163
CPT_PD_AverageCallLength_Squares,
164
CPT_PD_NbOfCallUsedForAverageResponseTime,
165
CPT_PD_NbOfCallUsedForAverageResponseTime_2, // This must match or exceed MAX_RTD_INFO
166
CPT_PD_NbOfCallUsedForAverageResponseTime_3, // This must match or exceed MAX_RTD_INFO
167
CPT_PD_NbOfCallUsedForAverageResponseTime_4, // This must match or exceed MAX_RTD_INFO
168
CPT_PD_NbOfCallUsedForAverageResponseTime_5, // This must match or exceed MAX_RTD_INFO
169
CPT_PD_AverageResponseTime_Sum,
170
CPT_PD_AverageResponseTime_Sum_2,
171
CPT_PD_AverageResponseTime_Sum_3,
172
CPT_PD_AverageResponseTime_Sum_4,
173
CPT_PD_AverageResponseTime_Sum_5,
174
CPT_PD_AverageResponseTime_Squares,
175
CPT_PD_AverageResponseTime_Squares_2,
176
CPT_PD_AverageResponseTime_Squares_3,
177
CPT_PD_AverageResponseTime_Squares_4,
178
CPT_PD_AverageResponseTime_Squares_5,
179
CPT_PD_FailedCallCannotSendMessage,
180
CPT_PD_FailedCallMaxUdpRetrans,
181
CPT_PD_FailedCallTcpConnect,
182
CPT_PD_FailedCallTcpClosed,
183
CPT_PD_FailedCallUnexpectedMessage,
184
CPT_PD_FailedCallCallRejected,
185
CPT_PD_FailedCallCmdNotSent,
186
CPT_PD_FailedCallRegexpDoesntMatch,
187
CPT_PD_FailedCallRegexpShouldntMatch,
188
CPT_PD_FailedCallRegexpHdrNotFound,
189
CPT_PD_FailedOutboundCongestion,
190
CPT_PD_FailedTimeoutOnRecv,
191
CPT_PD_FailedTimeoutOnSend,
192
CPT_PD_Retransmissions,
194
// Periodic logging counter
195
CPT_PL_IncomingCallCreated, // must be first (RESET_PL_COUNTER macro)
196
CPT_PL_OutgoingCallCreated,
197
CPT_PL_SuccessfulCall,
199
CPT_PL_CurrentCallPeak,
200
CPT_PL_CurrentCallPeakTime,
201
CPT_PL_NbOfCallUsedForAverageCallLength,
202
CPT_PL_AverageCallLength_Sum,
203
/* The squares let us compute the standard deviation. */
204
CPT_PL_AverageCallLength_Squares,
205
CPT_PL_NbOfCallUsedForAverageResponseTime,
206
CPT_PL_NbOfCallUsedForAverageResponseTime_2,
207
CPT_PL_NbOfCallUsedForAverageResponseTime_3,
208
CPT_PL_NbOfCallUsedForAverageResponseTime_4,
209
CPT_PL_NbOfCallUsedForAverageResponseTime_5,
210
CPT_PL_AverageResponseTime_Sum,
211
CPT_PL_AverageResponseTime_Sum_2,
212
CPT_PL_AverageResponseTime_Sum_3,
213
CPT_PL_AverageResponseTime_Sum_4,
214
CPT_PL_AverageResponseTime_Sum_5,
215
CPT_PL_AverageResponseTime_Squares,
216
CPT_PL_AverageResponseTime_Squares_2,
217
CPT_PL_AverageResponseTime_Squares_3,
218
CPT_PL_AverageResponseTime_Squares_4,
219
CPT_PL_AverageResponseTime_Squares_5,
220
CPT_PL_FailedCallCannotSendMessage,
221
CPT_PL_FailedCallMaxUdpRetrans,
222
CPT_PL_FailedCallTcpConnect,
223
CPT_PL_FailedCallTcpClosed,
224
CPT_PL_FailedCallUnexpectedMessage,
225
CPT_PL_FailedCallCallRejected,
226
CPT_PL_FailedCallCmdNotSent,
227
CPT_PL_FailedCallRegexpDoesntMatch,
228
CPT_PL_FailedCallRegexpShouldntMatch,
229
CPT_PL_FailedCallRegexpHdrNotFound,
230
CPT_PL_FailedOutboundCongestion,
231
CPT_PL_FailedTimeoutOnRecv,
232
CPT_PL_FailedTimeoutOnSend,
233
CPT_PL_Retransmissions,
238
// Cumulative counters
239
CPT_G_C_OutOfCallMsgs,
240
CPT_G_C_DeadCallMsgs,
243
CPT_G_C_WatchdogMajor,
244
CPT_G_C_WatchdogMinor,
245
CPT_G_C_AutoAnswered,
246
// Periodic Display counter
247
CPT_G_PD_OutOfCallMsgs,
248
CPT_G_PD_DeadCallMsgs,
249
CPT_G_PD_FatalErrors,
251
CPT_G_PD_WatchdogMajor,
252
CPT_G_PD_WatchdogMinor,
253
CPT_G_PD_AutoAnswered, // must be last (RESET_PD_COUNTER)
255
// Periodic logging counter
256
CPT_G_PL_OutOfCallMsgs,
257
CPT_G_PL_DeadCallMsgs,
258
CPT_G_PL_FatalErrors,
260
CPT_G_PL_WatchdogMajor,
261
CPT_G_PL_WatchdogMinor,
262
CPT_G_PL_AutoAnswered, // must be last (RESET_PL_COUNTER)
284
* Delete the single instance of the class.
286
* Only one instance of CStat exists in the component. This
287
* instance is deleted when the close method is called.
292
* ComputeStat Methods are used to modify counter value
293
* It's the main interface to update counter
295
* @return 0 if the action is known
298
int computeStat (E_Action P_action);
299
int computeStat (E_Action P_action, unsigned long P_value);
300
int computeStat (E_Action P_action, unsigned long P_value, int which);
302
/* This works for global counters and does not require an instance. */
303
static int globalStat (E_Action P_action);
306
* ComputeRtt Methods are used to calculate the response time
308
void computeRtt ( unsigned long long P_start_time, unsigned long long P_stop_time, int which);
311
* GetStat Method is used to retrieve a counter value
313
* @return the counter value
315
unsigned long long GetStat (E_CounterName P_counter);
317
/* Get the current start time. */
318
void getStartTime(struct timeval *t);
323
* This method converts a struct timeval parameter into a printable string
324
* in the format given in parameter.
327
* @return a pointer on a static string containing formated time
329
static char* formatTime (struct timeval* P_tv, bool microseconds = false);
332
* setRepartitionCallLength
333
* - set the unsigned int table passed in parameter as the repartition table
334
* for call length. This is done by calling the initRepartition methode on
335
* the M_CallLengthRepartition variable.
336
* - set the char* list of int (must be separeted with coma as the
337
* repartition table for call length
338
* This is done by calling the createIntegerTable to transform the char*
339
* list into unsigned int list. Then the initRepartition methode is
340
* call with the created unsigned int list and the M_CallLengthRepartition
343
* setRepartitionResponseTime
344
* Same than setRepartitionCallLength with the variable
345
* M_ResponseTimeRepartition variableinstead of M_CallLengthRepartition
348
void setRepartitionCallLength (unsigned int* repartition, int nombre);
349
void setRepartitionCallLength (char * liste);
350
void setRepartitionResponseTime (unsigned int* repartition, int nombre);
351
void setRepartitionResponseTime (char * liste);
353
/* define the file name to use to dump statistic in file */
354
void setFileName (char * name);
355
void setFileName (char * name, char * extension);
356
void initRtt (char * name, char * extension, unsigned long P_value);
359
* Display data periodically updated on screen.
361
void displayData (FILE *f);
362
void displayStat(FILE *f);
363
void displayRepartition(FILE *f);
364
void displayRtdRepartition (FILE *f, int which);
367
* Dump data periodically in the file M_FileName
374
* initialize the class variable member
379
* computeDiffTimeInMs.
381
* This method calculates elaped time in ms
383
* @param tf = final date
384
* @param ti = initial date
386
* @return number of ms between the 2 dates
388
static long computeDiffTimeInMs (struct timeval* tf, struct timeval* ti);
393
* This converts an unsigned long containing a number of ms
394
* into a string expressing the same value in format HH:MM:SS.
398
* @return a pointer on a static string containing formated time
400
static char* msToHHMMSS (unsigned long P_ms);
405
* This converts an unsigned long containing a number of ms
406
* into a string expressing the same value in format HH:MM:SS:mmm.
410
* @return a pointer on a static string containing formated time
412
static char* msToHHMMSSmmm (unsigned long P_ms);
414
/* Get a counter ID by name. */
415
int findCounter(const char *counter, bool alloc);
416
int findRtd(const char *name, bool start);
421
unsigned long long M_counters[E_NB_COUNTER];
422
static unsigned long long M_G_counters[E_NB_G_COUNTER - E_NB_COUNTER];
427
#define GENERIC_TYPES 3
428
unsigned long long *M_genericCounters;
430
str_int_map M_genericMap;
431
int_str_map M_revGenericMap;
432
int_str_map M_genericDisplay;
434
str_int_map rtd_started;
435
str_int_map rtd_stopped;
441
unsigned long long *M_rtdInfo;
442
str_int_map M_rtdMap;
443
int_str_map M_revRtdMap;
445
T_dynamicalRepartition** M_ResponseTimeRepartition;
446
T_dynamicalRepartition* M_CallLengthRepartition;
447
int M_SizeOfResponseTimeRepartition;
448
int M_SizeOfCallLengthRepartition;
449
struct timeval M_startTime;
450
struct timeval M_pdStartTime;
451
struct timeval M_plStartTime;
453
bool M_headerAlreadyDisplayed;
455
ofstream* M_outputStream;
457
bool M_headerAlreadyDisplayedRtt ;
458
char* M_fileNameRtt ;
459
ofstream* M_outputStreamRtt ;
462
T_pValue_rtt M_dumpRespTime ;
463
unsigned int M_counterDumpRespTime ;
464
unsigned long M_report_freq_dumpRtt ;
468
* This methode is used to create the repartition table with a table of
469
* unsigned int the reparition is created like following, with Vi the given
476
* So the repartition table have the size n+1 if the given table has a size
478
void initRepartition(unsigned int* repartition, int nombre,
479
T_dynamicalRepartition ** tabRepartition, int* nbTab);
483
* this method try to create a table of unsigned int with the list of char*
484
* passed in parameters
485
* if it succed, it's return true (1)
486
* else it's return false (0)
488
int createIntegerTable(char * P_listeStr,
489
unsigned int ** listeInteger,
494
* this method check if the char* passed in parameter in really a list of
495
* integer separated with comma.
496
* if yes, it's return true (1)
497
* else, it's return false (0)
499
int isWellFormed(char * P_listeStr, int * nombre);
503
* The method looks for the place to set the value passed in parameter
504
* Once found, the associated counter is incremented
506
void updateRepartition( T_dynamicalRepartition* tabRepart,
508
unsigned long value);
512
* Zeros out all repartition counters.
514
void resetRepartition(T_dynamicalRepartition* P_tabReport,
518
* Display the repartition passed in parameter at the screen
520
void displayRepartition(FILE *f,
521
T_dynamicalRepartition * tabRepartition,
526
* return a string with the range description of the given repartition
528
char* sRepartitionHeader(T_dynamicalRepartition * tabRepartition,
530
char* P_repartitionName);
534
* return a string with the number of value in the differente range of the
537
char* sRepartitionInfo(T_dynamicalRepartition * tabRepartition,
541
* UpdateAverageCounter
542
* This methode compute the real moyenne with the passed value on the given
545
void updateAverageCounter(E_CounterName P_SumCounter,
546
E_CounterName P_NbOfCallUsed,
547
E_CounterName P_Squares,
548
unsigned long P_value);
552
* This method computes the standard deviation using our recorded mean
553
* and recorded mean square.
555
double computeStdev(E_CounterName P_SumCounter,
556
E_CounterName P_NbOfCallUsed,
557
E_CounterName P_Squares);
561
* This method computes the recorded sum and count.
563
double computeMean(E_CounterName P_SumCounter,
564
E_CounterName P_NbOfCallUsed);
566
double computeRtdMean(int which, int type);
567
double computeRtdStdev(int which, int type);
572
* To prevent public copy ctor usage: no implementation
574
CStat (const CStat&);
579
* To prevent public operator= usage: no implementation
581
CStat& operator=(const CStat&);
585
* This abstract class provides the ability to sample from a distribution.
589
virtual double sample() = 0;
590
virtual int textDescr(char *s, int len) = 0;
591
virtual int timeDescr(char *s, int len) = 0;
592
virtual double cdfInv(double percentile) = 0;
597
/* Always return a fixed value for the sample. */
598
class CFixed : public CSample {
600
CFixed(double value);
602
int textDescr(char *s, int len);
603
int timeDescr(char *s, int len);
604
double cdfInv(double percentile);
609
/* Return the default scenario duration. */
610
class CDefaultPause : public CSample {
614
int textDescr(char *s, int len);
615
int timeDescr(char *s, int len);
616
double cdfInv(double percentile);
620
/* Uniform distribution. */
621
class CUniform : public CSample {
623
CUniform(double min, double max);
625
int textDescr(char *s, int len);
626
int timeDescr(char *s, int len);
627
double cdfInv(double percentile);
633
/* Normal distribution. */
634
class CNormal : public CSample {
636
CNormal(double mean, double stdev);
638
int textDescr(char *s, int len);
639
int timeDescr(char *s, int len);
640
double cdfInv(double percentile);
646
/* Lognormal distribution. */
647
class CLogNormal : public CNormal {
649
CLogNormal(double mean, double stdev) : CNormal(mean, stdev) {};
651
int textDescr(char *s, int len);
652
int timeDescr(char *s, int len);
653
double cdfInv(double percentile);
656
/* Exponential distribution. */
657
class CExponential : public CSample {
659
CExponential(double mean);
661
int textDescr(char *s, int len);
662
int timeDescr(char *s, int len);
663
double cdfInv(double percentile);
669
/* Weibull distribution. */
670
class CWeibull : public CSample {
672
CWeibull(double lambda, double k);
674
int textDescr(char *s, int len);
675
int timeDescr(char *s, int len);
676
double cdfInv(double percentile);
682
/* Pareto distribution. */
683
class CPareto : public CSample {
685
CPareto(double k, double xsubm);
687
int textDescr(char *s, int len);
688
int timeDescr(char *s, int len);
689
double cdfInv(double percentile);
695
/* Generalized Pareto distribution. */
696
class CGPareto : public CSample {
698
CGPareto(double shape, double scale, double location);
700
int textDescr(char *s, int len);
701
int timeDescr(char *s, int len);
702
double cdfInv(double percentile);
704
double shape, scale, location;
709
/* Gamma distribution. */
710
class CGamma : public CSample {
712
CGamma(double k, double theta);
714
int textDescr(char *s, int len);
715
int timeDescr(char *s, int len);
716
double cdfInv(double percentile);
722
/* Negative Binomial distribution. */
723
class CNegBin : public CSample {
725
CNegBin(double p, double n);
727
int textDescr(char *s, int len);
728
int timeDescr(char *s, int len);
729
double cdfInv(double percentile);