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