diff --git a/src/modules/tm/t_stats.c b/src/modules/tm/t_stats.c index 856f6230d80..7643ac624cc 100644 --- a/src/modules/tm/t_stats.c +++ b/src/modules/tm/t_stats.c @@ -14,8 +14,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -29,21 +29,19 @@ #include "../../core/dprint.h" #include "../../core/config.h" #include "../../core/pt.h" -#ifdef TM_HASH_STATS #include "h_table.h" -#endif union t_stats *tm_stats=0; int init_tm_stats(void) { - /* Delay initialization of tm_stats to - * init_tm_stats_child which gets called from child_init, - * in mod_init function other modules can increase the value of - * estimated_process_count and thus we do not know about processes created - * from modules which get loaded after tm and thus their mod_init - * functions will be called after tm mod_init function finishes - */ + /* Delay initialization of tm_stats to + * init_tm_stats_child which gets called from child_init, + * in mod_init function other modules can increase the value of + * estimated_process_count and thus we do not know about processes created + * from modules which get loaded after tm and thus their mod_init + * functions will be called after tm mod_init function finishes + */ return 0; } @@ -64,7 +62,7 @@ int init_tm_stats_child(void) } memset(tm_stats, 0, size); } - + return 0; error: return -1; @@ -115,7 +113,7 @@ void free_tm_stats() /* we don't worry about locking data during reads (unlike - * setting values which always happens from some locks) + * setting values which always happens from some locks) */ void tm_rpc_stats(rpc_t* rpc, void* c) { @@ -135,19 +133,19 @@ void tm_rpc_stats(rpc_t* rpc, void* c) if (rpc->add(c, "{", &st) < 0) return; rpc->struct_add(st, "dd", "current", (unsigned) current, "waiting", - (unsigned) waiting); + (unsigned) waiting); rpc->struct_add(st, "d", "total", (unsigned) all.transactions); rpc->struct_add(st, "d", "total_local", (unsigned)all.client_transactions); rpc->struct_add(st, "d", "rpl_received", (unsigned)all.rpl_received); rpc->struct_add(st, "d", "rpl_generated", (unsigned)all.rpl_generated); rpc->struct_add(st, "d", "rpl_sent", (unsigned)all.rpl_sent); - rpc->struct_add(st, "ddddd", + rpc->struct_add(st, "ddddd", "6xx", (unsigned int)all.completed_6xx, "5xx", (unsigned int)all.completed_5xx, "4xx", (unsigned int)all.completed_4xx, "3xx", (unsigned int)all.completed_3xx, "2xx", (unsigned int)all.completed_2xx); -#ifdef TM_MORE_STATS +#ifdef TM_MORE_STATS rpc->struct_add(st, "dd", "created", (unsigned int)all.t_created, "freed", (unsigned int)all.t_freed); rpc->struct_add(st, "d", "delayed_free", (unsigned int)all.delayed_free); @@ -182,7 +180,7 @@ void tm_rpc_hash_stats(rpc_t* rpc, void* c) double crt_average, crt_dev, crt_d; unsigned long acc, crt; int r; - + acc_count=0; acc_min=(unsigned long)(-1); acc_max=0; @@ -198,12 +196,12 @@ void tm_rpc_hash_stats(rpc_t* rpc, void* c) for (r=0; rentries[r].acc_entries; crt=_tm_table->entries[r].cur_entries; - + acc_count+=acc; if (accacc_max) acc_max=acc; if (acc==0) acc_zeroes++; - + crt_count+=crt; if (crtcrt_max) crt_max=crt; @@ -211,11 +209,11 @@ void tm_rpc_hash_stats(rpc_t* rpc, void* c) } acc_average=acc_count/(double)TABLE_ENTRIES; crt_average=crt_count/(double)TABLE_ENTRIES; - + for (r=0; rentries[r].acc_entries; crt=_tm_table->entries[r].cur_entries; - + acc_d=acc-acc_average; /* instead of fabs() which requires -lm */ if (acc_d<0) acc_d=-acc_d; @@ -227,14 +225,14 @@ void tm_rpc_hash_stats(rpc_t* rpc, void* c) if (crt_d>1) crt_dev_no++; crt_dev+=crt_d*crt_d; } - + if (rpc->add(c, "{", &st) < 0) return; rpc->struct_add(st, "d", "hash_size", (unsigned) TABLE_ENTRIES); rpc->struct_add(st, "d", "crt_transactions", (unsigned)crt_count); rpc->struct_add(st, "f", "crt_target_per_cell", crt_average); rpc->struct_add(st, "dd", "crt_min", (unsigned)crt_min, - "crt_max", (unsigned) crt_max); - rpc->struct_add(st, "d", "crt_worst_case_extra_cells", + "crt_max", (unsigned) crt_max); + rpc->struct_add(st, "d", "crt_worst_case_extra_cells", (unsigned)(crt_max-(unsigned)crt_average)); rpc->struct_add(st, "d", "crt_no_zero_cells", (unsigned)crt_zeroes); rpc->struct_add(st, "d", "crt_no_deviating_cells", crt_dev_no); @@ -242,8 +240,8 @@ void tm_rpc_hash_stats(rpc_t* rpc, void* c) rpc->struct_add(st, "d", "acc_transactions", (unsigned)acc_count); rpc->struct_add(st, "f", "acc_target_per_cell", acc_average); rpc->struct_add(st, "dd", "acc_min", (unsigned)acc_min, - "acc_max", (unsigned) acc_max); - rpc->struct_add(st, "d", "acc_worst_case_extra_cells", + "acc_max", (unsigned) acc_max); + rpc->struct_add(st, "d", "acc_worst_case_extra_cells", (unsigned)(acc_max-(unsigned)acc_average)); rpc->struct_add(st, "d", "acc_no_zero_cells", (unsigned)acc_zeroes); rpc->struct_add(st, "d", "acc_no_deviating_cells", acc_dev_no); @@ -253,3 +251,36 @@ void tm_rpc_hash_stats(rpc_t* rpc, void* c) "recompiling with -DTM_HASH_STATS)"); #endif /* TM_HASH_STATS */ } + +/* hash statistics */ +void tm_rpc_list(rpc_t* rpc, void* c) +{ + int r; + void* h; + tm_cell_t *tcell; + + for (r=0; rentries[r].next_c!=NULL) { + if (rpc->add(c, "{", &h) < 0) { + LM_ERR("failed to add transaction structure\n"); + return; + } + lock_hash(r); + clist_foreach(&_tm_table->entries[r], tcell, next_c) + { + rpc->struct_add(h, "ddSSSSSdd", + "tindex", (unsigned)tcell->hash_index, + "tlabel", (unsigned)tcell->label, + "method", &tcell->method, + "from", &tcell->from, + "to", &tcell->to, + "callid", &tcell->callid, + "cseq", &tcell->cseq_n, + "tflags", (unsigned)tcell->flags, + "outgoings", (unsigned)tcell->nr_of_outgoings + ); + } + unlock_hash(r); + } + } +} diff --git a/src/modules/tm/t_stats.h b/src/modules/tm/t_stats.h index b95d4781f41..0a0057c6203 100644 --- a/src/modules/tm/t_stats.h +++ b/src/modules/tm/t_stats.h @@ -13,8 +13,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -41,7 +41,7 @@ struct t_proc_stats { /* number of UAC transactions (part of transactions) */ stat_counter client_transactions; /* number of transactions which completed with this status */ - stat_counter completed_3xx, completed_4xx, completed_5xx, + stat_counter completed_3xx, completed_4xx, completed_5xx, completed_6xx, completed_2xx; stat_counter rpl_received; stat_counter rpl_generated; @@ -59,12 +59,12 @@ struct t_proc_stats { union t_stats{ struct t_proc_stats s; - char _pad[256]; /* pad at least to cache line size - athlon=64, p4=128, some sparcs=256 */ + char _pad[256]; /* pad at least to cache line size + * athlon=64, p4=128, some sparcs=256 */ }; extern union t_stats *tm_stats; -#ifdef TM_MORE_STATS +#ifdef TM_MORE_STATS inline void static t_stats_created(void) { /* keep it in process's piece of shmem */ @@ -149,5 +149,6 @@ void tm_rpc_hash_stats(rpc_t* rpc, void* c); typedef int (*tm_get_stats_f)(struct t_proc_stats *all); int tm_get_stats(struct t_proc_stats *all); +void tm_rpc_list(rpc_t* rpc, void* c); #endif diff --git a/src/modules/tm/tm.c b/src/modules/tm/tm.c index 68071c3fe42..7adaa8796d0 100644 --- a/src/modules/tm/tm.c +++ b/src/modules/tm/tm.c @@ -2516,6 +2516,11 @@ static const char* rpc_t_uac_wait_doc[2] = { 0 }; +static const char* tm_rpc_list_doc[2] = { + "List transactions.", + 0 +}; + /* rpc exports */ static rpc_export_t tm_rpc[] = { @@ -2526,6 +2531,7 @@ static rpc_export_t tm_rpc[] = { {"tm.hash_stats", tm_rpc_hash_stats, tm_rpc_hash_stats_doc, 0}, {"tm.t_uac_start", rpc_t_uac_start, rpc_t_uac_start_doc, 0 }, {"tm.t_uac_wait", rpc_t_uac_wait, rpc_t_uac_wait_doc, RET_ARRAY}, + {"tm.list", tm_rpc_list, tm_rpc_list_doc, RET_ARRAY}, {0, 0, 0, 0} };