ats-testing-log.c 27 KB

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