perf_ats_logging.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2010-2013 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your 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. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file ats/perf_ats_logging.c
  18. * @brief ats benchmark: logging for performance tests
  19. * @author Christian Grothoff
  20. * @author Matthias Wachs
  21. */
  22. #include "platform.h"
  23. #include "gnunet_util_lib.h"
  24. #include "perf_ats.h"
  25. #define THROUGHPUT_TEMPLATE "#!/usr/bin/gnuplot \n" \
  26. "set datafile separator ';' \n" \
  27. "set title \"Throughput between Master and Slaves\" \n" \
  28. "set xlabel \"Time in ms\" \n" \
  29. "set ylabel \"Bytes/s\" \n" \
  30. "set grid \n"
  31. #define RTT_TEMPLATE "#!/usr/bin/gnuplot \n" \
  32. "set datafile separator ';' \n" \
  33. "set title \"Application level roundtrip time between Master and Slaves\" \n" \
  34. "set xlabel \"Time in ms\" \n" \
  35. "set ylabel \"ms\" \n" \
  36. "set grid \n"
  37. #define BW_TEMPLATE "#!/usr/bin/gnuplot \n" \
  38. "set datafile separator ';' \n" \
  39. "set title \"Bandwidth inbound and outbound between Master and Slaves\" \n" \
  40. "set xlabel \"Time in ms\" \n" \
  41. "set ylabel \"Bytes / s \" \n" \
  42. "set grid \n"
  43. #define LOG_ITEMS_TIME 2
  44. #define LOG_ITEMS_PER_PEER 17
  45. #define LOG_ITEM_BYTES_SENT 1
  46. #define LOG_ITEM_MSGS_SENT 2
  47. #define LOG_ITEM_THROUGHPUT_SENT 3
  48. #define LOG_ITEM_BYTES_RECV 4
  49. #define LOG_ITEM_MSGS_RECV 5
  50. #define LOG_ITEM_THROUGHPUT_RECV 6
  51. #define LOG_ITEM_APP_RTT 7
  52. #define LOG_ITEM_ATS_BW_IN 8
  53. #define LOG_ITEM_ATS_BW_OUT 9
  54. #define LOG_ITEM_ATS_COSTS_LAN 10
  55. #define LOG_ITEM_ATS_WAN 11
  56. #define LOG_ITEM_ATS_WLAN 12
  57. #define LOG_ITEM_ATS_DELAY 13
  58. #define LOG_ITEM_ATS_DISTANCE 14
  59. #define LOG_ITEM_ATS_NETWORKTYPE 15
  60. #define LOG_ITEM_ATS_UTIL_UP 16
  61. #define LOG_ITEM_ATS_UTIL_DOWN 17
  62. /**
  63. * Logging task
  64. */
  65. static struct GNUNET_SCHEDULER_Task * log_task;
  66. /**
  67. * Reference to perf_ats' masters
  68. */
  69. static int num_peers;
  70. static int running;
  71. static char *name;
  72. static struct GNUNET_TIME_Relative frequency;
  73. /**
  74. * A single logging time step for a partner
  75. */
  76. struct PartnerLoggingTimestep {
  77. /**
  78. * Peer
  79. */
  80. struct BenchmarkPeer *slave;
  81. /**
  82. * Total number of messages this peer has sent
  83. */
  84. unsigned int total_messages_sent;
  85. /**
  86. * Total number of bytes this peer has sent
  87. */
  88. unsigned int total_bytes_sent;
  89. /**
  90. * Total number of messages this peer has received
  91. */
  92. unsigned int total_messages_received;
  93. /**
  94. * Total number of bytes this peer has received
  95. */
  96. unsigned int total_bytes_received;
  97. /**
  98. * Total outbound throughput for master in Bytes / s
  99. */
  100. unsigned int throughput_sent;
  101. /**
  102. * Total inbound throughput for master in Bytes / s
  103. */
  104. unsigned int throughput_recv;
  105. /**
  106. * Accumulated RTT for all messages
  107. */
  108. unsigned int total_app_rtt;
  109. /**
  110. * Current application level delay
  111. */
  112. unsigned int app_rtt;
  113. /* Current ATS properties */
  114. uint32_t ats_distance;
  115. uint32_t ats_delay;
  116. uint32_t bandwidth_in;
  117. uint32_t bandwidth_out;
  118. uint32_t ats_utilization_up;
  119. uint32_t ats_utilization_down;
  120. uint32_t ats_network_type;
  121. uint32_t ats_cost_wan;
  122. uint32_t ats_cost_lan;
  123. uint32_t ats_cost_wlan;
  124. };
  125. /**
  126. * A single logging time step for a peer
  127. */
  128. struct PeerLoggingTimestep {
  129. /**
  130. * Next in DLL
  131. */
  132. struct PeerLoggingTimestep *next;
  133. /**
  134. * Prev in DLL
  135. */
  136. struct PeerLoggingTimestep *prev;
  137. /**
  138. * Logging timestamp
  139. */
  140. struct GNUNET_TIME_Absolute timestamp;
  141. /**
  142. * Total number of messages this peer has sent
  143. */
  144. unsigned int total_messages_sent;
  145. /**
  146. * Total number of bytes this peer has sent
  147. */
  148. unsigned int total_bytes_sent;
  149. /**
  150. * Total number of messages this peer has received
  151. */
  152. unsigned int total_messages_received;
  153. /**
  154. * Total number of bytes this peer has received
  155. */
  156. unsigned int total_bytes_received;
  157. /**
  158. * Total outbound throughput for master in Bytes / s
  159. */
  160. unsigned int total_throughput_send;
  161. /**
  162. * Total inbound throughput for master in Bytes / s
  163. */
  164. unsigned int total_throughput_recv;
  165. /**
  166. * Logs for slaves
  167. */
  168. struct PartnerLoggingTimestep *slaves_log;
  169. };
  170. /**
  171. * Entry for a benchmark peer
  172. */
  173. struct LoggingPeer {
  174. /**
  175. * Peer
  176. */
  177. struct BenchmarkPeer *peer;
  178. /**
  179. * Start time
  180. */
  181. struct GNUNET_TIME_Absolute start;
  182. /**
  183. * DLL for logging entries: head
  184. */
  185. struct PeerLoggingTimestep *head;
  186. /**
  187. * DLL for logging entries: tail
  188. */
  189. struct PeerLoggingTimestep *tail;
  190. };
  191. /**
  192. * Log structure of length num_peers
  193. */
  194. static struct LoggingPeer *lp;
  195. static void
  196. write_throughput_gnuplot_script(char * fn, struct LoggingPeer *lp)
  197. {
  198. struct GNUNET_DISK_FileHandle *f;
  199. char * gfn;
  200. char *data;
  201. int c_s;
  202. int peer_index;
  203. GNUNET_asprintf(&gfn, "gnuplot_throughput_%s", fn);
  204. f = GNUNET_DISK_file_open(gfn,
  205. GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE,
  206. GNUNET_DISK_PERM_USER_EXEC | GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
  207. if (NULL == f)
  208. {
  209. GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cannot open gnuplot file `%s'\n", gfn);
  210. GNUNET_free(gfn);
  211. return;
  212. }
  213. /* Write header */
  214. if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, THROUGHPUT_TEMPLATE, strlen(THROUGHPUT_TEMPLATE)))
  215. GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn);
  216. /* Write master data */
  217. peer_index = LOG_ITEMS_TIME;
  218. GNUNET_asprintf(&data, "plot '%s' using 2:%u with lines title 'Master %u send total', \\\n" \
  219. "'%s' using 2:%u with lines title 'Master %u receive total', \\\n",
  220. fn, peer_index + LOG_ITEM_THROUGHPUT_SENT, lp->peer->no,
  221. fn, peer_index + LOG_ITEM_THROUGHPUT_RECV, lp->peer->no);
  222. if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, data, strlen(data)))
  223. GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn);
  224. GNUNET_free(data);
  225. peer_index = LOG_ITEMS_TIME + LOG_ITEMS_PER_PEER;
  226. for (c_s = 0; c_s < lp->peer->num_partners; c_s++)
  227. {
  228. GNUNET_asprintf(&data, "'%s' using 2:%u with lines title 'Master %u - Slave %u send', \\\n" \
  229. "'%s' using 2:%u with lines title 'Master %u - Slave %u receive'%s\n",
  230. fn, peer_index + LOG_ITEM_THROUGHPUT_SENT, lp->peer->no, lp->peer->partners[c_s].dest->no,
  231. fn, peer_index + LOG_ITEM_THROUGHPUT_RECV, lp->peer->no, lp->peer->partners[c_s].dest->no,
  232. (c_s < lp->peer->num_partners - 1) ? ", \\" : "\n pause -1");
  233. if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, data, strlen(data)))
  234. GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn);
  235. GNUNET_free(data);
  236. peer_index += LOG_ITEMS_PER_PEER;
  237. }
  238. if (GNUNET_SYSERR == GNUNET_DISK_file_close(f))
  239. GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cannot close gnuplot file `%s'\n", gfn);
  240. else
  241. GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Data successfully written to plot file `%s'\n", gfn);
  242. GNUNET_free(gfn);
  243. }
  244. static void
  245. write_rtt_gnuplot_script(char * fn, struct LoggingPeer *lp)
  246. {
  247. struct GNUNET_DISK_FileHandle *f;
  248. char * gfn;
  249. char *data;
  250. int c_s;
  251. int index;
  252. GNUNET_asprintf(&gfn, "gnuplot_rtt_%s", fn);
  253. f = GNUNET_DISK_file_open(gfn,
  254. GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE,
  255. GNUNET_DISK_PERM_USER_EXEC | GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
  256. if (NULL == f)
  257. {
  258. GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cannot open gnuplot file `%s'\n", gfn);
  259. GNUNET_free(gfn);
  260. return;
  261. }
  262. /* Write header */
  263. if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, RTT_TEMPLATE, strlen(RTT_TEMPLATE)))
  264. GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn);
  265. index = LOG_ITEMS_TIME + LOG_ITEMS_PER_PEER;
  266. for (c_s = 0; c_s < lp->peer->num_partners; c_s++)
  267. {
  268. GNUNET_asprintf(&data, "%s'%s' using 2:%u with lines title 'Master %u - Slave %u '%s\n",
  269. (0 == c_s) ? "plot " : "",
  270. fn, index + LOG_ITEM_APP_RTT, lp->peer->no, lp->peer->partners[c_s].dest->no,
  271. (c_s < lp->peer->num_partners - 1) ? ", \\" : "\n pause -1");
  272. if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, data, strlen(data)))
  273. GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn);
  274. GNUNET_free(data);
  275. index += LOG_ITEMS_PER_PEER;
  276. }
  277. if (GNUNET_SYSERR == GNUNET_DISK_file_close(f))
  278. GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cannot close gnuplot file `%s'\n", gfn);
  279. else
  280. GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Data successfully written to plot file `%s'\n", gfn);
  281. GNUNET_free(gfn);
  282. }
  283. static void
  284. write_bw_gnuplot_script(char * fn, struct LoggingPeer *lp)
  285. {
  286. struct GNUNET_DISK_FileHandle *f;
  287. char * gfn;
  288. char *data;
  289. int c_s;
  290. int index;
  291. GNUNET_asprintf(&gfn, "gnuplot_bw_%s", fn);
  292. f = GNUNET_DISK_file_open(gfn,
  293. GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE,
  294. GNUNET_DISK_PERM_USER_EXEC | GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
  295. if (NULL == f)
  296. {
  297. GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cannot open gnuplot file `%s'\n", gfn);
  298. GNUNET_free(gfn);
  299. return;
  300. }
  301. /* Write header */
  302. if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, BW_TEMPLATE, strlen(BW_TEMPLATE)))
  303. GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn);
  304. index = LOG_ITEMS_TIME + LOG_ITEMS_PER_PEER;
  305. for (c_s = 0; c_s < lp->peer->num_partners; c_s++)
  306. {
  307. GNUNET_asprintf(&data, "%s" \
  308. "'%s' using 2:%u with lines title 'BW out master %u - Slave %u ', \\\n" \
  309. "'%s' using 2:%u with lines title 'BW in master %u - Slave %u '" \
  310. "%s\n",
  311. (0 == c_s) ? "plot " : "",
  312. fn, index + LOG_ITEM_ATS_BW_OUT, lp->peer->no, lp->peer->partners[c_s].dest->no,
  313. fn, index + LOG_ITEM_ATS_BW_IN, lp->peer->no, lp->peer->partners[c_s].dest->no,
  314. (c_s < lp->peer->num_partners - 1) ? ", \\" : "\n pause -1");
  315. if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, data, strlen(data)))
  316. GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn);
  317. GNUNET_free(data);
  318. index += LOG_ITEMS_PER_PEER;
  319. }
  320. if (GNUNET_SYSERR == GNUNET_DISK_file_close(f))
  321. GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cannot close gnuplot file `%s'\n", gfn);
  322. else
  323. GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Data successfully written to plot file `%s'\n", gfn);
  324. GNUNET_free(gfn);
  325. }
  326. static void
  327. write_to_file()
  328. {
  329. struct GNUNET_DISK_FileHandle *f;
  330. char * filename;
  331. char *data;
  332. char *slave_string;
  333. char *slave_string_tmp;
  334. struct PeerLoggingTimestep *cur_lt;
  335. struct PartnerLoggingTimestep *plt;
  336. int c_m;
  337. int c_s;
  338. for (c_m = 0; c_m < num_peers; c_m++)
  339. {
  340. GNUNET_asprintf(&filename, "%llu_master_%u_%s_%s.data", GNUNET_TIME_absolute_get().abs_value_us,
  341. lp[c_m].peer->no, GNUNET_i2s(&lp[c_m].peer->id), name);
  342. f = GNUNET_DISK_file_open(filename,
  343. GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE,
  344. GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
  345. if (NULL == f)
  346. {
  347. GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cannot open log file `%s'\n", filename);
  348. GNUNET_free(filename);
  349. return;
  350. }
  351. for (cur_lt = lp[c_m].head; NULL != cur_lt; cur_lt = cur_lt->next)
  352. {
  353. GNUNET_log(GNUNET_ERROR_TYPE_INFO,
  354. "Master [%u]: timestamp %llu %llu ; %u %u %u ; %u %u %u\n", lp[c_m].peer->no,
  355. cur_lt->timestamp, GNUNET_TIME_absolute_get_difference(lp[c_m].start, cur_lt->timestamp).rel_value_us / 1000,
  356. cur_lt->total_messages_sent, cur_lt->total_bytes_sent, cur_lt->total_throughput_send,
  357. cur_lt->total_messages_received, cur_lt->total_bytes_received, cur_lt->total_throughput_recv);
  358. slave_string = GNUNET_strdup(";");
  359. for (c_s = 0; c_s < lp[c_m].peer->num_partners; c_s++)
  360. {
  361. plt = &cur_lt->slaves_log[c_s];
  362. /* Log partners */
  363. /* Assembling slave string */
  364. GNUNET_log(GNUNET_ERROR_TYPE_INFO,
  365. "\t Slave [%u]: %u %u %u ; %u %u %u rtt %u delay %u bw_in %u bw_out %u \n", plt->slave->no,
  366. plt->total_messages_sent, plt->total_bytes_sent, plt->throughput_sent,
  367. plt->total_messages_received, plt->total_bytes_received, plt->throughput_recv,
  368. plt->app_rtt, plt->ats_delay,
  369. plt->bandwidth_in, plt->bandwidth_out);
  370. GNUNET_asprintf(&slave_string_tmp, "%s%u;%u;%u;%u;%u;%u;%.3f;%u;%u;%u;%u;%u;%u;%u;%u;%u;%u;", slave_string,
  371. plt->total_messages_sent, plt->total_bytes_sent, plt->throughput_sent,
  372. plt->total_messages_received, plt->total_bytes_received, plt->throughput_sent,
  373. (double)plt->app_rtt / 1000,
  374. plt->bandwidth_in, plt->bandwidth_out,
  375. plt->ats_cost_lan, plt->ats_cost_wan, plt->ats_cost_wlan,
  376. plt->ats_delay, plt->ats_distance, plt->ats_network_type,
  377. plt->ats_utilization_up, plt->ats_utilization_down);
  378. GNUNET_free(slave_string);
  379. slave_string = slave_string_tmp;
  380. }
  381. /* Assembling master string */
  382. GNUNET_asprintf(&data, "%llu;%llu;%u;%u;%u;%u;%u;%u;;;;;;;;;;;%s\n",
  383. cur_lt->timestamp,
  384. GNUNET_TIME_absolute_get_difference(lp[c_m].start, cur_lt->timestamp).rel_value_us / 1000,
  385. cur_lt->total_messages_sent, cur_lt->total_bytes_sent, cur_lt->total_throughput_send,
  386. cur_lt->total_messages_received, cur_lt->total_bytes_received, cur_lt->total_throughput_recv,
  387. slave_string);
  388. GNUNET_free(slave_string);
  389. if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, data, strlen(data)))
  390. GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cannot write data to log file `%s'\n", filename);
  391. GNUNET_free(data);
  392. }
  393. if (GNUNET_SYSERR == GNUNET_DISK_file_close(f))
  394. {
  395. GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cannot close log file `%s'\n", filename);
  396. GNUNET_free(filename);
  397. return;
  398. }
  399. write_throughput_gnuplot_script(filename, lp);
  400. write_rtt_gnuplot_script(filename, lp);
  401. write_bw_gnuplot_script(filename, lp);
  402. GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Data file successfully written to log file `%s'\n", filename);
  403. GNUNET_free(filename);
  404. }
  405. }
  406. void
  407. collect_log_now(void)
  408. {
  409. struct LoggingPeer *bp;
  410. struct PeerLoggingTimestep *mlt;
  411. struct PeerLoggingTimestep *prev_log_mlt;
  412. struct PartnerLoggingTimestep *slt;
  413. struct PartnerLoggingTimestep *prev_log_slt;
  414. struct BenchmarkPartner *p;
  415. struct GNUNET_TIME_Relative delta;
  416. int c_s;
  417. int c_m;
  418. unsigned int app_rtt;
  419. double mult;
  420. if (GNUNET_YES != running)
  421. return;
  422. for (c_m = 0; c_m < num_peers; c_m++)
  423. {
  424. bp = &lp[c_m];
  425. mlt = GNUNET_new(struct PeerLoggingTimestep);
  426. GNUNET_CONTAINER_DLL_insert_tail(bp->head, bp->tail, mlt);
  427. prev_log_mlt = mlt->prev;
  428. /* Collect data */
  429. /* Current master state */
  430. mlt->timestamp = GNUNET_TIME_absolute_get();
  431. mlt->total_bytes_sent = bp->peer->total_bytes_sent;
  432. mlt->total_messages_sent = bp->peer->total_messages_sent;
  433. mlt->total_bytes_received = bp->peer->total_bytes_received;
  434. mlt->total_messages_received = bp->peer->total_messages_received;
  435. /* Throughput */
  436. if (NULL == prev_log_mlt)
  437. {
  438. /* Get difference to start */
  439. delta = GNUNET_TIME_absolute_get_difference(lp[c_m].start, mlt->timestamp);
  440. }
  441. else
  442. {
  443. /* Get difference to last timestep */
  444. delta = GNUNET_TIME_absolute_get_difference(mlt->prev->timestamp, mlt->timestamp);
  445. }
  446. /* Multiplication factor for throughput calculation */
  447. mult = (1.0 * 1000 * 1000) / (delta.rel_value_us);
  448. /* Total throughput */
  449. if (NULL != prev_log_mlt)
  450. {
  451. if (mlt->total_bytes_sent - mlt->prev->total_bytes_sent > 0)
  452. mlt->total_throughput_send = mult * (mlt->total_bytes_sent - mlt->prev->total_bytes_sent);
  453. else
  454. mlt->total_throughput_send = prev_log_mlt->total_throughput_send; /* no msgs send */
  455. if (mlt->total_bytes_received - mlt->prev->total_bytes_received > 0)
  456. mlt->total_throughput_recv = mult * (mlt->total_bytes_received - mlt->prev->total_bytes_received);
  457. else
  458. mlt->total_throughput_recv = prev_log_mlt->total_throughput_recv; /* no msgs received */
  459. }
  460. else
  461. {
  462. mlt->total_throughput_send = mult * mlt->total_bytes_sent;
  463. mlt->total_throughput_send = mult * mlt->total_bytes_received;
  464. }
  465. mlt->slaves_log = GNUNET_malloc(bp->peer->num_partners *
  466. sizeof(struct PartnerLoggingTimestep));
  467. for (c_s = 0; c_s < bp->peer->num_partners; c_s++)
  468. {
  469. p = &bp->peer->partners[c_s];
  470. slt = &mlt->slaves_log[c_s];
  471. slt->slave = p->dest;
  472. /* Bytes sent from master to this slave */
  473. slt->total_bytes_sent = p->bytes_sent;
  474. /* Messages sent from master to this slave */
  475. slt->total_messages_sent = p->messages_sent;
  476. /* Bytes master received from this slave */
  477. slt->total_bytes_received = p->bytes_received;
  478. /* Messages master received from this slave */
  479. slt->total_messages_received = p->messages_received;
  480. slt->total_app_rtt = p->total_app_rtt;
  481. /* ats performance information */
  482. slt->ats_cost_lan = p->ats_cost_lan;
  483. slt->ats_cost_wan = p->ats_cost_wan;
  484. slt->ats_cost_wlan = p->ats_cost_wlan;
  485. slt->ats_delay = p->ats_delay;
  486. slt->ats_distance = p->ats_distance;
  487. slt->ats_network_type = p->ats_network_type;
  488. slt->ats_utilization_down = p->ats_utilization_down;
  489. slt->ats_utilization_up = p->ats_utilization_up;
  490. slt->bandwidth_in = p->bandwidth_in;
  491. slt->bandwidth_out = p->bandwidth_out;
  492. /* Total application level rtt */
  493. if (NULL == prev_log_mlt)
  494. {
  495. if (0 != slt->total_messages_sent)
  496. app_rtt = slt->total_app_rtt / slt->total_messages_sent;
  497. else
  498. app_rtt = 0;
  499. }
  500. else
  501. {
  502. prev_log_slt = &prev_log_mlt->slaves_log[c_s];
  503. if ((slt->total_messages_sent - prev_log_slt->total_messages_sent) > 0)
  504. app_rtt = (slt->total_app_rtt - prev_log_slt->total_app_rtt) /
  505. (slt->total_messages_sent - prev_log_slt->total_messages_sent);
  506. else
  507. app_rtt = prev_log_slt->app_rtt; /* No messages were */
  508. }
  509. slt->app_rtt = app_rtt;
  510. /* Partner throughput */
  511. if (NULL != prev_log_mlt)
  512. {
  513. prev_log_slt = &prev_log_mlt->slaves_log[c_s];
  514. if (slt->total_bytes_sent - prev_log_slt->total_bytes_sent > 0)
  515. slt->throughput_sent = mult * (slt->total_bytes_sent - prev_log_slt->total_bytes_sent);
  516. else
  517. slt->throughput_sent = prev_log_slt->throughput_sent; /* no msgs send */
  518. if (slt->total_bytes_received - prev_log_slt->total_bytes_received > 0)
  519. slt->throughput_recv = mult * (slt->total_bytes_received - prev_log_slt->total_bytes_received);
  520. else
  521. slt->throughput_recv = prev_log_slt->throughput_recv; /* no msgs received */
  522. }
  523. else
  524. {
  525. slt->throughput_sent = mult * slt->total_bytes_sent;
  526. slt->throughput_sent = mult * slt->total_bytes_received;
  527. }
  528. GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
  529. "Master [%u]: slave [%u]\n",
  530. bp->peer->no, p->dest->no);
  531. }
  532. }
  533. }
  534. static void
  535. collect_log_task(void *cls)
  536. {
  537. log_task = NULL;
  538. collect_log_now();
  539. log_task = GNUNET_SCHEDULER_add_delayed(frequency,
  540. &collect_log_task, NULL);
  541. }
  542. void
  543. perf_logging_stop()
  544. {
  545. int c_m;
  546. struct PeerLoggingTimestep *cur;
  547. if (GNUNET_YES != running)
  548. return;
  549. if (NULL != log_task)
  550. {
  551. GNUNET_SCHEDULER_cancel(log_task);
  552. log_task = NULL;
  553. }
  554. collect_log_task(NULL);
  555. GNUNET_log(GNUNET_ERROR_TYPE_INFO,
  556. _("Stop logging\n"));
  557. write_to_file();
  558. for (c_m = 0; c_m < num_peers; c_m++)
  559. {
  560. while (NULL != (cur = lp[c_m].head))
  561. {
  562. GNUNET_CONTAINER_DLL_remove(lp[c_m].head, lp[c_m].tail, cur);
  563. GNUNET_free(cur->slaves_log);
  564. GNUNET_free(cur);
  565. }
  566. }
  567. GNUNET_free(lp);
  568. }
  569. void
  570. perf_logging_start(struct GNUNET_TIME_Relative log_frequency,
  571. char * testname, struct BenchmarkPeer *masters, int num_masters)
  572. {
  573. int c_m;
  574. GNUNET_log(GNUNET_ERROR_TYPE_INFO,
  575. _("Start logging `%s'\n"), testname);
  576. num_peers = num_masters;
  577. name = testname;
  578. frequency = log_frequency;
  579. lp = GNUNET_malloc(num_masters * sizeof(struct LoggingPeer));
  580. for (c_m = 0; c_m < num_masters; c_m++)
  581. {
  582. lp[c_m].peer = &masters[c_m];
  583. lp[c_m].start = GNUNET_TIME_absolute_get();
  584. }
  585. /* Schedule logging task */
  586. log_task = GNUNET_SCHEDULER_add_now(&collect_log_task, NULL);
  587. running = GNUNET_YES;
  588. }
  589. /* end of file perf_ats_logging.c */