diff options
Diffstat (limited to 'src/ats-tests/ats-testing-log.c')
-rw-r--r-- | src/ats-tests/ats-testing-log.c | 979 |
1 files changed, 0 insertions, 979 deletions
diff --git a/src/ats-tests/ats-testing-log.c b/src/ats-tests/ats-testing-log.c deleted file mode 100644 index dfdfa8a80..000000000 --- a/src/ats-tests/ats-testing-log.c +++ /dev/null | |||
@@ -1,979 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2010-2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your 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 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /** | ||
21 | * @file ats-tests/ats-testing-log.c | ||
22 | * @brief ats benchmark: logging for performance tests | ||
23 | * @author Christian Grothoff | ||
24 | * @author Matthias Wachs | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "ats-testing.h" | ||
29 | |||
30 | #define THROUGHPUT_TEMPLATE "#!/usr/bin/gnuplot \n" \ | ||
31 | "set datafile separator ';' \n" \ | ||
32 | "set title \"Throughput between Master and Slaves\" \n" \ | ||
33 | "set xlabel \"Time in ms\" \n" \ | ||
34 | "set ylabel \"Bytes/s\" \n" \ | ||
35 | "set grid \n" | ||
36 | |||
37 | #define RTT_TEMPLATE "#!/usr/bin/gnuplot \n" \ | ||
38 | "set datafile separator ';' \n" \ | ||
39 | "set title \"Application level roundtrip time between Master and Slaves\" \n" \ | ||
40 | "set xlabel \"Time in ms\" \n" \ | ||
41 | "set ylabel \"ms\" \n" \ | ||
42 | "set grid \n" | ||
43 | |||
44 | #define BW_TEMPLATE "#!/usr/bin/gnuplot \n" \ | ||
45 | "set datafile separator ';' \n" \ | ||
46 | "set title \"Bandwidth inbound and outbound between Master and Slaves\" \n" \ | ||
47 | "set xlabel \"Time in ms\" \n" \ | ||
48 | "set ylabel \"Bytes / s \" \n" \ | ||
49 | "set grid \n" | ||
50 | |||
51 | #define LOG_ITEMS_TIME 2 | ||
52 | #define LOG_ITEMS_PER_PEER 17 | ||
53 | |||
54 | #define LOG_ITEM_BYTES_SENT 1 | ||
55 | #define LOG_ITEM_MSGS_SENT 2 | ||
56 | #define LOG_ITEM_THROUGHPUT_SENT 3 | ||
57 | #define LOG_ITEM_BYTES_RECV 4 | ||
58 | #define LOG_ITEM_MSGS_RECV 5 | ||
59 | #define LOG_ITEM_THROUGHPUT_RECV 6 | ||
60 | #define LOG_ITEM_APP_RTT 7 | ||
61 | #define LOG_ITEM_ATS_BW_IN 8 | ||
62 | #define LOG_ITEM_ATS_BW_OUT 9 | ||
63 | #define LOG_ITEM_ATS_COSTS_LAN 10 | ||
64 | #define LOG_ITEM_ATS_WAN 11 | ||
65 | #define LOG_ITEM_ATS_WLAN 12 | ||
66 | #define LOG_ITEM_ATS_DELAY 13 | ||
67 | #define LOG_ITEM_ATS_DISTANCE 14 | ||
68 | #define LOG_ITEM_ATS_NETWORKTYPE 15 | ||
69 | #define LOG_ITEM_ATS_UTIL_UP 16 | ||
70 | #define LOG_ITEM_ATS_UTIL_DOWN 17 | ||
71 | |||
72 | /** | ||
73 | * A single logging time step for a partner | ||
74 | */ | ||
75 | struct PartnerLoggingTimestep | ||
76 | { | ||
77 | /** | ||
78 | * Peer | ||
79 | */ | ||
80 | struct BenchmarkPeer *slave; | ||
81 | |||
82 | /** | ||
83 | * Total number of messages this peer has sent | ||
84 | */ | ||
85 | unsigned int total_messages_sent; | ||
86 | |||
87 | /** | ||
88 | * Total number of bytes this peer has sent | ||
89 | */ | ||
90 | unsigned int total_bytes_sent; | ||
91 | |||
92 | /** | ||
93 | * Total number of messages this peer has received | ||
94 | */ | ||
95 | unsigned int total_messages_received; | ||
96 | |||
97 | /** | ||
98 | * Total number of bytes this peer has received | ||
99 | */ | ||
100 | unsigned int total_bytes_received; | ||
101 | |||
102 | /** | ||
103 | * Total outbound throughput for master in Bytes / s | ||
104 | */ | ||
105 | unsigned int throughput_sent; | ||
106 | |||
107 | /** | ||
108 | * Total inbound throughput for master in Bytes / s | ||
109 | */ | ||
110 | unsigned int throughput_recv; | ||
111 | |||
112 | /** | ||
113 | * Accumulated RTT for all messages | ||
114 | */ | ||
115 | unsigned int total_app_rtt; | ||
116 | |||
117 | /** | ||
118 | * Current application level delay | ||
119 | */ | ||
120 | unsigned int app_rtt; | ||
121 | |||
122 | /* Current ATS properties */ | ||
123 | |||
124 | unsigned int ats_distance; | ||
125 | |||
126 | struct GNUNET_TIME_Relative ats_delay; | ||
127 | |||
128 | uint32_t bandwidth_in; | ||
129 | |||
130 | uint32_t bandwidth_out; | ||
131 | |||
132 | uint32_t ats_utilization_out; | ||
133 | |||
134 | uint32_t ats_utilization_in; | ||
135 | |||
136 | enum GNUNET_NetworkType ats_network_type; | ||
137 | |||
138 | double pref_bandwidth; | ||
139 | double pref_delay; | ||
140 | }; | ||
141 | |||
142 | |||
143 | /** | ||
144 | * A single logging time step for a peer | ||
145 | */ | ||
146 | struct PeerLoggingTimestep | ||
147 | { | ||
148 | /** | ||
149 | * Next in DLL | ||
150 | */ | ||
151 | struct PeerLoggingTimestep *next; | ||
152 | |||
153 | /** | ||
154 | * Prev in DLL | ||
155 | */ | ||
156 | struct PeerLoggingTimestep *prev; | ||
157 | |||
158 | /** | ||
159 | * Logging timestamp | ||
160 | */ | ||
161 | struct GNUNET_TIME_Absolute timestamp; | ||
162 | |||
163 | /** | ||
164 | * Total number of messages this peer has sent | ||
165 | */ | ||
166 | unsigned int total_messages_sent; | ||
167 | |||
168 | /** | ||
169 | * Total number of bytes this peer has sent | ||
170 | */ | ||
171 | unsigned int total_bytes_sent; | ||
172 | |||
173 | /** | ||
174 | * Total number of messages this peer has received | ||
175 | */ | ||
176 | unsigned int total_messages_received; | ||
177 | |||
178 | /** | ||
179 | * Total number of bytes this peer has received | ||
180 | */ | ||
181 | unsigned int total_bytes_received; | ||
182 | |||
183 | /** | ||
184 | * Total outbound throughput for master in Bytes / s | ||
185 | */ | ||
186 | unsigned int total_throughput_send; | ||
187 | |||
188 | /** | ||
189 | * Total inbound throughput for master in Bytes / s | ||
190 | */ | ||
191 | unsigned int total_throughput_recv; | ||
192 | |||
193 | /** | ||
194 | * Logs for slaves | ||
195 | */ | ||
196 | struct PartnerLoggingTimestep *slaves_log; | ||
197 | }; | ||
198 | |||
199 | /** | ||
200 | * Entry for a benchmark peer | ||
201 | */ | ||
202 | struct LoggingPeer | ||
203 | { | ||
204 | /** | ||
205 | * Peer | ||
206 | */ | ||
207 | struct BenchmarkPeer *peer; | ||
208 | |||
209 | /** | ||
210 | * Start time | ||
211 | */ | ||
212 | struct GNUNET_TIME_Absolute start; | ||
213 | |||
214 | /** | ||
215 | * DLL for logging entries: head | ||
216 | */ | ||
217 | struct PeerLoggingTimestep *head; | ||
218 | |||
219 | /** | ||
220 | * DLL for logging entries: tail | ||
221 | */ | ||
222 | struct PeerLoggingTimestep *tail; | ||
223 | }; | ||
224 | |||
225 | struct LoggingHandle | ||
226 | { | ||
227 | /** | ||
228 | * Logging task | ||
229 | */ | ||
230 | struct GNUNET_SCHEDULER_Task *log_task; | ||
231 | |||
232 | /** | ||
233 | * Reference to perf_ats' masters | ||
234 | */ | ||
235 | int num_masters; | ||
236 | int num_slaves; | ||
237 | int running; | ||
238 | int verbose; | ||
239 | const char *name; | ||
240 | struct GNUNET_TIME_Relative frequency; | ||
241 | |||
242 | /** | ||
243 | * Log structure of length num_peers | ||
244 | */ | ||
245 | struct LoggingPeer *lp; | ||
246 | }; | ||
247 | |||
248 | |||
249 | static void | ||
250 | write_throughput_gnuplot_script (char *fn, struct LoggingPeer *lp, char **fs, | ||
251 | int slaves) | ||
252 | { | ||
253 | struct GNUNET_DISK_FileHandle *f; | ||
254 | char *gfn; | ||
255 | char *data; | ||
256 | int c_s; | ||
257 | |||
258 | GNUNET_asprintf (&gfn, "gnuplot_throughput_%s", fn); | ||
259 | fprintf (stderr, | ||
260 | "Writing throughput plot for master %u and %u slaves to `%s'\n", | ||
261 | lp->peer->no, slaves, gfn); | ||
262 | |||
263 | f = GNUNET_DISK_file_open (gfn, | ||
264 | GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, | ||
265 | GNUNET_DISK_PERM_USER_EXEC | ||
266 | | GNUNET_DISK_PERM_USER_READ | ||
267 | | GNUNET_DISK_PERM_USER_WRITE); | ||
268 | if (NULL == f) | ||
269 | { | ||
270 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open gnuplot file `%s'\n", | ||
271 | gfn); | ||
272 | GNUNET_free (gfn); | ||
273 | return; | ||
274 | } | ||
275 | |||
276 | /* Write header */ | ||
277 | if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, THROUGHPUT_TEMPLATE, | ||
278 | strlen (THROUGHPUT_TEMPLATE))) | ||
279 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
280 | "Cannot write data to plot file `%s'\n", gfn); | ||
281 | |||
282 | /* Write master data */ | ||
283 | GNUNET_asprintf (&data, | ||
284 | "plot '%s' using 2:%u with lines title 'Master %u send total', \\\n" \ | ||
285 | "'%s' using 2:%u with lines title 'Master %u receive total', \\\n", | ||
286 | fn, LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_SENT, lp->peer->no, | ||
287 | fn, LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_RECV, lp->peer->no); | ||
288 | if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, data, strlen (data))) | ||
289 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
290 | "Cannot write data to plot file `%s'\n", gfn); | ||
291 | GNUNET_free (data); | ||
292 | |||
293 | for (c_s = 0; c_s < slaves; c_s++) | ||
294 | { | ||
295 | GNUNET_asprintf (&data, | ||
296 | "'%s' using 2:%u with lines title 'Master %u - Slave %u send', \\\n" \ | ||
297 | "'%s' using 2:%u with lines title 'Master %u - Slave %u receive'%s\n", | ||
298 | fs[c_s], | ||
299 | LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_SENT, | ||
300 | lp->peer->no, | ||
301 | lp->peer->partners[c_s].dest->no, | ||
302 | fs[c_s], | ||
303 | LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_RECV, | ||
304 | lp->peer->no, | ||
305 | lp->peer->partners[c_s].dest->no, | ||
306 | (c_s < lp->peer->num_partners - 1) ? ", \\" : | ||
307 | "\n pause -1"); | ||
308 | if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, data, strlen (data))) | ||
309 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
310 | "Cannot write data to plot file `%s'\n", gfn); | ||
311 | GNUNET_free (data); | ||
312 | } | ||
313 | |||
314 | if (GNUNET_SYSERR == GNUNET_DISK_file_close (f)) | ||
315 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
316 | "Cannot close gnuplot file `%s'\n", gfn); | ||
317 | else | ||
318 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
319 | "Data successfully written to plot file `%s'\n", gfn); | ||
320 | GNUNET_free (gfn); | ||
321 | } | ||
322 | |||
323 | |||
324 | static void | ||
325 | write_rtt_gnuplot_script (char *fn, struct LoggingPeer *lp, char **fs, int | ||
326 | slaves) | ||
327 | { | ||
328 | struct GNUNET_DISK_FileHandle *f; | ||
329 | char *gfn; | ||
330 | char *data; | ||
331 | int c_s; | ||
332 | |||
333 | GNUNET_asprintf (&gfn, "gnuplot_rtt_%s", fn); | ||
334 | fprintf (stderr, "Writing rtt plot for master %u to `%s'\n", | ||
335 | lp->peer->no, gfn); | ||
336 | |||
337 | f = GNUNET_DISK_file_open (gfn, | ||
338 | GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, | ||
339 | GNUNET_DISK_PERM_USER_EXEC | ||
340 | | GNUNET_DISK_PERM_USER_READ | ||
341 | | GNUNET_DISK_PERM_USER_WRITE); | ||
342 | if (NULL == f) | ||
343 | { | ||
344 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open gnuplot file `%s'\n", | ||
345 | gfn); | ||
346 | GNUNET_free (gfn); | ||
347 | return; | ||
348 | } | ||
349 | |||
350 | /* Write header */ | ||
351 | if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, RTT_TEMPLATE, strlen ( | ||
352 | RTT_TEMPLATE))) | ||
353 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
354 | "Cannot write data to plot file `%s'\n", gfn); | ||
355 | |||
356 | for (c_s = 0; c_s < slaves; c_s++) | ||
357 | { | ||
358 | GNUNET_asprintf (&data, | ||
359 | "%s'%s' using 2:%u with lines title 'Master %u - Slave %u '%s\n", | ||
360 | (0 == c_s) ? "plot " : "", | ||
361 | fs[c_s], | ||
362 | LOG_ITEMS_TIME + LOG_ITEM_APP_RTT, | ||
363 | lp->peer->no, | ||
364 | lp->peer->partners[c_s].dest->no, | ||
365 | (c_s < lp->peer->num_partners - 1) ? ", \\" : | ||
366 | "\n pause -1"); | ||
367 | if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, data, strlen (data))) | ||
368 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
369 | "Cannot write data to plot file `%s'\n", gfn); | ||
370 | GNUNET_free (data); | ||
371 | } | ||
372 | |||
373 | if (GNUNET_SYSERR == GNUNET_DISK_file_close (f)) | ||
374 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot close gnuplot file `%s'\n", | ||
375 | gfn); | ||
376 | else | ||
377 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
378 | "Data successfully written to plot file `%s'\n", gfn); | ||
379 | GNUNET_free (gfn); | ||
380 | } | ||
381 | |||
382 | |||
383 | static void | ||
384 | write_bw_gnuplot_script (char *fn, struct LoggingPeer *lp, char **fs, int | ||
385 | slaves) | ||
386 | { | ||
387 | struct GNUNET_DISK_FileHandle *f; | ||
388 | char *gfn; | ||
389 | char *data; | ||
390 | int c_s; | ||
391 | |||
392 | GNUNET_asprintf (&gfn, "gnuplot_bw_%s", fn); | ||
393 | fprintf (stderr, "Writing bandwidth plot for master %u to `%s'\n", | ||
394 | lp->peer->no, gfn); | ||
395 | |||
396 | f = GNUNET_DISK_file_open (gfn, | ||
397 | GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, | ||
398 | GNUNET_DISK_PERM_USER_EXEC | ||
399 | | GNUNET_DISK_PERM_USER_READ | ||
400 | | GNUNET_DISK_PERM_USER_WRITE); | ||
401 | if (NULL == f) | ||
402 | { | ||
403 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open gnuplot file `%s'\n", | ||
404 | gfn); | ||
405 | GNUNET_free (gfn); | ||
406 | return; | ||
407 | } | ||
408 | |||
409 | /* Write header */ | ||
410 | if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, BW_TEMPLATE, strlen ( | ||
411 | BW_TEMPLATE))) | ||
412 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
413 | "Cannot write data to plot file `%s'\n", gfn); | ||
414 | |||
415 | for (c_s = 0; c_s < slaves; c_s++) | ||
416 | { | ||
417 | GNUNET_asprintf (&data, "%s" \ | ||
418 | "'%s' using 2:%u with lines title 'BW out master %u - Slave %u ', \\\n" \ | ||
419 | "'%s' using 2:%u with lines title 'BW in master %u - Slave %u '" \ | ||
420 | "%s\n", | ||
421 | (0 == c_s) ? "plot " : "", | ||
422 | fs[c_s], | ||
423 | LOG_ITEMS_TIME + LOG_ITEM_ATS_BW_OUT, | ||
424 | lp->peer->no, c_s, | ||
425 | fs[c_s], | ||
426 | LOG_ITEMS_TIME + LOG_ITEM_ATS_BW_IN, | ||
427 | lp->peer->no, c_s, | ||
428 | (c_s < lp->peer->num_partners - 1) ? ", \\" : | ||
429 | "\n pause -1"); | ||
430 | if (GNUNET_SYSERR == GNUNET_DISK_file_write (f, data, strlen (data))) | ||
431 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
432 | "Cannot write data to plot file `%s'\n", gfn); | ||
433 | GNUNET_free (data); | ||
434 | } | ||
435 | |||
436 | if (GNUNET_SYSERR == GNUNET_DISK_file_close (f)) | ||
437 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot close gnuplot file `%s'\n", | ||
438 | gfn); | ||
439 | else | ||
440 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
441 | "Data successfully written to plot file `%s'\n", gfn); | ||
442 | GNUNET_free (gfn); | ||
443 | } | ||
444 | |||
445 | |||
446 | void | ||
447 | GNUNET_ATS_TEST_logging_write_to_file (struct LoggingHandle *l, | ||
448 | const char *experiment_name, | ||
449 | int plots) | ||
450 | { | ||
451 | struct GNUNET_DISK_FileHandle *f[l->num_slaves]; | ||
452 | struct GNUNET_DISK_FileHandle *f_m; | ||
453 | const char *tmp_exp_name; | ||
454 | char *filename_master; | ||
455 | char *filename_slaves[l->num_slaves]; | ||
456 | char *data; | ||
457 | struct PeerLoggingTimestep *cur_lt; | ||
458 | struct PartnerLoggingTimestep *plt; | ||
459 | struct GNUNET_TIME_Absolute timestamp; | ||
460 | int c_m; | ||
461 | int c_s; | ||
462 | |||
463 | |||
464 | timestamp = GNUNET_TIME_absolute_get (); | ||
465 | |||
466 | tmp_exp_name = experiment_name; | ||
467 | for (c_m = 0; c_m < l->num_masters; c_m++) | ||
468 | { | ||
469 | GNUNET_asprintf (&filename_master, "%s_%llu_master%u_%s", | ||
470 | experiment_name, | ||
471 | (unsigned long long) timestamp.abs_value_us, c_m, l->name); | ||
472 | fprintf (stderr, "Writing data for master %u to file `%s'\n", | ||
473 | c_m, filename_master); | ||
474 | |||
475 | f_m = GNUNET_DISK_file_open (filename_master, | ||
476 | GNUNET_DISK_OPEN_WRITE | ||
477 | | GNUNET_DISK_OPEN_CREATE, | ||
478 | GNUNET_DISK_PERM_USER_READ | ||
479 | | GNUNET_DISK_PERM_USER_WRITE); | ||
480 | if (NULL == f_m) | ||
481 | { | ||
482 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open log file `%s'\n", | ||
483 | filename_master); | ||
484 | GNUNET_free (filename_master); | ||
485 | return; | ||
486 | } | ||
487 | |||
488 | GNUNET_asprintf (&data, "# master %u; experiment : %s\n" | ||
489 | "timestamp; timestamp delta; #messages sent; #bytes sent; #throughput sent; #messages received; #bytes received; #throughput received; \n", | ||
490 | c_m, experiment_name); | ||
491 | if (GNUNET_SYSERR == GNUNET_DISK_file_write (f_m, data, strlen (data))) | ||
492 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
493 | "Cannot write data to log file `%s'\n", filename_master); | ||
494 | GNUNET_free (data); | ||
495 | |||
496 | for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++) | ||
497 | { | ||
498 | GNUNET_asprintf (&filename_slaves[c_s], "%s_%llu_master%u_slave_%u_%s", | ||
499 | tmp_exp_name, | ||
500 | (unsigned long long) timestamp.abs_value_us, | ||
501 | c_m, c_s, l->name); | ||
502 | |||
503 | fprintf (stderr, "Writing data for master %u slave %u to file `%s'\n", | ||
504 | c_m, c_s, filename_slaves[c_s]); | ||
505 | |||
506 | f[c_s] = GNUNET_DISK_file_open (filename_slaves[c_s], | ||
507 | GNUNET_DISK_OPEN_WRITE | ||
508 | | GNUNET_DISK_OPEN_CREATE, | ||
509 | GNUNET_DISK_PERM_USER_READ | ||
510 | | GNUNET_DISK_PERM_USER_WRITE); | ||
511 | if (NULL == f[c_s]) | ||
512 | { | ||
513 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open log file `%s'\n", | ||
514 | filename_slaves[c_s]); | ||
515 | GNUNET_free (filename_slaves[c_s]); | ||
516 | GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (f_m)); | ||
517 | GNUNET_free (filename_master); | ||
518 | return; | ||
519 | } | ||
520 | |||
521 | /* Header */ | ||
522 | GNUNET_asprintf (&data, "# master %u; slave %u ; experiment : %s\n" | ||
523 | "timestamp; timestamp delta; #messages sent; #bytes sent; #throughput sent; #messages received; #bytes received; #throughput received; " \ | ||
524 | "rtt; bw in; bw out; ats_cost_lan; ats_cost_wlan; ats_delay; ats_distance; ats_network_type; ats_utilization_up ;ats_utilization_down;" \ | ||
525 | "pref bandwidth; pref delay\n", | ||
526 | c_m, c_s, experiment_name); | ||
527 | if (GNUNET_SYSERR == GNUNET_DISK_file_write (f[c_s], data, strlen (data))) | ||
528 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
529 | "Cannot write data to log file `%s'\n", | ||
530 | filename_slaves[c_s]); | ||
531 | GNUNET_free (data); | ||
532 | } | ||
533 | |||
534 | for (cur_lt = l->lp[c_m].head; NULL != cur_lt; cur_lt = cur_lt->next) | ||
535 | { | ||
536 | if (l->verbose) | ||
537 | fprintf (stderr, | ||
538 | "Master [%u]: timestamp %llu %llu ; %u %u %u ; %u %u %u\n", | ||
539 | l->lp[c_m].peer->no, | ||
540 | (long long unsigned int) cur_lt->timestamp.abs_value_us, | ||
541 | (long long unsigned int) GNUNET_TIME_absolute_get_difference ( | ||
542 | l->lp[c_m].start, | ||
543 | cur_lt | ||
544 | ->timestamp).rel_value_us / 1000, | ||
545 | cur_lt->total_messages_sent, | ||
546 | cur_lt->total_bytes_sent, | ||
547 | cur_lt->total_throughput_send, | ||
548 | cur_lt->total_messages_received, | ||
549 | cur_lt->total_bytes_received, | ||
550 | cur_lt->total_throughput_recv); | ||
551 | |||
552 | /* Assembling master string */ | ||
553 | GNUNET_asprintf (&data, "%llu;%llu;%u;%u;%u;%u;%u;%u;\n", | ||
554 | (long long unsigned int) cur_lt->timestamp.abs_value_us, | ||
555 | (long long unsigned | ||
556 | int) GNUNET_TIME_absolute_get_difference ( | ||
557 | l->lp[c_m].start, | ||
558 | cur_lt | ||
559 | ->timestamp). | ||
560 | rel_value_us / 1000, | ||
561 | cur_lt->total_messages_sent, | ||
562 | cur_lt->total_bytes_sent, | ||
563 | cur_lt->total_throughput_send, | ||
564 | cur_lt->total_messages_received, | ||
565 | cur_lt->total_bytes_received, | ||
566 | cur_lt->total_throughput_recv); | ||
567 | |||
568 | if (GNUNET_SYSERR == GNUNET_DISK_file_write (f_m, data, strlen (data))) | ||
569 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
570 | "Cannot write data to master file %u\n", c_m); | ||
571 | GNUNET_free (data); | ||
572 | |||
573 | |||
574 | for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++) | ||
575 | { | ||
576 | plt = &cur_lt->slaves_log[c_s]; | ||
577 | /* Log partners */ | ||
578 | |||
579 | /* Assembling slave string */ | ||
580 | GNUNET_asprintf (&data, | ||
581 | "%llu;%llu;%u;%u;%u;%u;%u;%u;%.3f;%u;%u;%llu;%u;%u;%u;%u;%.3f;%.3f\n", | ||
582 | (long long unsigned | ||
583 | int) cur_lt->timestamp.abs_value_us, | ||
584 | (long long unsigned | ||
585 | int) GNUNET_TIME_absolute_get_difference ( | ||
586 | l->lp[c_m].start, | ||
587 | cur_lt | ||
588 | ->timestamp) | ||
589 | .rel_value_us / 1000, | ||
590 | plt->total_messages_sent, | ||
591 | plt->total_bytes_sent, | ||
592 | plt->throughput_sent, | ||
593 | plt->total_messages_received, | ||
594 | plt->total_bytes_received, | ||
595 | plt->throughput_recv, | ||
596 | (double) plt->app_rtt / 1000, | ||
597 | plt->bandwidth_in, | ||
598 | plt->bandwidth_out, | ||
599 | (unsigned long long) plt->ats_delay.rel_value_us, | ||
600 | plt->ats_distance, | ||
601 | plt->ats_network_type, | ||
602 | plt->ats_utilization_out, | ||
603 | plt->ats_utilization_in, | ||
604 | plt->pref_bandwidth, | ||
605 | plt->pref_delay); | ||
606 | |||
607 | if (l->verbose) | ||
608 | fprintf (stderr, | ||
609 | "\t Slave [%u]: %u %u %u ; %u %u %u rtt %u delay %llu bw_in %u bw_out %u \n", | ||
610 | plt->slave->no, | ||
611 | plt->total_messages_sent, | ||
612 | plt->total_bytes_sent, | ||
613 | plt->throughput_sent, | ||
614 | plt->total_messages_received, | ||
615 | plt->total_bytes_received, | ||
616 | plt->throughput_recv, | ||
617 | plt->app_rtt, | ||
618 | (long long unsigned int) plt->ats_delay.rel_value_us, | ||
619 | plt->bandwidth_in, | ||
620 | plt->bandwidth_out); | ||
621 | |||
622 | if (GNUNET_SYSERR == GNUNET_DISK_file_write (f[c_s], data, strlen ( | ||
623 | data))) | ||
624 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
625 | "Cannot write data to log file `%s'\n", | ||
626 | filename_slaves[c_s]); | ||
627 | GNUNET_free (data); | ||
628 | } | ||
629 | } | ||
630 | |||
631 | for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++) | ||
632 | { | ||
633 | if (GNUNET_SYSERR == GNUNET_DISK_file_close (f[c_s])) | ||
634 | { | ||
635 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
636 | "Cannot close log file for master[%u] slave[%u]\n", c_m, | ||
637 | c_s); | ||
638 | continue; | ||
639 | } | ||
640 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
641 | "Data file successfully written to log file for `%s'\n", | ||
642 | filename_slaves[c_s]); | ||
643 | } | ||
644 | |||
645 | if (GNUNET_SYSERR == GNUNET_DISK_file_close (f_m)) | ||
646 | { | ||
647 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, | ||
648 | "close", | ||
649 | filename_master); | ||
650 | GNUNET_free (filename_master); | ||
651 | return; | ||
652 | } | ||
653 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
654 | "Data file successfully written to log file for master `%s'\n", | ||
655 | filename_master); | ||
656 | |||
657 | if (GNUNET_YES == plots) | ||
658 | { | ||
659 | write_throughput_gnuplot_script (filename_master, &l->lp[c_m], | ||
660 | filename_slaves, l->num_slaves); | ||
661 | write_rtt_gnuplot_script (filename_master, &l->lp[c_m], filename_slaves, | ||
662 | l->num_slaves); | ||
663 | write_bw_gnuplot_script (filename_master, &l->lp[c_m], filename_slaves, | ||
664 | l->num_slaves); | ||
665 | } | ||
666 | } | ||
667 | GNUNET_free (filename_master); | ||
668 | } | ||
669 | |||
670 | |||
671 | /** | ||
672 | * Log all data now | ||
673 | * | ||
674 | * @param l logging handle to use | ||
675 | */ | ||
676 | void | ||
677 | GNUNET_ATS_TEST_logging_now (struct LoggingHandle *l) | ||
678 | { | ||
679 | struct LoggingPeer *bp; | ||
680 | struct PeerLoggingTimestep *mlt; | ||
681 | struct PeerLoggingTimestep *prev_log_mlt; | ||
682 | struct PartnerLoggingTimestep *slt; | ||
683 | struct PartnerLoggingTimestep *prev_log_slt; | ||
684 | struct BenchmarkPartner *p; | ||
685 | struct GNUNET_TIME_Relative delta; | ||
686 | int c_s; | ||
687 | int c_m; | ||
688 | unsigned int app_rtt; | ||
689 | double mult; | ||
690 | |||
691 | if (GNUNET_YES != l->running) | ||
692 | return; | ||
693 | |||
694 | for (c_m = 0; c_m < l->num_masters; c_m++) | ||
695 | { | ||
696 | bp = &l->lp[c_m]; | ||
697 | mlt = GNUNET_new (struct PeerLoggingTimestep); | ||
698 | GNUNET_CONTAINER_DLL_insert_tail (l->lp[c_m].head, l->lp[c_m].tail, mlt); | ||
699 | prev_log_mlt = mlt->prev; | ||
700 | |||
701 | /* Collect data */ | ||
702 | /* Current master state */ | ||
703 | mlt->timestamp = GNUNET_TIME_absolute_get (); | ||
704 | mlt->total_bytes_sent = bp->peer->total_bytes_sent; | ||
705 | mlt->total_messages_sent = bp->peer->total_messages_sent; | ||
706 | mlt->total_bytes_received = bp->peer->total_bytes_received; | ||
707 | mlt->total_messages_received = bp->peer->total_messages_received; | ||
708 | |||
709 | /* Throughput */ | ||
710 | if (NULL == prev_log_mlt) | ||
711 | { | ||
712 | /* Get difference to start */ | ||
713 | delta = GNUNET_TIME_absolute_get_difference (l->lp[c_m].start, | ||
714 | mlt->timestamp); | ||
715 | } | ||
716 | else | ||
717 | { | ||
718 | /* Get difference to last timestep */ | ||
719 | delta = GNUNET_TIME_absolute_get_difference (mlt->prev->timestamp, | ||
720 | mlt->timestamp); | ||
721 | } | ||
722 | |||
723 | /* Multiplication factor for throughput calculation */ | ||
724 | mult = (double) GNUNET_TIME_UNIT_SECONDS.rel_value_us | ||
725 | / (delta.rel_value_us); | ||
726 | |||
727 | /* Total throughput */ | ||
728 | if (NULL != prev_log_mlt) | ||
729 | { | ||
730 | if (mlt->total_bytes_sent - mlt->prev->total_bytes_sent > 0) | ||
731 | { | ||
732 | mlt->total_throughput_send = mult * (mlt->total_bytes_sent | ||
733 | - mlt->prev->total_bytes_sent); | ||
734 | } | ||
735 | else | ||
736 | { | ||
737 | mlt->total_throughput_send = 0; | ||
738 | // mlt->total_throughput_send = prev_log_mlt->total_throughput_send; /* no msgs send */ | ||
739 | } | ||
740 | |||
741 | if (mlt->total_bytes_received - mlt->prev->total_bytes_received > 0) | ||
742 | { | ||
743 | mlt->total_throughput_recv = mult * (mlt->total_bytes_received | ||
744 | - mlt->prev->total_bytes_received); | ||
745 | } | ||
746 | else | ||
747 | { | ||
748 | mlt->total_throughput_recv = 0; | ||
749 | // mlt->total_throughput_recv = prev_log_mlt->total_throughput_recv; /* no msgs received */ | ||
750 | } | ||
751 | } | ||
752 | else | ||
753 | { | ||
754 | mlt->total_throughput_send = mult * mlt->total_bytes_sent; | ||
755 | mlt->total_throughput_recv = mult * mlt->total_bytes_received; | ||
756 | } | ||
757 | |||
758 | if (GNUNET_YES == l->verbose) | ||
759 | { | ||
760 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
761 | "Master[%u] delta: %llu us, bytes (sent/received): %u / %u; throughput send/recv: %u / %u\n", | ||
762 | c_m, | ||
763 | (unsigned long long) delta.rel_value_us, | ||
764 | mlt->total_bytes_sent, | ||
765 | mlt->total_bytes_received, | ||
766 | mlt->total_throughput_send, | ||
767 | mlt->total_throughput_recv); | ||
768 | } | ||
769 | |||
770 | mlt->slaves_log = GNUNET_malloc (bp->peer->num_partners | ||
771 | * sizeof(struct PartnerLoggingTimestep)); | ||
772 | |||
773 | for (c_s = 0; c_s < bp->peer->num_partners; c_s++) | ||
774 | { | ||
775 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
776 | "Collect logging data master[%u] slave [%u]\n", c_m, c_s); | ||
777 | |||
778 | p = &bp->peer->partners[c_s]; | ||
779 | slt = &mlt->slaves_log[c_s]; | ||
780 | |||
781 | slt->slave = p->dest; | ||
782 | /* Bytes sent from master to this slave */ | ||
783 | slt->total_bytes_sent = p->bytes_sent; | ||
784 | /* Messages sent from master to this slave */ | ||
785 | slt->total_messages_sent = p->messages_sent; | ||
786 | /* Bytes master received from this slave */ | ||
787 | slt->total_bytes_received = p->bytes_received; | ||
788 | /* Messages master received from this slave */ | ||
789 | slt->total_messages_received = p->messages_received; | ||
790 | slt->total_app_rtt = p->total_app_rtt; | ||
791 | /* ats performance information */ | ||
792 | slt->ats_delay = p->props.delay; | ||
793 | slt->ats_distance = p->props.distance; | ||
794 | slt->ats_network_type = p->props.scope; | ||
795 | slt->ats_utilization_in = p->props.utilization_out; | ||
796 | slt->ats_utilization_out = p->props.utilization_out; | ||
797 | slt->bandwidth_in = p->bandwidth_in; | ||
798 | slt->bandwidth_out = p->bandwidth_out; | ||
799 | slt->pref_bandwidth = p->pref_bandwidth; | ||
800 | slt->pref_delay = p->pref_delay; | ||
801 | |||
802 | /* Total application level rtt */ | ||
803 | if (NULL == prev_log_mlt) | ||
804 | { | ||
805 | if (0 != slt->total_messages_sent) | ||
806 | app_rtt = slt->total_app_rtt / slt->total_messages_sent; | ||
807 | else | ||
808 | app_rtt = 0; | ||
809 | } | ||
810 | else | ||
811 | { | ||
812 | prev_log_slt = &prev_log_mlt->slaves_log[c_s]; | ||
813 | if ((slt->total_messages_sent - prev_log_slt->total_messages_sent) > 0) | ||
814 | app_rtt = (slt->total_app_rtt - prev_log_slt->total_app_rtt) | ||
815 | / (slt->total_messages_sent | ||
816 | - prev_log_slt->total_messages_sent); | ||
817 | else | ||
818 | { | ||
819 | app_rtt = prev_log_slt->app_rtt; /* No messages were */ | ||
820 | } | ||
821 | } | ||
822 | slt->app_rtt = app_rtt; | ||
823 | |||
824 | /* Partner throughput */ | ||
825 | if (NULL != prev_log_mlt) | ||
826 | { | ||
827 | prev_log_slt = &prev_log_mlt->slaves_log[c_s]; | ||
828 | if (slt->total_bytes_sent > prev_log_slt->total_bytes_sent) | ||
829 | slt->throughput_sent = mult * (slt->total_bytes_sent | ||
830 | - prev_log_slt->total_bytes_sent); | ||
831 | else | ||
832 | slt->throughput_sent = 0; | ||
833 | |||
834 | if (slt->total_bytes_received > prev_log_slt->total_bytes_received) | ||
835 | slt->throughput_recv = mult | ||
836 | * (slt->total_bytes_received | ||
837 | - prev_log_slt->total_bytes_received); | ||
838 | else | ||
839 | slt->throughput_recv = 0; | ||
840 | } | ||
841 | else | ||
842 | { | ||
843 | slt->throughput_sent = mult * slt->total_bytes_sent; | ||
844 | slt->throughput_recv = mult * slt->total_bytes_received; | ||
845 | } | ||
846 | |||
847 | if (GNUNET_YES == l->verbose) | ||
848 | { | ||
849 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
850 | "Master [%u] -> Slave [%u]: delta: %llu us, bytes (sent/received): %u / %u; throughput send/recv: %u / %u\n", | ||
851 | c_m, c_s, | ||
852 | (unsigned long long) delta.rel_value_us, | ||
853 | mlt->total_bytes_sent, | ||
854 | mlt->total_bytes_received, | ||
855 | slt->throughput_sent, | ||
856 | slt->throughput_recv); | ||
857 | } | ||
858 | else | ||
859 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
860 | "Master [%u]: slave [%u]\n", | ||
861 | bp->peer->no, p->dest->no); | ||
862 | } | ||
863 | } | ||
864 | } | ||
865 | |||
866 | |||
867 | static void | ||
868 | collect_log_task (void *cls) | ||
869 | { | ||
870 | struct LoggingHandle *l = cls; | ||
871 | |||
872 | l->log_task = NULL; | ||
873 | GNUNET_ATS_TEST_logging_now (l); | ||
874 | l->log_task = GNUNET_SCHEDULER_add_delayed (l->frequency, | ||
875 | &collect_log_task, | ||
876 | l); | ||
877 | } | ||
878 | |||
879 | |||
880 | /** | ||
881 | * Stop logging | ||
882 | * | ||
883 | * @param l the logging handle | ||
884 | */ | ||
885 | void | ||
886 | GNUNET_ATS_TEST_logging_stop (struct LoggingHandle *l) | ||
887 | { | ||
888 | if (GNUNET_YES != l->running) | ||
889 | return; | ||
890 | |||
891 | if (NULL != l->log_task) | ||
892 | { | ||
893 | GNUNET_SCHEDULER_cancel (l->log_task); | ||
894 | l->log_task = NULL; | ||
895 | } | ||
896 | l->running = GNUNET_NO; | ||
897 | |||
898 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
899 | _ ("Stop logging\n")); | ||
900 | } | ||
901 | |||
902 | |||
903 | /** | ||
904 | * Clean up logging data | ||
905 | * | ||
906 | * @param l the logging handle | ||
907 | */ | ||
908 | void | ||
909 | GNUNET_ATS_TEST_logging_clean_up (struct LoggingHandle *l) | ||
910 | { | ||
911 | int c_m; | ||
912 | struct PeerLoggingTimestep *cur; | ||
913 | |||
914 | if (GNUNET_YES == l->running) | ||
915 | GNUNET_ATS_TEST_logging_stop (l); | ||
916 | |||
917 | for (c_m = 0; c_m < l->num_masters; c_m++) | ||
918 | { | ||
919 | while (NULL != (cur = l->lp[c_m].head)) | ||
920 | { | ||
921 | GNUNET_CONTAINER_DLL_remove (l->lp[c_m].head, l->lp[c_m].tail, cur); | ||
922 | GNUNET_free (cur->slaves_log); | ||
923 | GNUNET_free (cur); | ||
924 | } | ||
925 | } | ||
926 | |||
927 | GNUNET_free (l->lp); | ||
928 | GNUNET_free (l); | ||
929 | } | ||
930 | |||
931 | |||
932 | /** | ||
933 | * Start logging | ||
934 | * | ||
935 | * @param log_frequency the logging frequency | ||
936 | * @param testname the testname | ||
937 | * @param masters the master peers used for benchmarking | ||
938 | * @param num_masters the number of master peers | ||
939 | * @param num_slaves the number of slave peers | ||
940 | * @param verbose verbose logging | ||
941 | * @return the logging handle or NULL on error | ||
942 | */ | ||
943 | struct LoggingHandle * | ||
944 | GNUNET_ATS_TEST_logging_start (struct GNUNET_TIME_Relative log_frequency, | ||
945 | const char *testname, | ||
946 | struct BenchmarkPeer *masters, | ||
947 | int num_masters, | ||
948 | int num_slaves, | ||
949 | int verbose) | ||
950 | { | ||
951 | struct LoggingHandle *l; | ||
952 | int c_m; | ||
953 | |||
954 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
955 | _ ("Start logging `%s'\n"), testname); | ||
956 | |||
957 | l = GNUNET_new (struct LoggingHandle); | ||
958 | l->num_masters = num_masters; | ||
959 | l->num_slaves = num_slaves; | ||
960 | l->name = testname; | ||
961 | l->frequency = log_frequency; | ||
962 | l->verbose = verbose; | ||
963 | l->lp = GNUNET_malloc (num_masters * sizeof(struct LoggingPeer)); | ||
964 | |||
965 | for (c_m = 0; c_m < num_masters; c_m++) | ||
966 | { | ||
967 | l->lp[c_m].peer = &masters[c_m]; | ||
968 | l->lp[c_m].start = GNUNET_TIME_absolute_get (); | ||
969 | } | ||
970 | |||
971 | /* Schedule logging task */ | ||
972 | l->log_task = GNUNET_SCHEDULER_add_now (&collect_log_task, l); | ||
973 | l->running = GNUNET_YES; | ||
974 | |||
975 | return l; | ||
976 | } | ||
977 | |||
978 | |||
979 | /* end of file ats-testing-log.c */ | ||