]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * ircd-ratbox: A slightly useful ircd. | |
3 | * s_stats.c: Statistics related functions | |
4 | * | |
5 | * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center | |
6 | * Copyright (C) 1996-2002 Hybrid Development Team | |
7 | * Copyright (C) 2002-2005 ircd-ratbox development team | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or modify | |
10 | * it under the terms of the GNU General Public License as published by | |
11 | * the Free Software Foundation; either version 2 of the License, or | |
12 | * (at your option) any later version. | |
13 | * | |
14 | * This program is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | * GNU General Public License for more details. | |
18 | * | |
19 | * You should have received a copy of the GNU General Public License | |
20 | * along with this program; if not, write to the Free Software | |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | |
22 | * USA | |
23 | * | |
24 | * $Id: s_stats.c 3249 2007-03-05 18:51:17Z nenolod $ | |
25 | */ | |
26 | ||
27 | #include "stdinc.h" | |
28 | #include "s_stats.h" | |
29 | #include "client.h" | |
30 | #include "irc_string.h" | |
31 | #include "ircd.h" | |
32 | #include "numeric.h" | |
33 | #include "send.h" | |
34 | #include "s_conf.h" | |
35 | #include "s_newconf.h" | |
36 | #include "whowas.h" | |
37 | #include "hash.h" | |
38 | #include "scache.h" | |
39 | #include "reject.h" | |
40 | ||
41 | /* | |
42 | * stats stuff | |
43 | */ | |
44 | static struct ServerStatistics ircst; | |
45 | struct ServerStatistics *ServerStats = &ircst; | |
46 | ||
47 | void | |
48 | init_stats() | |
49 | { | |
50 | memset(&ircst, 0, sizeof(ircst)); | |
51 | } | |
52 | ||
53 | /* | |
54 | * tstats | |
55 | * | |
56 | * inputs - client to report to | |
57 | * output - NONE | |
58 | * side effects - | |
59 | */ | |
60 | void | |
61 | tstats(struct Client *source_p) | |
62 | { | |
63 | struct Client *target_p; | |
64 | struct ServerStatistics *sp; | |
65 | struct ServerStatistics tmp; | |
66 | rb_dlink_node *ptr; | |
67 | ||
68 | sp = &tmp; | |
69 | memcpy(sp, ServerStats, sizeof(struct ServerStatistics)); | |
70 | ||
71 | RB_DLINK_FOREACH(ptr, serv_list.head) | |
72 | { | |
73 | target_p = ptr->data; | |
74 | ||
75 | sp->is_sbs += target_p->localClient->sendB; | |
76 | sp->is_sbr += target_p->localClient->receiveB; | |
77 | sp->is_sks += target_p->localClient->sendK; | |
78 | sp->is_skr += target_p->localClient->receiveK; | |
79 | sp->is_sti += rb_current_time() - target_p->localClient->firsttime; | |
80 | sp->is_sv++; | |
81 | if(sp->is_sbs > 1023) | |
82 | { | |
83 | sp->is_sks += (sp->is_sbs >> 10); | |
84 | sp->is_sbs &= 0x3ff; | |
85 | } | |
86 | if(sp->is_sbr > 1023) | |
87 | { | |
88 | sp->is_skr += (sp->is_sbr >> 10); | |
89 | sp->is_sbr &= 0x3ff; | |
90 | } | |
91 | } | |
92 | ||
93 | RB_DLINK_FOREACH(ptr, lclient_list.head) | |
94 | { | |
95 | target_p = ptr->data; | |
96 | ||
97 | sp->is_cbs += target_p->localClient->sendB; | |
98 | sp->is_cbr += target_p->localClient->receiveB; | |
99 | sp->is_cks += target_p->localClient->sendK; | |
100 | sp->is_ckr += target_p->localClient->receiveK; | |
101 | sp->is_cti += rb_current_time() - target_p->localClient->firsttime; | |
102 | sp->is_cl++; | |
103 | if(sp->is_cbs > 1023) | |
104 | { | |
105 | sp->is_cks += (sp->is_cbs >> 10); | |
106 | sp->is_cbs &= 0x3ff; | |
107 | } | |
108 | if(sp->is_cbr > 1023) | |
109 | { | |
110 | sp->is_ckr += (sp->is_cbr >> 10); | |
111 | sp->is_cbr &= 0x3ff; | |
112 | } | |
113 | ||
114 | } | |
115 | ||
116 | RB_DLINK_FOREACH(ptr, unknown_list.head) | |
117 | { | |
118 | sp->is_ni++; | |
119 | } | |
120 | ||
121 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
122 | "T :accepts %u refused %u", sp->is_ac, sp->is_ref); | |
123 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
124 | "T :rejected %u delaying %lu", | |
125 | sp->is_rej, rb_dlink_list_length(&delay_exit)); | |
126 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
127 | "T :nicks being delayed %lu", | |
128 | get_nd_count()); | |
129 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
130 | "T :unknown commands %u prefixes %u", | |
131 | sp->is_unco, sp->is_unpf); | |
132 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
133 | "T :nick collisions %u saves %u unknown closes %u", | |
134 | sp->is_kill, sp->is_save, sp->is_ni); | |
135 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
136 | "T :wrong direction %u empty %u", | |
137 | sp->is_wrdi, sp->is_empt); | |
138 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
139 | "T :numerics seen %u", sp->is_num); | |
140 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
141 | "T :tgchange blocked msgs %u restricted addrs %lu", | |
142 | sp->is_tgch, rb_dlink_list_length(&tgchange_list)); | |
143 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
144 | "T :auth successes %u fails %u", | |
145 | sp->is_asuc, sp->is_abad); | |
146 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
147 | "T :sasl successes %u fails %u", | |
148 | sp->is_ssuc, sp->is_sbad); | |
149 | sendto_one_numeric(source_p, RPL_STATSDEBUG, "T :Client Server"); | |
150 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
151 | "T :connected %u %u", sp->is_cl, sp->is_sv); | |
152 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
153 | "T :bytes sent %d.%uK %d.%uK", | |
154 | (int) sp->is_cks, sp->is_cbs, | |
155 | (int) sp->is_sks, sp->is_sbs); | |
156 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
157 | "T :bytes recv %d.%uK %d.%uK", | |
158 | (int) sp->is_ckr, sp->is_cbr, | |
159 | (int) sp->is_skr, sp->is_sbr); | |
160 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
161 | "T :time connected %d %d", | |
162 | (int) sp->is_cti, (int) sp->is_sti); | |
163 | } | |
164 | ||
165 | void | |
166 | count_memory(struct Client *source_p) | |
167 | { | |
168 | struct Client *target_p; | |
169 | struct Channel *chptr; | |
170 | struct Ban *actualBan; | |
171 | rb_dlink_node *rb_dlink; | |
172 | rb_dlink_node *ptr; | |
173 | int channel_count = 0; | |
174 | int local_client_conf_count = 0; /* local client conf links */ | |
175 | int users_counted = 0; /* user structs */ | |
176 | ||
177 | int channel_users = 0; | |
178 | int channel_invites = 0; | |
179 | int channel_bans = 0; | |
180 | int channel_except = 0; | |
181 | int channel_invex = 0; | |
182 | int channel_quiets = 0; | |
183 | ||
184 | int class_count = 0; /* classes */ | |
185 | int conf_count = 0; /* conf lines */ | |
186 | int users_invited_count = 0; /* users invited */ | |
187 | int user_channels = 0; /* users in channels */ | |
188 | int aways_counted = 0; | |
189 | size_t number_servers_cached; /* number of servers cached by scache */ | |
190 | ||
191 | size_t channel_memory = 0; | |
192 | size_t channel_ban_memory = 0; | |
193 | size_t channel_except_memory = 0; | |
194 | size_t channel_invex_memory = 0; | |
195 | size_t channel_quiet_memory = 0; | |
196 | ||
197 | size_t away_memory = 0; /* memory used by aways */ | |
198 | size_t ww = 0; /* whowas array count */ | |
199 | size_t wwm = 0; /* whowas array memory used */ | |
200 | size_t conf_memory = 0; /* memory used by conf lines */ | |
201 | size_t mem_servers_cached; /* memory used by scache */ | |
202 | ||
203 | size_t linebuf_count = 0; | |
204 | size_t linebuf_memory_used = 0; | |
205 | ||
206 | size_t total_channel_memory = 0; | |
207 | size_t totww = 0; | |
208 | ||
209 | size_t local_client_count = 0; | |
210 | size_t local_client_memory_used = 0; | |
211 | ||
212 | size_t remote_client_count = 0; | |
213 | size_t remote_client_memory_used = 0; | |
214 | ||
215 | size_t total_memory = 0; | |
216 | ||
217 | count_whowas_memory(&ww, &wwm); | |
218 | ||
219 | RB_DLINK_FOREACH(ptr, global_client_list.head) | |
220 | { | |
221 | target_p = ptr->data; | |
222 | if(MyConnect(target_p)) | |
223 | { | |
224 | local_client_conf_count++; | |
225 | } | |
226 | ||
227 | if(target_p->user) | |
228 | { | |
229 | users_counted++; | |
230 | users_invited_count += rb_dlink_list_length(&target_p->user->invited); | |
231 | user_channels += rb_dlink_list_length(&target_p->user->channel); | |
232 | if(target_p->user->away) | |
233 | { | |
234 | aways_counted++; | |
235 | away_memory += (strlen(target_p->user->away) + 1); | |
236 | } | |
237 | } | |
238 | } | |
239 | ||
240 | /* Count up all channels, ban lists, except lists, Invex lists */ | |
241 | RB_DLINK_FOREACH(ptr, global_channel_list.head) | |
242 | { | |
243 | chptr = ptr->data; | |
244 | channel_count++; | |
245 | channel_memory += (strlen(chptr->chname) + sizeof(struct Channel)); | |
246 | ||
247 | channel_users += rb_dlink_list_length(&chptr->members); | |
248 | channel_invites += rb_dlink_list_length(&chptr->invites); | |
249 | ||
250 | RB_DLINK_FOREACH(rb_dlink, chptr->banlist.head) | |
251 | { | |
252 | actualBan = rb_dlink->data; | |
253 | channel_bans++; | |
254 | ||
255 | channel_ban_memory += sizeof(rb_dlink_node) + sizeof(struct Ban); | |
256 | } | |
257 | ||
258 | RB_DLINK_FOREACH(rb_dlink, chptr->exceptlist.head) | |
259 | { | |
260 | actualBan = rb_dlink->data; | |
261 | channel_except++; | |
262 | ||
263 | channel_except_memory += (sizeof(rb_dlink_node) + sizeof(struct Ban)); | |
264 | } | |
265 | ||
266 | RB_DLINK_FOREACH(rb_dlink, chptr->invexlist.head) | |
267 | { | |
268 | actualBan = rb_dlink->data; | |
269 | channel_invex++; | |
270 | ||
271 | channel_invex_memory += (sizeof(rb_dlink_node) + sizeof(struct Ban)); | |
272 | } | |
273 | ||
274 | RB_DLINK_FOREACH(rb_dlink, chptr->quietlist.head) | |
275 | { | |
276 | actualBan = rb_dlink->data; | |
277 | channel_quiets++; | |
278 | ||
279 | channel_quiet_memory += (sizeof(rb_dlink_node) + sizeof(struct Ban)); | |
280 | } | |
281 | } | |
282 | ||
283 | /* count up all classes */ | |
284 | ||
285 | class_count = rb_dlink_list_length(&class_list) + 1; | |
286 | ||
287 | rb_count_rb_linebuf_memory(&linebuf_count, &linebuf_memory_used); | |
288 | ||
289 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
290 | "z :Users %u(%lu) Invites %u(%lu)", | |
291 | users_counted, | |
292 | (unsigned long) users_counted * sizeof(struct User), | |
293 | users_invited_count, | |
294 | (unsigned long) users_invited_count * sizeof(rb_dlink_node)); | |
295 | ||
296 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
297 | "z :User channels %u(%lu) Aways %u(%d)", | |
298 | user_channels, | |
299 | (unsigned long) user_channels * sizeof(rb_dlink_node), | |
300 | aways_counted, (int) away_memory); | |
301 | ||
302 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
303 | "z :Attached confs %u(%lu)", | |
304 | local_client_conf_count, | |
305 | (unsigned long) local_client_conf_count * sizeof(rb_dlink_node)); | |
306 | ||
307 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
308 | "z :Conflines %u(%d)", conf_count, (int) conf_memory); | |
309 | ||
310 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
311 | "z :Classes %u(%lu)", | |
312 | class_count, | |
313 | (unsigned long) class_count * sizeof(struct Class)); | |
314 | ||
315 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
316 | "z :Channels %u(%d)", | |
317 | channel_count, (int) channel_memory); | |
318 | ||
319 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
320 | "z :Bans %u(%d) Exceptions %u(%d) Invex %u(%d) Quiets %u(%d)", | |
321 | channel_bans, (int) channel_ban_memory, | |
322 | channel_except, (int) channel_except_memory, | |
323 | channel_invex, (int) channel_invex_memory, | |
324 | channel_quiets, (int) channel_quiet_memory); | |
325 | ||
326 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
327 | "z :Channel members %u(%lu) invite %u(%lu)", | |
328 | channel_users, | |
329 | (unsigned long) channel_users * sizeof(rb_dlink_node), | |
330 | channel_invites, | |
331 | (unsigned long) channel_invites * sizeof(rb_dlink_node)); | |
332 | ||
333 | total_channel_memory = channel_memory + | |
334 | channel_ban_memory + | |
335 | channel_users * sizeof(rb_dlink_node) + channel_invites * sizeof(rb_dlink_node); | |
336 | ||
337 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
338 | "z :Whowas array %ld(%ld)", | |
339 | (long)ww, (long)wwm); | |
340 | ||
341 | totww = wwm; | |
342 | ||
343 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
344 | "z :Hash: client %u(%ld) chan %u(%ld)", | |
345 | U_MAX, (long)(U_MAX * sizeof(rb_dlink_list)), | |
346 | CH_MAX, (long)(CH_MAX * sizeof(rb_dlink_list))); | |
347 | ||
348 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
349 | "z :linebuf %ld(%ld)", | |
350 | (long)linebuf_count, (long)linebuf_memory_used); | |
351 | ||
352 | count_scache(&number_servers_cached, &mem_servers_cached); | |
353 | ||
354 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
355 | "z :scache %ld(%ld)", | |
356 | (long)number_servers_cached, (long)mem_servers_cached); | |
357 | ||
358 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
359 | "z :hostname hash %d(%ld)", | |
360 | HOST_MAX, (long)HOST_MAX * sizeof(rb_dlink_list)); | |
361 | ||
362 | total_memory = totww + total_channel_memory + conf_memory + | |
363 | class_count * sizeof(struct Class); | |
364 | ||
365 | total_memory += mem_servers_cached; | |
366 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
367 | "z :Total: whowas %d channel %d conf %d", | |
368 | (int) totww, (int) total_channel_memory, | |
369 | (int) conf_memory); | |
370 | ||
371 | count_local_client_memory(&local_client_count, &local_client_memory_used); | |
372 | total_memory += local_client_memory_used; | |
373 | ||
374 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
375 | "z :Local client Memory in use: %ld(%ld)", | |
376 | (long)local_client_count, (long)local_client_memory_used); | |
377 | ||
378 | ||
379 | count_remote_client_memory(&remote_client_count, &remote_client_memory_used); | |
380 | total_memory += remote_client_memory_used; | |
381 | ||
382 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
383 | "z :Remote client Memory in use: %ld(%ld)", | |
384 | (long)remote_client_count, | |
385 | (long)remote_client_memory_used); | |
386 | } |