]>
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 | struct ServerStatistics ServerStats; | |
45 | ||
46 | void | |
47 | init_stats() | |
48 | { | |
49 | memset(&ircst, 0, sizeof(ircst)); | |
50 | } | |
51 | ||
52 | /* | |
53 | * tstats | |
54 | * | |
55 | * inputs - client to report to | |
56 | * output - NONE | |
57 | * side effects - | |
58 | */ | |
59 | void | |
60 | tstats(struct Client *source_p) | |
61 | { | |
62 | struct Client *target_p; | |
63 | struct ServerStatistics *sp; | |
64 | struct ServerStatistics tmp; | |
65 | rb_dlink_node *ptr; | |
66 | ||
67 | sp = &tmp; | |
68 | memcpy(sp, ServerStats, sizeof(struct ServerStatistics)); | |
69 | ||
70 | RB_DLINK_FOREACH(ptr, serv_list.head) | |
71 | { | |
72 | target_p = ptr->data; | |
73 | ||
74 | sp->is_sbs += target_p->localClient->sendB; | |
75 | sp->is_sbr += target_p->localClient->receiveB; | |
76 | sp->is_sks += target_p->localClient->sendK; | |
77 | sp->is_skr += target_p->localClient->receiveK; | |
78 | sp->is_sti += rb_current_time() - target_p->localClient->firsttime; | |
79 | sp->is_sv++; | |
80 | if(sp->is_sbs > 1023) | |
81 | { | |
82 | sp->is_sks += (sp->is_sbs >> 10); | |
83 | sp->is_sbs &= 0x3ff; | |
84 | } | |
85 | if(sp->is_sbr > 1023) | |
86 | { | |
87 | sp->is_skr += (sp->is_sbr >> 10); | |
88 | sp->is_sbr &= 0x3ff; | |
89 | } | |
90 | } | |
91 | ||
92 | RB_DLINK_FOREACH(ptr, lclient_list.head) | |
93 | { | |
94 | target_p = ptr->data; | |
95 | ||
96 | sp->is_cbs += target_p->localClient->sendB; | |
97 | sp->is_cbr += target_p->localClient->receiveB; | |
98 | sp->is_cks += target_p->localClient->sendK; | |
99 | sp->is_ckr += target_p->localClient->receiveK; | |
100 | sp->is_cti += rb_current_time() - target_p->localClient->firsttime; | |
101 | sp->is_cl++; | |
102 | if(sp->is_cbs > 1023) | |
103 | { | |
104 | sp->is_cks += (sp->is_cbs >> 10); | |
105 | sp->is_cbs &= 0x3ff; | |
106 | } | |
107 | if(sp->is_cbr > 1023) | |
108 | { | |
109 | sp->is_ckr += (sp->is_cbr >> 10); | |
110 | sp->is_cbr &= 0x3ff; | |
111 | } | |
112 | ||
113 | } | |
114 | ||
115 | RB_DLINK_FOREACH(ptr, unknown_list.head) | |
116 | { | |
117 | sp->is_ni++; | |
118 | } | |
119 | ||
120 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
121 | "T :accepts %u refused %u", sp->is_ac, sp->is_ref); | |
122 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
123 | "T :rejected %u delaying %lu", | |
124 | sp->is_rej, rb_dlink_list_length(&delay_exit)); | |
125 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
126 | "T :nicks being delayed %lu", | |
127 | get_nd_count()); | |
128 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
129 | "T :unknown commands %u prefixes %u", | |
130 | sp->is_unco, sp->is_unpf); | |
131 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
132 | "T :nick collisions %u saves %u unknown closes %u", | |
133 | sp->is_kill, sp->is_save, sp->is_ni); | |
134 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
135 | "T :wrong direction %u empty %u", | |
136 | sp->is_wrdi, sp->is_empt); | |
137 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
138 | "T :numerics seen %u", sp->is_num); | |
139 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
140 | "T :tgchange blocked msgs %u restricted addrs %lu", | |
141 | sp->is_tgch, rb_dlink_list_length(&tgchange_list)); | |
142 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
143 | "T :auth successes %u fails %u", | |
144 | sp->is_asuc, sp->is_abad); | |
145 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
146 | "T :sasl successes %u fails %u", | |
147 | sp->is_ssuc, sp->is_sbad); | |
148 | sendto_one_numeric(source_p, RPL_STATSDEBUG, "T :Client Server"); | |
149 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
150 | "T :connected %u %u", sp->is_cl, sp->is_sv); | |
151 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
152 | "T :bytes sent %d.%uK %d.%uK", | |
153 | (int) sp->is_cks, sp->is_cbs, | |
154 | (int) sp->is_sks, sp->is_sbs); | |
155 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
156 | "T :bytes recv %d.%uK %d.%uK", | |
157 | (int) sp->is_ckr, sp->is_cbr, | |
158 | (int) sp->is_skr, sp->is_sbr); | |
159 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
160 | "T :time connected %d %d", | |
161 | (int) sp->is_cti, (int) sp->is_sti); | |
162 | } | |
163 | ||
164 | void | |
165 | count_memory(struct Client *source_p) | |
166 | { | |
167 | struct Client *target_p; | |
168 | struct Channel *chptr; | |
169 | struct Ban *actualBan; | |
170 | rb_dlink_node *rb_dlink; | |
171 | rb_dlink_node *ptr; | |
172 | int channel_count = 0; | |
173 | int local_client_conf_count = 0; /* local client conf links */ | |
174 | int users_counted = 0; /* user structs */ | |
175 | ||
176 | int channel_users = 0; | |
177 | int channel_invites = 0; | |
178 | int channel_bans = 0; | |
179 | int channel_except = 0; | |
180 | int channel_invex = 0; | |
181 | int channel_quiets = 0; | |
182 | ||
183 | int class_count = 0; /* classes */ | |
184 | int conf_count = 0; /* conf lines */ | |
185 | int users_invited_count = 0; /* users invited */ | |
186 | int user_channels = 0; /* users in channels */ | |
187 | int aways_counted = 0; | |
188 | size_t number_servers_cached; /* number of servers cached by scache */ | |
189 | ||
190 | size_t channel_memory = 0; | |
191 | size_t channel_ban_memory = 0; | |
192 | size_t channel_except_memory = 0; | |
193 | size_t channel_invex_memory = 0; | |
194 | size_t channel_quiet_memory = 0; | |
195 | ||
196 | size_t away_memory = 0; /* memory used by aways */ | |
197 | size_t ww = 0; /* whowas array count */ | |
198 | size_t wwm = 0; /* whowas array memory used */ | |
199 | size_t conf_memory = 0; /* memory used by conf lines */ | |
200 | size_t mem_servers_cached; /* memory used by scache */ | |
201 | ||
202 | size_t linebuf_count = 0; | |
203 | size_t linebuf_memory_used = 0; | |
204 | ||
205 | size_t total_channel_memory = 0; | |
206 | size_t totww = 0; | |
207 | ||
208 | size_t local_client_count = 0; | |
209 | size_t local_client_memory_used = 0; | |
210 | ||
211 | size_t remote_client_count = 0; | |
212 | size_t remote_client_memory_used = 0; | |
213 | ||
214 | size_t total_memory = 0; | |
215 | ||
216 | count_whowas_memory(&ww, &wwm); | |
217 | ||
218 | RB_DLINK_FOREACH(ptr, global_client_list.head) | |
219 | { | |
220 | target_p = ptr->data; | |
221 | if(MyConnect(target_p)) | |
222 | { | |
223 | local_client_conf_count++; | |
224 | } | |
225 | ||
226 | if(target_p->user) | |
227 | { | |
228 | users_counted++; | |
229 | users_invited_count += rb_dlink_list_length(&target_p->user->invited); | |
230 | user_channels += rb_dlink_list_length(&target_p->user->channel); | |
231 | if(target_p->user->away) | |
232 | { | |
233 | aways_counted++; | |
234 | away_memory += (strlen(target_p->user->away) + 1); | |
235 | } | |
236 | } | |
237 | } | |
238 | ||
239 | /* Count up all channels, ban lists, except lists, Invex lists */ | |
240 | RB_DLINK_FOREACH(ptr, global_channel_list.head) | |
241 | { | |
242 | chptr = ptr->data; | |
243 | channel_count++; | |
244 | channel_memory += (strlen(chptr->chname) + sizeof(struct Channel)); | |
245 | ||
246 | channel_users += rb_dlink_list_length(&chptr->members); | |
247 | channel_invites += rb_dlink_list_length(&chptr->invites); | |
248 | ||
249 | RB_DLINK_FOREACH(rb_dlink, chptr->banlist.head) | |
250 | { | |
251 | actualBan = rb_dlink->data; | |
252 | channel_bans++; | |
253 | ||
254 | channel_ban_memory += sizeof(rb_dlink_node) + sizeof(struct Ban); | |
255 | } | |
256 | ||
257 | RB_DLINK_FOREACH(rb_dlink, chptr->exceptlist.head) | |
258 | { | |
259 | actualBan = rb_dlink->data; | |
260 | channel_except++; | |
261 | ||
262 | channel_except_memory += (sizeof(rb_dlink_node) + sizeof(struct Ban)); | |
263 | } | |
264 | ||
265 | RB_DLINK_FOREACH(rb_dlink, chptr->invexlist.head) | |
266 | { | |
267 | actualBan = rb_dlink->data; | |
268 | channel_invex++; | |
269 | ||
270 | channel_invex_memory += (sizeof(rb_dlink_node) + sizeof(struct Ban)); | |
271 | } | |
272 | ||
273 | RB_DLINK_FOREACH(rb_dlink, chptr->quietlist.head) | |
274 | { | |
275 | actualBan = rb_dlink->data; | |
276 | channel_quiets++; | |
277 | ||
278 | channel_quiet_memory += (sizeof(rb_dlink_node) + sizeof(struct Ban)); | |
279 | } | |
280 | } | |
281 | ||
282 | /* count up all classes */ | |
283 | ||
284 | class_count = rb_dlink_list_length(&class_list) + 1; | |
285 | ||
286 | rb_count_rb_linebuf_memory(&linebuf_count, &linebuf_memory_used); | |
287 | ||
288 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
289 | "z :Users %u(%lu) Invites %u(%lu)", | |
290 | users_counted, | |
291 | (unsigned long) users_counted * sizeof(struct User), | |
292 | users_invited_count, | |
293 | (unsigned long) users_invited_count * sizeof(rb_dlink_node)); | |
294 | ||
295 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
296 | "z :User channels %u(%lu) Aways %u(%d)", | |
297 | user_channels, | |
298 | (unsigned long) user_channels * sizeof(rb_dlink_node), | |
299 | aways_counted, (int) away_memory); | |
300 | ||
301 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
302 | "z :Attached confs %u(%lu)", | |
303 | local_client_conf_count, | |
304 | (unsigned long) local_client_conf_count * sizeof(rb_dlink_node)); | |
305 | ||
306 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
307 | "z :Conflines %u(%d)", conf_count, (int) conf_memory); | |
308 | ||
309 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
310 | "z :Classes %u(%lu)", | |
311 | class_count, | |
312 | (unsigned long) class_count * sizeof(struct Class)); | |
313 | ||
314 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
315 | "z :Channels %u(%d)", | |
316 | channel_count, (int) channel_memory); | |
317 | ||
318 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
319 | "z :Bans %u(%d) Exceptions %u(%d) Invex %u(%d) Quiets %u(%d)", | |
320 | channel_bans, (int) channel_ban_memory, | |
321 | channel_except, (int) channel_except_memory, | |
322 | channel_invex, (int) channel_invex_memory, | |
323 | channel_quiets, (int) channel_quiet_memory); | |
324 | ||
325 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
326 | "z :Channel members %u(%lu) invite %u(%lu)", | |
327 | channel_users, | |
328 | (unsigned long) channel_users * sizeof(rb_dlink_node), | |
329 | channel_invites, | |
330 | (unsigned long) channel_invites * sizeof(rb_dlink_node)); | |
331 | ||
332 | total_channel_memory = channel_memory + | |
333 | channel_ban_memory + | |
334 | channel_users * sizeof(rb_dlink_node) + channel_invites * sizeof(rb_dlink_node); | |
335 | ||
336 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
337 | "z :Whowas array %ld(%ld)", | |
338 | (long)ww, (long)wwm); | |
339 | ||
340 | totww = wwm; | |
341 | ||
342 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
343 | "z :Hash: client %u(%ld) chan %u(%ld)", | |
344 | U_MAX, (long)(U_MAX * sizeof(rb_dlink_list)), | |
345 | CH_MAX, (long)(CH_MAX * sizeof(rb_dlink_list))); | |
346 | ||
347 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
348 | "z :linebuf %ld(%ld)", | |
349 | (long)linebuf_count, (long)linebuf_memory_used); | |
350 | ||
351 | count_scache(&number_servers_cached, &mem_servers_cached); | |
352 | ||
353 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
354 | "z :scache %ld(%ld)", | |
355 | (long)number_servers_cached, (long)mem_servers_cached); | |
356 | ||
357 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
358 | "z :hostname hash %d(%ld)", | |
359 | HOST_MAX, (long)HOST_MAX * sizeof(rb_dlink_list)); | |
360 | ||
361 | total_memory = totww + total_channel_memory + conf_memory + | |
362 | class_count * sizeof(struct Class); | |
363 | ||
364 | total_memory += mem_servers_cached; | |
365 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
366 | "z :Total: whowas %d channel %d conf %d", | |
367 | (int) totww, (int) total_channel_memory, | |
368 | (int) conf_memory); | |
369 | ||
370 | count_local_client_memory(&local_client_count, &local_client_memory_used); | |
371 | total_memory += local_client_memory_used; | |
372 | ||
373 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
374 | "z :Local client Memory in use: %ld(%ld)", | |
375 | (long)local_client_count, (long)local_client_memory_used); | |
376 | ||
377 | ||
378 | count_remote_client_memory(&remote_client_count, &remote_client_memory_used); | |
379 | total_memory += remote_client_memory_used; | |
380 | ||
381 | sendto_one_numeric(source_p, RPL_STATSDEBUG, | |
382 | "z :Remote client Memory in use: %ld(%ld)", | |
383 | (long)remote_client_count, | |
384 | (long)remote_client_memory_used); | |
385 | } |