- applied patch from Dragos Vingarzan <vingarzan@fokus.fraunhofer.de> which
[sip-router] / modules / tm / t_stats.c
1 /*
2  *
3  * $Id$
4  *
5  *
6  * Copyright (C) 2001-2003 FhG Fokus
7  *
8  * This file is part of ser, a free SIP server.
9  *
10  * ser is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version
14  *
15  * For a license to use the ser software under conditions
16  * other than those described here, or to purchase support for this
17  * software, please contact iptel.org by e-mail at the following addresses:
18  *    info@iptel.org
19  *
20  * ser is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License 
26  * along with this program; if not, write to the Free Software 
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  */
29 /*
30  * History:
31  * --------
32  *  2003-06-27  tm_stats & friends freed on exit only if non-null (andrei)
33  */
34
35
36 #include "defs.h"
37
38
39 #include <stdio.h>
40 #include "t_stats.h"
41 #include "../../mem/shm_mem.h"
42 #include "../../dprint.h"
43 #include "../../config.h"
44 #include "../../pt.h"
45
46 struct t_stats *tm_stats=0;
47
48 int init_tm_stats(void)
49 {
50
51         tm_stats = shm_malloc(sizeof(struct t_stats));
52         if (tm_stats==0) {
53                 ERR("No mem for stats\n");
54                 return -1;
55         }
56         memset(tm_stats, 0, sizeof(struct t_stats) );
57
58              /* Delay initialization of tm_stats structures to
59               * init_tm_stats_child which gets called from child_init,
60               * in mod_init function other modules can increase the value of
61               * estimated_process_count and thus we do not know about processes created
62               * from modules which get loaded after tm and thus their mod_init
63               * functions will be called after tm mod_init function finishes
64               */
65         return 0;
66 }
67
68
69 int init_tm_stats_child(void)
70 {
71         int size;
72
73              /* We are called from child_init, estimated_process_count has definitive
74               * value now and thus we can safely allocate the variables
75               */
76         size = sizeof(stat_counter) * get_max_procs();
77         tm_stats->s_waiting = shm_malloc(size);
78         if (tm_stats->s_waiting == 0) {
79                 ERR("No mem for stats\n");
80                 goto error1;
81         }
82         memset(tm_stats->s_waiting, 0, size);
83
84         tm_stats->s_transactions = shm_malloc(size);
85         if (tm_stats->s_transactions == 0) {
86                 ERR("No mem for stats\n");
87                 goto error2;
88         }
89         memset(tm_stats->s_transactions, 0, size);
90
91         tm_stats->s_client_transactions = shm_malloc(size);
92         if (tm_stats->s_client_transactions == 0) {
93                 ERR("No mem for stats\n");
94                 goto error3;
95         }
96         memset(tm_stats->s_client_transactions, 0, size);
97         return 0;
98
99  error3:
100         shm_free(tm_stats->s_transactions);
101         tm_stats->s_transactions = 0;
102  error2:
103         shm_free(tm_stats->s_waiting);
104         tm_stats->s_waiting = 0;
105  error1:
106         shm_free(tm_stats);
107         return -1;
108 }
109
110
111 void free_tm_stats()
112 {
113         if (tm_stats == 0) return;
114         if (tm_stats->s_client_transactions) 
115                 shm_free(tm_stats->s_client_transactions);
116         if (tm_stats->s_transactions)
117                 shm_free(tm_stats->s_transactions);
118         if (tm_stats->s_waiting)
119                 shm_free(tm_stats->s_waiting);
120         shm_free(tm_stats);
121 }
122
123
124 const char* tm_rpc_stats_doc[2] = {
125         "Print transaction statistics.",
126         0
127 };
128
129 /* we don't worry about locking data during reads (unlike
130  * setting values which always happens from some locks) 
131  */
132 void tm_rpc_stats(rpc_t* rpc, void* c)
133 {
134         void* st;
135         unsigned long total, current, waiting, total_local;
136         int i, pno;
137
138         pno = get_max_procs();
139         for(i = 0, total = 0, waiting = 0, total_local = 0; i < pno; i++) {
140                 total += tm_stats->s_transactions[i];
141                 waiting += tm_stats->s_waiting[i];
142                 total_local += tm_stats->s_client_transactions[i];
143         }
144         current = total - tm_stats->deleted;
145         waiting -= tm_stats->deleted;
146
147         if (rpc->add(c, "{", &st) < 0) return;
148
149         rpc->struct_add(st, "dd", "current", current, "waiting", waiting);
150         rpc->struct_add(st, "dd", "waiting", waiting, "total", total);
151         rpc->struct_add(st, "d", "total_local", total_local);
152         rpc->struct_add(st, "d", "replied_localy", tm_stats->replied_localy);
153         rpc->struct_add(st, "ddddd", 
154                         "6xx", tm_stats->completed_6xx,
155                         "5xx", tm_stats->completed_5xx,
156                         "4xx", tm_stats->completed_4xx,
157                         "3xx", tm_stats->completed_3xx,
158                         "2xx", tm_stats->completed_2xx);
159         /* rpc->fault(c, 100, "Trying"); */
160 }