00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #if !defined (_StatSystem_h_)
00030 #define _StatSystem_h_
00031
00032 #include "ink_platform.h"
00033 #include "ink_hrtime.h"
00034 #include "ink_atomic.h"
00035 #ifdef USE_LOCKS_FOR_DYN_STATS
00036 #include "Lock.h"
00037 #endif
00038
00039 #include "ink_apidefs.h"
00040
00041 #define STATS_MAJOR_VERSION 6 // increment when changing the stats!
00042 #define DEFAULT_SNAP_FILENAME "stats.snap"
00043
00044
00045
00046
00047
00048
00049 class TransactionMilestones
00050 {
00051 public:
00052 TransactionMilestones()
00053 : ua_begin(0), ua_read_header_done(0), ua_begin_write(0), ua_close(0), server_first_connect(0), server_connect(0),
00054 server_connect_end(0), server_begin_write(0), server_first_read(0), server_read_header_done(0), server_close(0),
00055 cache_open_read_begin(0), cache_open_read_end(0), cache_open_write_begin(0), cache_open_write_end(0),
00056 dns_lookup_begin(0), dns_lookup_end(0), sm_start(0), sm_finish(0)
00057 { }
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 ink_hrtime ua_begin;
00069 ink_hrtime ua_read_header_done;
00070 ink_hrtime ua_begin_write;
00071 ink_hrtime ua_close;
00072
00073
00074
00075
00076 ink_hrtime server_first_connect;
00077 ink_hrtime server_connect;
00078 ink_hrtime server_connect_end;
00079 ink_hrtime server_begin_write;
00080 ink_hrtime server_first_read;
00081 ink_hrtime server_read_header_done;
00082 ink_hrtime server_close;
00083
00084 ink_hrtime cache_open_read_begin;
00085 ink_hrtime cache_open_read_end;
00086 ink_hrtime cache_open_write_begin;
00087 ink_hrtime cache_open_write_end;
00088
00089 ink_hrtime dns_lookup_begin;
00090 ink_hrtime dns_lookup_end;
00091
00092
00093
00094
00095 ink_hrtime sm_start;
00096 ink_hrtime sm_finish;
00097
00098
00099
00100
00101
00102
00103 };
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 #define _HEADER \
00124 typedef enum { \
00125 NO_HTTP_TRANS_STATS = 0,
00126
00127 #define _FOOTER \
00128 MAX_HTTP_TRANS_STATS \
00129 } HttpTransactionStat_t;
00130
00131 #if defined(freebsd)
00132 #undef _D
00133 #endif
00134 #define _D(_x) _x,
00135
00136 #include "HttpTransStats.h"
00137 #undef _HEADER
00138 #undef _FOOTER
00139 #undef _D
00140
00141 struct HttpTransactionStatsString_t
00142 {
00143 HttpTransactionStat_t i;
00144 char *name;
00145 };
00146
00147
00148
00149
00150
00151 #define DYN_STAT_START 2048
00152 #define DYN_STAT_MASK (~(2047UL))
00153
00154
00155
00156 #define _HEADER \
00157 typedef enum { \
00158 NO_DYN_STATS = DYN_STAT_START,
00159
00160 #define _FOOTER \
00161 MAX_DYN_STATS \
00162 } DynamicStat_t;
00163
00164 #define _D(_x) _x,
00165
00166 #include "DynamicStats.h"
00167
00168 #undef _HEADER
00169 #undef _FOOTER
00170 #undef _D
00171
00172 struct DynamicStatsString_t
00173 {
00174 DynamicStat_t i;
00175 const char *name;
00176 };
00177
00178 extern HttpTransactionStatsString_t HttpTransactionStatsStrings[];
00179 extern DynamicStatsString_t DynamicStatsStrings[];
00180
00181
00182
00183
00184
00185
00186 #define ink_stat_lock_t ink_mutex
00187
00188 typedef int64_t ink_statval_t;
00189
00190 struct ink_local_stat_t
00191 {
00192 ink_statval_t count;
00193 ink_statval_t value;
00194 };
00195
00196 struct ink_prot_global_stat_t
00197 {
00198 ink_stat_lock_t access_lock;
00199 ink_statval_t count;
00200 ink_statval_t sum;
00201
00202 ink_prot_global_stat_t()
00203 : count(0), sum(0)
00204 {
00205 ink_mutex_init(&access_lock, "Stats Access Lock");
00206 }
00207 };
00208
00209 struct ink_unprot_global_stat_t
00210 {
00211 ink_statval_t count;
00212 ink_statval_t sum;
00213 ink_unprot_global_stat_t():count(0), sum(0)
00214 {
00215 }
00216 };
00217
00218
00219
00220
00221
00222
00223
00224 #define CLEAR_DYN_STAT(X) \
00225 { \
00226 ink_assert (X & DYN_STAT_MASK); \
00227 CLEAR_GLOBAL_DYN_STAT(X-DYN_STAT_START); \
00228 }
00229
00230 #define DECREMENT_DYN_STAT(X) SUM_DYN_STAT(X, (ink_statval_t)-1)
00231
00232 #define COUNT_DYN_STAT(X,C) \
00233 { \
00234 ink_assert (X & DYN_STAT_MASK); \
00235 ADD_TO_GLOBAL_DYN_COUNT((X-DYN_STAT_START), C); \
00236 }
00237
00238 #define FSUM_DYN_STAT(X, S) \
00239 { \
00240 ink_assert (X & DYN_STAT_MASK); \
00241 ADD_TO_GLOBAL_DYN_FSUM((X-DYN_STAT_START), S); \
00242 }
00243
00244
00245 #define INCREMENT_DYN_STAT(X) SUM_DYN_STAT(X, (ink_statval_t)1)
00246
00247
00248
00249
00250
00251 #define READ_DYN_STAT(X,C,S) \
00252 { \
00253 ink_assert (X & DYN_STAT_MASK); \
00254 READ_GLOBAL_DYN_STAT((X-DYN_STAT_START),C,S); \
00255 }
00256
00257 #define READ_DYN_COUNT(X,C) \
00258 { \
00259 ink_assert (X & DYN_STAT_MASK); \
00260 READ_GLOBAL_DYN_COUNT((X-DYN_STAT_START),C); \
00261 }
00262
00263 #define READ_DYN_SUM(X,S) \
00264 { \
00265 ink_assert (X & DYN_STAT_MASK); \
00266 READ_GLOBAL_DYN_SUM((X-DYN_STAT_START),S); \
00267 }
00268
00269
00270 #define SET_DYN_COUNT(X, V) \
00271 { \
00272 ink_assert (X & DYN_STAT_MASK); \
00273 SET_GLOBAL_DYN_COUNT((X-DYN_STAT_START), V); \
00274 }
00275
00276
00277 #define SET_DYN_STAT(X, C, S) \
00278 { \
00279 ink_assert (X & DYN_STAT_MASK); \
00280 SET_GLOBAL_DYN_STAT((X-DYN_STAT_START), C, S); \
00281 }
00282
00283
00284 #define SUM_DYN_STAT(X,S) \
00285 { \
00286 ink_assert (X & DYN_STAT_MASK); \
00287 ADD_TO_GLOBAL_DYN_SUM((X-DYN_STAT_START), S); \
00288 }
00289
00290
00291 #define SUM_GLOBAL_DYN_STAT(X,S) \
00292 { \
00293 ink_assert (X & DYN_STAT_MASK); \
00294 ADD_TO_GLOBAL_GLOBAL_DYN_SUM((X-DYN_STAT_START), S); \
00295 }
00296
00297 #define __CLEAR_TRANS_STAT(local_stat_struct_, X) \
00298 { \
00299 ink_assert (!(X & DYN_STAT_MASK)); \
00300 local_stat_struct_[X].count = (ink_statval_t)0; \
00301 local_stat_struct_[X].value = (ink_statval_t)0; \
00302 }
00303
00304 #define __DECREMENT_TRANS_STAT(local_stat_struct_, X) __SUM_TRANS_STAT(local_stat_struct_, X, (ink_statval_t)-1)
00305
00306 #define __FSUM_TRANS_STAT(local_stat_struct_, X, S) \
00307 { \
00308 ink_assert (!(X & DYN_STAT_MASK)); \
00309 local_stat_struct_[X].count++; \
00310 (*(double *)&local_stat_struct_[X].value) += S; \
00311 }
00312
00313
00314 #define __INCREMENT_TRANS_STAT(local_stat_struct_, X) __SUM_TRANS_STAT(local_stat_struct_, X, (ink_statval_t)1);
00315
00316 #define __INITIALIZE_LOCAL_STAT_STRUCT(local_stat_struct_, X) __CLEAR_TRANS_STAT(local_stat_struct_, X)
00317
00318 #define INITIALIZE_GLOBAL_TRANS_STATS(X) \
00319 { \
00320 X.count = (ink_statval_t)0; \
00321 X.sum = (ink_statval_t)0; \
00322 }
00323
00324
00325
00326
00327
00328 #define READ_HTTP_TRANS_STAT(X,C,S) \
00329 { \
00330 ink_assert (!(X & DYN_STAT_MASK)); \
00331 READ_GLOBAL_HTTP_TRANS_STAT(X,C,S); \
00332 }
00333
00334
00335 #define __SET_TRANS_COUNT(local_stat_struct_, X, V) \
00336 { \
00337 ink_assert (!(X & DYN_STAT_MASK)); \
00338 local_stat_struct_[X].value = (ink_statval_t)V; \
00339 }
00340
00341
00342 #define __SET_TRANS_STAT(local_stat_struct_, X, C, S) \
00343 { \
00344 ink_assert (!(X & DYN_STAT_MASK)); \
00345 local_stat_struct_[X].value = (ink_statval_t)S; \
00346 }
00347
00348
00349
00350
00351 #define __SUM_TRANS_STAT(local_stat_struct_, X,S) \
00352 { \
00353 ink_assert (!(X & DYN_STAT_MASK)); \
00354 local_stat_struct_[X].count += 1; \
00355 local_stat_struct_[X].value += S; \
00356 }
00357
00358 #define UPDATE_HTTP_TRANS_STATS(local_stat_struct_) \
00359 { \
00360 int i; \
00361 STAT_LOCK_ACQUIRE(&(global_http_trans_stat_lock)); \
00362 for (i=NO_HTTP_TRANS_STATS; i<MAX_HTTP_TRANS_STATS; i++) { \
00363 global_http_trans_stats[i].count += local_stat_struct_[i].count; \
00364 global_http_trans_stats[i].sum += local_stat_struct_[i].value; \
00365 } \
00366 STAT_LOCK_RELEASE(&(global_http_trans_stat_lock)); \
00367 }
00368
00369 #define STAT_LOCK_ACQUIRE(X) (ink_mutex_acquire(X))
00370 #define STAT_LOCK_RELEASE(X) (ink_mutex_release(X))
00371 #define STAT_LOCK_INIT(X,S) (ink_mutex_init(X,S))
00372
00373
00374
00375
00376
00377 #ifndef USE_LOCKS_FOR_DYN_STATS
00378
00379 #ifdef USE_THREAD_LOCAL_DYN_STATS
00380
00381 #error "Should not build with USE_THREAD_LOCAL_DYN_STATS"
00382
00383
00384 #define ADD_TO_GLOBAL_DYN_COUNT(X,C) \
00385 mutex->thread_holding->global_dyn_stats[X].count += (C)
00386
00387 #define ADD_TO_GLOBAL_DYN_SUM(X,S) \
00388 mutex->thread_holding->global_dyn_stats[X].count ++; \
00389 mutex->thread_holding->global_dyn_stats[X].sum += (S)
00390
00391 #define ADD_TO_GLOBAL_GLOBAL_DYN_SUM(X,S) \
00392 ink_atomic_increment(&global_dyn_stats[X].count,(ink_statval_t)1); \
00393 ink_atomic_increment(&global_dyn_stats[X].sum,S)
00394
00395
00396
00397
00398
00399 #define ADD_TO_GLOBAL_DYN_FSUM(X,S) \
00400 mutex->thread_holding->global_dyn_stats[X].count++; \
00401 mutex->thread_holding->global_dyn_stats[X].sum += (S)
00402
00403 #define CLEAR_GLOBAL_DYN_STAT(X) \
00404 global_dyn_stats[X].count = 0; \
00405 global_dyn_stats[X].sum = 0
00406
00407 #define READ_GLOBAL_DYN_STAT(X,C,S) do { \
00408 ink_unprot_global_stat_t _s = global_dyn_stats[X]; \
00409 for (int _e = 0; _e < eventProcessor.n_ethreads ; _e++) { \
00410 _s.count += eventProcessor.all_ethreads[_e]->global_dyn_stats[X].count; \
00411 _s.sum += eventProcessor.all_ethreads[_e]->global_dyn_stats[X].sum; \
00412 } \
00413 for (int _e = 0; _e < eventProcessor.n_dthreads ; _e++) { \
00414 _s.count += eventProcessor.all_dthreads[_e]->global_dyn_stats[X].count; \
00415 _s.sum += eventProcessor.all_dthreads[_e]->global_dyn_stats[X].sum; \
00416 } \
00417 C = _s.count; \
00418 S = _s.sum; \
00419 } while (0)
00420
00421 #define READ_GLOBAL_DYN_COUNT(X,C) do { \
00422 ink_statval_t _s = global_dyn_stats[X].count; \
00423 for (int _e = 0; _e < eventProcessor.n_ethreads ; _e++) \
00424 _s += eventProcessor.all_ethreads[_e]->global_dyn_stats[X].count; \
00425 for (int _e = 0; _e < eventProcessor.n_dthreads ; _e++) \
00426 _s += eventProcessor.all_dthreads[_e]->global_dyn_stats[X].count; \
00427 C = _s; \
00428 } while (0)
00429
00430 #define READ_GLOBAL_DYN_SUM(X,S) do { \
00431 ink_statval_t _s = global_dyn_stats[X].sum; \
00432 for (int _e = 0; _e < eventProcessor.n_ethreads ; _e++) \
00433 _s += eventProcessor.all_ethreads[_e]->global_dyn_stats[X].sum; \
00434 for (int _e = 0; _e < eventProcessor.n_dthreads ; _e++) \
00435 _s += eventProcessor.all_dthreads[_e]->global_dyn_stats[X].sum; \
00436 S = _s; \
00437 } while (0)
00438
00439 #define READ_GLOBAL_HTTP_TRANS_STAT(X,C,S) \
00440 { \
00441 C = global_http_trans_stats[X].count; \
00442 S = global_http_trans_stats[X].sum; \
00443 }
00444
00445 #define SET_GLOBAL_DYN_COUNT(X,V) \
00446 global_dyn_stats[X].count = V
00447
00448 #define SET_GLOBAL_DYN_STAT(X,C,S) \
00449 global_dyn_stats[X].count = C; \
00450 global_dyn_stats[X].sum = S
00451
00452 #define INITIALIZE_GLOBAL_DYN_STATS(X, T) \
00453 { \
00454 X.count = (ink_statval_t)0; \
00455 X.sum = (ink_statval_t)0; \
00456 }
00457
00458 #else
00459
00460 #define ADD_TO_GLOBAL_DYN_COUNT(X,C) \
00461 ink_atomic_increment(&global_dyn_stats[X].count,C)
00462
00463 #define ADD_TO_GLOBAL_DYN_SUM(X,S) \
00464 ink_atomic_increment(&global_dyn_stats[X].count,(ink_statval_t)1); \
00465 ink_atomic_increment(&global_dyn_stats[X].sum,S)
00466
00467 #define ADD_TO_GLOBAL_GLOBAL_DYN_SUM(X,S) \
00468 ink_atomic_increment(&global_dyn_stats[X].count,(ink_statval_t)1); \
00469 ink_atomic_increment(&global_dyn_stats[X].sum,S)
00470
00471 #define ADD_TO_GLOBAL_DYN_FSUM(X,S) \
00472 ink_atomic_increment(&global_dyn_stats[X].count,(ink_statval_t)1); \
00473 (*(double *)&global_dyn_stats[X].sum) += S
00474
00475 #define CLEAR_GLOBAL_DYN_STAT(X) \
00476 global_dyn_stats[X].count = 0; \
00477 global_dyn_stats[X].sum = 0
00478
00479 #define READ_GLOBAL_DYN_STAT(X,C,S) \
00480 C = global_dyn_stats[X].count; \
00481 S = global_dyn_stats[X].sum
00482
00483 #define READ_GLOBAL_DYN_COUNT(X,C) \
00484 C = global_dyn_stats[X].count;
00485
00486 #define READ_GLOBAL_DYN_SUM(X,S) \
00487 S = global_dyn_stats[X].sum;
00488
00489 #define READ_GLOBAL_HTTP_TRANS_STAT(X,C,S) \
00490 { \
00491 C = global_http_trans_stats[X].count; \
00492 S = global_http_trans_stats[X].sum; \
00493 }
00494
00495 #define SET_GLOBAL_DYN_COUNT(X,V) \
00496 global_dyn_stats[X].count = V
00497
00498 #define SET_GLOBAL_DYN_STAT(X,C,S) \
00499 global_dyn_stats[X].count = C; \
00500 global_dyn_stats[X].sum = S
00501
00502 #define INITIALIZE_GLOBAL_DYN_STATS(X, T) \
00503 { \
00504 X.count = (ink_statval_t)0; \
00505 X.sum = (ink_statval_t)0; \
00506 }
00507
00508 #endif
00509
00510 #else
00511
00512 #define ADD_TO_GLOBAL_DYN_COUNT(X,C) \
00513 { \
00514 STAT_LOCK_ACQUIRE(&(global_dyn_stats[X].access_lock)); \
00515 global_dyn_stats[X].count += C; \
00516 STAT_LOCK_RELEASE(&(global_dyn_stats[X].access_lock)); \
00517 }
00518 #define ADD_TO_GLOBAL_DYN_SUM(X,S) \
00519 { \
00520 STAT_LOCK_ACQUIRE(&(global_dyn_stats[X].access_lock)); \
00521 global_dyn_stats[X].count += 1; \
00522 global_dyn_stats[X].sum += S; \
00523 STAT_LOCK_RELEASE(&(global_dyn_stats[X].access_lock)); \
00524 }
00525 #define ADD_TO_GLOBAL_GLOBAL_DYN_SUM(X,S) \
00526 { \
00527 STAT_LOCK_ACQUIRE(&(global_dyn_stats[X].access_lock)); \
00528 global_dyn_stats[X].count += 1; \
00529 global_dyn_stats[X].sum += S; \
00530 STAT_LOCK_RELEASE(&(global_dyn_stats[X].access_lock)); \
00531 }
00532 #define ADD_TO_GLOBAL_DYN_FSUM(X,S) \
00533 { \
00534 STAT_LOCK_ACQUIRE(&(global_dyn_stats[X].access_lock)); \
00535 global_dyn_stats[X].count += (ink_statval_t)1; \
00536 (*(double *)&global_dyn_stats[X].sum) += S; \
00537 STAT_LOCK_RELEASE(&(global_dyn_stats[X].access_lock)); \
00538 }
00539 #define CLEAR_GLOBAL_DYN_STAT(X) \
00540 { \
00541 STAT_LOCK_ACQUIRE(&(global_dyn_stats[X].access_lock)); \
00542 global_dyn_stats[X].count = (ink_statval_t)0; \
00543 global_dyn_stats[X].sum = (ink_statval_t)0; \
00544 STAT_LOCK_RELEASE(&(global_dyn_stats[X].access_lock)); \
00545 }
00546 #define READ_GLOBAL_DYN_STAT(X,C,S) \
00547 { \
00548 STAT_LOCK_ACQUIRE(&(global_dyn_stats[X].access_lock)); \
00549 C = global_dyn_stats[X].count; \
00550 S = global_dyn_stats[X].sum; \
00551 STAT_LOCK_RELEASE(&(global_dyn_stats[X].access_lock)); \
00552 }
00553 #define READ_GLOBAL_HTTP_TRANS_STAT(X,C,S) \
00554 { \
00555 C = global_http_trans_stats[X].count; \
00556 S = global_http_trans_stats[X].sum; \
00557 }
00558 #define SET_GLOBAL_DYN_COUNT(X,V) \
00559 { \
00560 STAT_LOCK_ACQUIRE(&(global_dyn_stats[X].access_lock)); \
00561 global_dyn_stats[X].count = V; \
00562 STAT_LOCK_RELEASE(&(global_dyn_stats[X].access_lock)); \
00563 }
00564
00565 #define SET_GLOBAL_DYN_STAT(X,C,S) \
00566 { \
00567 STAT_LOCK_ACQUIRE(&(global_dyn_stats[X].access_lock)); \
00568 global_dyn_stats[X].count = C; \
00569 global_dyn_stats[X].sum = S; \
00570 STAT_LOCK_RELEASE(&(global_dyn_stats[X].access_lock)); \
00571 }
00572
00573 #define INITIALIZE_GLOBAL_DYN_STATS(X, T) \
00574 { \
00575 STAT_LOCK_INIT(&(X.access_lock), T); \
00576 X.count = (ink_statval_t)0; \
00577 X.sum = (ink_statval_t)0; \
00578 }
00579
00580 #endif
00581
00582
00583
00584
00585 extern void start_stats_snap(void);
00586 void initialize_all_global_stats();
00587
00588
00589
00590
00591
00592 void *http_trans_stats_count_cb(void *data, void *res);
00593 void *http_trans_stats_sum_cb(void *data, void *res);
00594 void *http_trans_stats_avg_cb(void *data, void *res);
00595 void *http_trans_stats_fsum_cb(void *data, void *res);
00596 void *http_trans_stats_favg_cb(void *data, void *res);
00597 void *http_trans_stats_time_seconds_cb(void *data, void *res);
00598 void *http_trans_stats_time_mseconds_cb(void *data, void *res);
00599 void *http_trans_stats_time_useconds_cb(void *data, void *res);
00600
00601 void *dyn_stats_count_cb(void *data, void *res);
00602 inkcoreapi void *dyn_stats_sum_cb(void *data, void *res);
00603 void *dyn_stats_avg_cb(void *data, void *res);
00604 void *dyn_stats_fsum_cb(void *data, void *res);
00605 void *dyn_stats_favg_cb(void *data, void *res);
00606 void *dyn_stats_time_seconds_cb(void *data, void *res);
00607 void *dyn_stats_time_mseconds_cb(void *data, void *res);
00608 void *dyn_stats_time_useconds_cb(void *data, void *res);
00609 void *dyn_stats_int_msecs_to_float_seconds_cb(void *data, void *res);
00610
00611
00612
00613 extern ink_stat_lock_t global_http_trans_stat_lock;
00614 extern ink_unprot_global_stat_t global_http_trans_stats[MAX_HTTP_TRANS_STATS];
00615 #ifndef USE_LOCKS_FOR_DYN_STATS
00616 extern inkcoreapi ink_unprot_global_stat_t global_dyn_stats[MAX_DYN_STATS - DYN_STAT_START];
00617 #else
00618 extern inkcoreapi ink_prot_global_stat_t global_dyn_stats[MAX_DYN_STATS - DYN_STAT_START];
00619 #endif
00620
00621 #ifdef DEBUG
00622 extern ink_mutex http_time_lock;
00623 extern time_t last_http_local_time;
00624 #endif
00625
00626 #define MAX_HTTP_HANDLER_EVENTS 25
00627 extern void clear_http_handler_times();
00628 extern void print_http_handler_time(int event);
00629 extern void print_all_http_handler_times();
00630 #ifdef DEBUG
00631 extern ink_hrtime http_handler_times[MAX_HTTP_HANDLER_EVENTS];
00632 extern int http_handler_counts[MAX_HTTP_HANDLER_EVENTS];
00633 #endif
00634
00635
00636 #endif