diff options
Diffstat (limited to 'src/plugins/stats/functions.c')
-rw-r--r-- | src/plugins/stats/functions.c | 376 |
1 files changed, 376 insertions, 0 deletions
diff --git a/src/plugins/stats/functions.c b/src/plugins/stats/functions.c new file mode 100644 index 00000000..ed21dcd3 --- /dev/null +++ b/src/plugins/stats/functions.c | |||
@@ -0,0 +1,376 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | (C) 2004, 2005 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 2, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | |||
20 | */ | ||
21 | |||
22 | #include "platform.h" | ||
23 | #include "gnunetgtk_common.h" | ||
24 | #include <GNUnet/gnunet_stats_lib.h> | ||
25 | #include <GNUnet/gnunet_getoption_lib.h> | ||
26 | #include <GNUnet/gnunet_protocols.h> | ||
27 | #include "functions.h" | ||
28 | |||
29 | static StatPair * lastStatValues; | ||
30 | |||
31 | static unsigned int lsv_size; | ||
32 | |||
33 | static GNUNET_TCP_SOCKET * sock; | ||
34 | |||
35 | static int getStatValue(long long * value, | ||
36 | long long * lvalue, | ||
37 | cron_t * dtime, | ||
38 | const char * optName) { | ||
39 | unsigned int i; | ||
40 | |||
41 | *value = 0; | ||
42 | if (lvalue != NULL) | ||
43 | *lvalue = 0; | ||
44 | for (i=0;i<lsv_size;i++) { | ||
45 | if (0 == strcmp(optName, | ||
46 | lastStatValues[i].statName)) { | ||
47 | *value = lastStatValues[i].value; | ||
48 | if (lvalue != NULL) | ||
49 | *lvalue = lastStatValues[i].lvalue; | ||
50 | if (dtime != NULL) | ||
51 | *dtime = lastStatValues[i].delta; | ||
52 | return OK; | ||
53 | } | ||
54 | } | ||
55 | return SYSERR; | ||
56 | } | ||
57 | |||
58 | static int getConnectedNodesStat(const void * closure, | ||
59 | gfloat ** data) { | ||
60 | long long val; | ||
61 | char * cmh; | ||
62 | long cval; | ||
63 | |||
64 | cmh = getConfigurationOptionValue(sock, | ||
65 | "gnunetd", | ||
66 | "connection-max-hosts"); | ||
67 | if (cmh == NULL) | ||
68 | return SYSERR; | ||
69 | cval = atol(cmh); | ||
70 | FREE(cmh); | ||
71 | if (OK != getStatValue(&val, | ||
72 | NULL, | ||
73 | NULL, | ||
74 | _("# currently connected nodes"))) | ||
75 | return SYSERR; | ||
76 | data[0][0] = 0.8 * val / cval; | ||
77 | return OK; | ||
78 | } | ||
79 | |||
80 | static int getCPULoadStat(const void * closure, | ||
81 | gfloat ** data) { | ||
82 | long long val; | ||
83 | |||
84 | if (OK != getStatValue(&val, | ||
85 | NULL, | ||
86 | NULL, | ||
87 | _("% of allowed cpu load"))) | ||
88 | return SYSERR; | ||
89 | data[0][0] = val / 125.0; | ||
90 | return OK; | ||
91 | } | ||
92 | |||
93 | static int getTrafficRecvStats(const void * closure, | ||
94 | gfloat ** data) { | ||
95 | long long total; | ||
96 | long long noise; | ||
97 | long long content; | ||
98 | long long queries; | ||
99 | long long ltotal; | ||
100 | long long lnoise; | ||
101 | long long lcontent; | ||
102 | long long lqueries; | ||
103 | long long band; | ||
104 | long long tmp; | ||
105 | long long ltmp; | ||
106 | cron_t dtime; | ||
107 | char * available; | ||
108 | char * buffer; | ||
109 | int i; | ||
110 | |||
111 | if (OK != getStatValue(&total, | ||
112 | <otal, | ||
113 | &dtime, | ||
114 | _("# bytes decrypted"))) | ||
115 | return SYSERR; | ||
116 | if (OK != getStatValue(&noise, | ||
117 | &lnoise, | ||
118 | NULL, | ||
119 | _("# bytes of noise received"))) | ||
120 | return SYSERR; | ||
121 | i = 0; | ||
122 | content = lcontent = 0; | ||
123 | buffer = MALLOC(512); | ||
124 | SNPRINTF(buffer, | ||
125 | 512, | ||
126 | _("# bytes received of type %d"), | ||
127 | GAP_p2p_PROTO_RESULT); | ||
128 | if (OK == getStatValue(&tmp, | ||
129 | <mp, | ||
130 | NULL, | ||
131 | buffer)) { | ||
132 | content += tmp; | ||
133 | lcontent += ltmp; | ||
134 | } | ||
135 | i = 0; | ||
136 | SNPRINTF(buffer, | ||
137 | 512, | ||
138 | _("# bytes received of type %d"), | ||
139 | GAP_p2p_PROTO_QUERY); | ||
140 | if (OK == getStatValue(&tmp, | ||
141 | <mp, | ||
142 | NULL, | ||
143 | buffer)) { | ||
144 | queries += tmp; | ||
145 | lqueries += ltmp; | ||
146 | } | ||
147 | FREE(buffer); | ||
148 | available = getConfigurationOptionValue(sock, | ||
149 | "LOAD", | ||
150 | "MAXNETDOWNBPSTOTAL"); | ||
151 | if (available == NULL) | ||
152 | return SYSERR; | ||
153 | band = atol(available) * dtime / cronSECONDS; | ||
154 | FREE(available); | ||
155 | total -= ltotal; | ||
156 | noise -= lnoise; | ||
157 | queries -= lqueries; | ||
158 | content -= lcontent; | ||
159 | if (band <= 0) { | ||
160 | data[0][0] = 0.0; | ||
161 | data[0][1] = 0.0; | ||
162 | data[0][2] = 0.0; | ||
163 | data[0][3] = 0.0; | ||
164 | return OK; | ||
165 | } | ||
166 | data[0][0] = 0.8 * noise / band; /* red */ | ||
167 | data[0][1] = 0.8 * (content+noise) / band; /* green */ | ||
168 | data[0][2] = 0.8 * (queries+content+noise) / band; /* yellow */ | ||
169 | data[0][3] = 0.8 * total / band; /* blue */ | ||
170 | /*printf("I: %f %f %f\n", | ||
171 | data[0][0], | ||
172 | data[0][1], | ||
173 | data[0][2]);*/ | ||
174 | |||
175 | return OK; | ||
176 | } | ||
177 | |||
178 | static int getTrafficSendStats(const void * closure, | ||
179 | gfloat ** data) { | ||
180 | long long total; | ||
181 | long long noise; | ||
182 | long long content; | ||
183 | long long queries; | ||
184 | long long ltotal; | ||
185 | long long lnoise; | ||
186 | long long lcontent; | ||
187 | long long lqueries; | ||
188 | long long band; | ||
189 | long long tmp; | ||
190 | long long ltmp; | ||
191 | cron_t dtime; | ||
192 | char * available; | ||
193 | char * buffer; | ||
194 | int i; | ||
195 | |||
196 | if (OK != getStatValue(&total, | ||
197 | <otal, | ||
198 | &dtime, | ||
199 | _("# encrypted bytes sent"))) | ||
200 | return SYSERR; | ||
201 | if (OK != getStatValue(&noise, | ||
202 | &lnoise, | ||
203 | NULL, | ||
204 | _("# bytes noise sent"))) | ||
205 | return SYSERR; | ||
206 | i = 0; | ||
207 | content = lcontent = 0; | ||
208 | buffer = MALLOC(512); | ||
209 | SNPRINTF(buffer, | ||
210 | 512, | ||
211 | _("# bytes transmitted of type %d"), | ||
212 | GAP_p2p_PROTO_RESULT); | ||
213 | if (OK == getStatValue(&tmp, | ||
214 | <mp, | ||
215 | NULL, | ||
216 | buffer)) { | ||
217 | content += tmp; | ||
218 | lcontent += ltmp; | ||
219 | } | ||
220 | i = 0; | ||
221 | SNPRINTF(buffer, | ||
222 | 512, | ||
223 | _("# bytes received of type %d"), | ||
224 | GAP_p2p_PROTO_QUERY); | ||
225 | if (OK == getStatValue(&tmp, | ||
226 | <mp, | ||
227 | NULL, | ||
228 | buffer)) { | ||
229 | queries += tmp; | ||
230 | lqueries += ltmp; | ||
231 | } | ||
232 | FREE(buffer); | ||
233 | available = getConfigurationOptionValue(sock, | ||
234 | "LOAD", | ||
235 | "MAXNETUPBPSTOTAL"); | ||
236 | if (available == NULL) | ||
237 | return SYSERR; | ||
238 | band = atol(available) * dtime / cronSECONDS; | ||
239 | FREE(available); | ||
240 | total -= ltotal; | ||
241 | noise -= lnoise; | ||
242 | queries -= lqueries; | ||
243 | content -= lcontent; | ||
244 | if (band <= 0) { | ||
245 | data[0][0] = 0.0; | ||
246 | data[0][1] = 0.0; | ||
247 | data[0][2] = 0.0; | ||
248 | data[0][3] = 0.0; | ||
249 | return OK; | ||
250 | } | ||
251 | data[0][0] = 0.8 * noise / band; /* red */ | ||
252 | data[0][1] = 0.8 * (noise + content) / band; /* green */ | ||
253 | data[0][2] = 0.8 * (noise + content + queries) / band; /* yellow */ | ||
254 | data[0][3] = 0.8 * total / band; /* yellow */ | ||
255 | /* printf("O: %f %f %f\n", | ||
256 | data[0][0], | ||
257 | data[0][1], | ||
258 | data[0][2]);*/ | ||
259 | return OK; | ||
260 | } | ||
261 | |||
262 | |||
263 | static int statsProcessor(const char * optName, | ||
264 | unsigned long long value, | ||
265 | void * data) { | ||
266 | cron_t * delta = data; | ||
267 | int j; | ||
268 | int found; | ||
269 | |||
270 | found = -1; | ||
271 | for (j=0;j<lsv_size;j++) | ||
272 | if (0 == strcmp(optName, | ||
273 | lastStatValues[j].statName)) | ||
274 | found = j; | ||
275 | if (found == -1) { | ||
276 | found = lsv_size; | ||
277 | GROW(lastStatValues, | ||
278 | lsv_size, | ||
279 | lsv_size+1); | ||
280 | lastStatValues[found].statName | ||
281 | = STRDUP(optName); | ||
282 | } | ||
283 | lastStatValues[found].lvalue | ||
284 | = lastStatValues[found].value; | ||
285 | lastStatValues[found].value | ||
286 | = value; | ||
287 | lastStatValues[found].delta | ||
288 | = *delta; | ||
289 | return OK; | ||
290 | } | ||
291 | |||
292 | /** | ||
293 | * Cron-job that updates all stat values. | ||
294 | */ | ||
295 | static void updateStatValues(void * unused) { | ||
296 | static cron_t lastUpdate; | ||
297 | cron_t now; | ||
298 | cron_t delta; | ||
299 | |||
300 | cronTime(&now); | ||
301 | delta = now - lastUpdate; | ||
302 | if (OK == requestStatistics(sock, | ||
303 | &statsProcessor, | ||
304 | &delta)) | ||
305 | lastUpdate = now; | ||
306 | } | ||
307 | |||
308 | |||
309 | StatEntry stats[] = { | ||
310 | { | ||
311 | gettext_noop("Connectivity"), | ||
312 | gettext_noop("# connected nodes (100% = connection table size)"), | ||
313 | &getConnectedNodesStat, | ||
314 | NULL, | ||
315 | 1, | ||
316 | NO, | ||
317 | }, | ||
318 | { | ||
319 | gettext_noop("CPU load"), | ||
320 | gettext_noop("CPU load (in percent of allowed load)"), | ||
321 | &getCPULoadStat, | ||
322 | NULL, | ||
323 | 1, | ||
324 | NO, | ||
325 | }, | ||
326 | { | ||
327 | gettext_noop("Inbound Traffic"), | ||
328 | gettext_noop("Noise (red), Content (green), Queries (yellow), other (blue)"), | ||
329 | &getTrafficRecvStats, | ||
330 | NULL, | ||
331 | 4, | ||
332 | YES, | ||
333 | }, | ||
334 | { | ||
335 | gettext_noop("Outbound Traffic"), | ||
336 | gettext_noop("Noise (red), Content (green), Queries (yellow), other (blue)"), | ||
337 | &getTrafficSendStats, | ||
338 | NULL, | ||
339 | 4, | ||
340 | YES, | ||
341 | }, | ||
342 | { | ||
343 | NULL, | ||
344 | NULL, | ||
345 | NULL, | ||
346 | NULL, | ||
347 | 1, | ||
348 | NO, | ||
349 | }, | ||
350 | }; | ||
351 | |||
352 | int UPDATE_INTERVAL; | ||
353 | |||
354 | void init_functions() { | ||
355 | UPDATE_INTERVAL | ||
356 | = getConfigurationInt("GNUNET-GTK", | ||
357 | "STATS-INTERVAL") * cronSECONDS; | ||
358 | if (UPDATE_INTERVAL == 0) | ||
359 | UPDATE_INTERVAL = 30 * cronSECONDS; | ||
360 | sock = getClientSocket(); | ||
361 | addCronJob(&updateStatValues, | ||
362 | UPDATE_INTERVAL, | ||
363 | UPDATE_INTERVAL, | ||
364 | NULL); | ||
365 | } | ||
366 | |||
367 | void done_functions() { | ||
368 | delCronJob(&updateStatValues, | ||
369 | UPDATE_INTERVAL, | ||
370 | NULL); | ||
371 | releaseClientSocket(sock); | ||
372 | sock = NULL; | ||
373 | } | ||
374 | |||
375 | |||
376 | /* end of functions.c */ | ||