log.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. <?php
  2. $path='log';
  3. $lines = array();
  4. $peers = array();
  5. $comps = array();
  6. $ajax = FALSE;
  7. $colors = array('#F00', '#F80', '#FF0',
  8. '#4F0', '#0A0',
  9. '#22F', '#ADF', '#0FF', '#F0F', '#508', '#FAA',
  10. '#FFF', '#AAA', '#666', '#222');
  11. function render_row ($d, $component, $pid, $level, $msg, $c)
  12. {
  13. global $ajax;
  14. global $peers;
  15. if (!$ajax && $level == "DEBUG")
  16. return;
  17. list($comp,$peer) = explode (',', preg_replace ('/(.*)-(\d*)/', '\1,\2', $component));
  18. $peer = array_key_exists ($peer, $peers) ? $peers[$peer] : $peer;
  19. $date = $d ? $d->format('Y-m-d'). $d->format('H:i:s') : "";
  20. echo "<tr class=\"$level P-$peer C-$comp\" id=\"$c\">";
  21. echo "<td class=\"date\"><small>$date</td>";
  22. echo '<td class="usec"><small>';
  23. echo $d ? $d->format('u') : "";
  24. echo '</small></td>';
  25. echo "<td class=\"comp\">$comp</td><td class=\"peer\">$peer</td>";
  26. echo "<td class=\"level\">$level</td><td><pre>$msg</pre></td>";
  27. if ($level != "DEBUG")
  28. {
  29. echo '<td><div class="btn-group"><button class="btn btn-xs btn-default btn-showup"><span class="glyphicon glyphicon-chevron-up"></span></button>';
  30. echo '<button class="btn btn-xs btn-default btn-showdown"><span class="glyphicon glyphicon-chevron-down"></span></button></div></td>';
  31. }
  32. else
  33. echo '<td></td>';
  34. echo '</tr>';
  35. }
  36. function render_rows ()
  37. {
  38. global $lines;
  39. foreach ($lines as $line) {
  40. render_row ($line[0], $line[1], $line[2], $line[3], $line[4], $line[5]);
  41. }
  42. }
  43. function process ($line, $c)
  44. {
  45. global $lines;
  46. global $peers;
  47. global $comps;
  48. $a = explode (' ', $line);
  49. if (count($a) < 6)
  50. return;
  51. $date = DateTime::createFromFormat ("M d H:i:s-u", implode (' ', array_slice ($a, 0, 3)));
  52. $component = $a[3];
  53. $level = $a[4];
  54. $msg = implode (' ', array_slice ($a, 5));
  55. if (FALSE !== strpos($line, "STARTING SERVICE")) {
  56. $id = preg_replace ("/.*\[(....)\].*\n/", '\1', $line);
  57. $pid = preg_replace ("/.*[a-z-]*-([0-9]*).*\n/", '\1', $line);
  58. $peers[$pid] = $id;
  59. }
  60. $lines[] = array ($date, $component, 0, $level, $msg, $c);
  61. $comp = preg_replace ('/(.*)-\d*/', '\1', $component);
  62. $comps[$comp] = 1;
  63. }
  64. if (array_key_exists ('a', $_GET)) {
  65. $start = (int)$_GET['a'];
  66. $ajax= TRUE;
  67. }
  68. else
  69. {
  70. $start = null;
  71. }
  72. if (array_key_exists ('z', $_GET)) {
  73. $stop = (int)$_GET['z'];
  74. $ajax= TRUE;
  75. }
  76. else
  77. {
  78. $stop = null;
  79. }
  80. $t0 = microtime(true);
  81. $handle = @fopen($path, 'r');
  82. if ($handle) {
  83. $c = 0;
  84. while (($line = fgets($handle)) !== false) {
  85. if (!$start || $c >= $start) {
  86. process ($line, $c);
  87. }
  88. $c++;
  89. if ($stop && $c > $stop)
  90. break;
  91. }
  92. } else {
  93. echo "<div class=\"alert alert-danger\">Error opening file $path.</div>";
  94. }
  95. $t1 = microtime(true);
  96. /* Ajax request: don't render container HTML, just table rows. */
  97. if ($start !== null || $stop !== null) {
  98. render_rows();
  99. die();
  100. }
  101. // echo $t1-$t0;
  102. ksort($peers);
  103. ksort($comps);
  104. ?>
  105. <!DOCTYPE html>
  106. <html lang="en">
  107. <head>
  108. <meta charset="utf-8">
  109. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  110. <meta name="viewport" content="width=device-width, initial-scale=1">
  111. <title>GNUnet log view</title>
  112. <!-- Latest compiled and minified Bootstrap CSS -->
  113. <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css">
  114. <!-- Optional theme -->
  115. <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap-theme.min.css">
  116. <style>
  117. body {
  118. font-family: arial,sans-serif;
  119. }
  120. table {
  121. color:#000;
  122. margin-top: 40px;
  123. font-size:12px;
  124. border-collapse:collapse;
  125. }
  126. pre {
  127. padding: 0px;
  128. margin: 0px;
  129. border: 0px;
  130. background-color: transparent;
  131. }
  132. .alert {
  133. display: none;
  134. position: fixed;
  135. width: 75%;
  136. left: 50%;
  137. margin: 5% 0 0 -37.5%;
  138. }
  139. .btn-toolbar {
  140. position: fixed;
  141. top: 0px;
  142. }
  143. .btn-xs {
  144. font-size: 9px;
  145. padding: 0 5px;
  146. }
  147. .level {
  148. display: none;
  149. }
  150. .DEBUG {
  151. background-color:#CCC;
  152. }
  153. .WARNING {
  154. background-color:#EB9316;
  155. }
  156. .ERROR {
  157. background-color:#D2322D;
  158. }
  159. .btn-group {
  160. min-width: 48px;
  161. }
  162. table.table tbody tr td,
  163. table.table tbody th td {
  164. padding: 0px 0px 0px 2px;
  165. margin-bottom: 0px;
  166. }
  167. <?php
  168. $c = 0;
  169. foreach ($peers as $peer) {
  170. echo "table.table tbody tr.P-$peer td.peer {\n";
  171. echo ' background-color: ' . $colors[$c] . ";\n";
  172. echo "}\n";
  173. echo "#P-$peer { color: " . $colors[$c++] . "}\n";
  174. } ?>
  175. </style>
  176. </head>
  177. <body>
  178. <div class="btn-toolbar" role="toolbar">
  179. <div class="btn-group">
  180. <button id="ERROR" class="btn btn-danger btn-showlevel"><span class="glyphicon glyphicon-fire"></span> Error</button>
  181. <button id="WARNING" class="btn btn-warning btn-showlevel"><span class="glyphicon glyphicon-exclamation-sign"></span> Warning</button>
  182. <button id="INFO" class="btn btn-default btn-showlevel active"><span class="glyphicon glyphicon glyphicon-info-sign"></span> Info</button>
  183. <button id="DEBUG" class="btn btn-primary btn-showlevel"><span class="glyphicon glyphicon glyphicon-wrench"></span> Debug</button>
  184. </div>
  185. <div id="btn-showpeer" class="btn-group">
  186. <?php foreach($peers as $pid=>$id): ?>
  187. <button id="P-<?php echo $id ?>" class="btn btn-default btn-element active"><?php echo $id ?></button>
  188. <?php endforeach ?>
  189. <button class="btn btn-default btn-showall">All</button>
  190. <button class="btn btn-default btn-shownone">None</button>
  191. </div>
  192. <div id="btn-showcomp" class="btn-group">
  193. <?php foreach($comps as $c=>$one): ?>
  194. <button id="C-<?php echo $c ?>" class="btn btn-default btn-element active"><?php echo $c ?></button>
  195. <?php endforeach ?>
  196. <button class="btn btn-default btn-showall">All</button>
  197. <button class="btn btn-default btn-shownone">None</button>
  198. </div>
  199. </div>
  200. <div id="msg" class="alert alert-success"></div>
  201. <table class="table">
  202. <thead>
  203. <tr>
  204. <th>Date Time</th>
  205. <th>uSec</th>
  206. <th>Comp</th>
  207. <th>Peer</th>
  208. <th class="level">Level</th>
  209. <th>Message</th>
  210. <th></th>
  211. </tr>
  212. </thead>
  213. <tbody>
  214. <?php render_rows(); ?>
  215. </tbody>default
  216. </table>
  217. <p>Processed in <?php echo $t1-$t0; ?> seconds.</p>
  218. <p>Rendered in <?php echo microtime(true)-$t1; ?> seconds.</p>
  219. <!-- jQuery -->
  220. <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
  221. <!-- Latest compiled and minified Bootstrap JavaScript -->
  222. <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.0/js/bootstrap.min.js"></script>
  223. <script>
  224. var types = ["ERROR", "WARNING", "INFO", "DEBUG"];
  225. var peers = {<?php foreach($peers as $pid=>$id) echo "'$pid': '$id', "; ?>};
  226. var msg_timeout;
  227. function msg (content)
  228. {
  229. $("#msg").html(content);
  230. $("#msg").stop(true);
  231. $("#msg").fadeTo(100, 1).fadeTo(3000, 0.90).fadeOut(1000);
  232. }
  233. function showlevel (level)
  234. {
  235. $("tbody > tr").hide();
  236. $(".btn-showlevel").removeClass("active");
  237. $("#"+level).addClass("active");
  238. for (var index = 0; index < types.length; ++index) {
  239. $("#btn-showpeer > .btn-element.active").each(function(){
  240. var peer = this.id;
  241. $("#btn-showcomp > .btn-element.active").each(function(){
  242. $("."+types[index]+"."+peer+"."+this.id).show();
  243. });
  244. });
  245. if (types[index] == level)
  246. return;
  247. }
  248. }
  249. function shownone(btn)
  250. {
  251. $(btn).parents(".btn-group").children(".btn-element.active").each(function(){$(this).click()});
  252. }
  253. function showall(btn)
  254. {
  255. $(btn).parents(".btn-group").children(".btn-element:not(.active)").each(function(){$(this).click()});
  256. }
  257. function showpeer (peer)
  258. {
  259. $("#"+peer).toggleClass("active");
  260. if ($("#"+peer).hasClass("active")) {
  261. $("#btn-showcomp > .btn-element.active").each(function(){
  262. for (var index = 0; index < types.length; ++index) {
  263. var className = "." + types[index] + "." + peer + "." + this.id;
  264. $(className).show();
  265. if ($("#"+types[index]).hasClass("active"))
  266. return;
  267. }
  268. });
  269. } else {
  270. $("."+peer).hide();
  271. }
  272. }
  273. function showcomp (comp)
  274. {
  275. $("#"+comp).toggleClass("active");
  276. if ($("#"+comp).hasClass("active")) {
  277. $("#btn-showpeer > .btn-element.active").each(function(){
  278. for (var index = 0; index < types.length; ++index) {
  279. var className = "." + types[index] + "." + comp + "." + this.id;
  280. $(className).show();
  281. if ($("#"+types[index]).hasClass("active"))
  282. return;
  283. }
  284. });
  285. } else {
  286. $("."+comp).hide();
  287. }
  288. }
  289. function load_debug (btn, up)
  290. {
  291. var tr = $(btn).parents("tr");
  292. var level;
  293. var pos = parseInt(tr.attr("id"));
  294. var first = pos + 1;
  295. var last = pos - 1;
  296. for (var index = 0; index < types.length; ++index) {
  297. if (tr.hasClass(types[index]))
  298. {
  299. level = types[index];
  300. break;
  301. }
  302. }
  303. if (up) {
  304. if (parseInt(tr.prev().attr("id")) == last) {
  305. msg ("Already loaded");
  306. return;
  307. }
  308. first = parseInt(tr.prevAll("."+level).first().attr("id")) + 1;
  309. first = isNaN(first) ? 0 : first;
  310. } else {
  311. if (parseInt(tr.next().attr("id")) == first) {
  312. msg ("Already loaded");
  313. return;
  314. }
  315. last = parseInt(tr.nextAll("."+level).first().attr("id")) - 1;
  316. }
  317. if (first > last)
  318. return;
  319. $.ajax({
  320. url: document.location,
  321. data: { a: first, z: last }
  322. }).done(function ( resp ) {
  323. var loc = $("#"+(first-1));
  324. var trs = $(resp);
  325. for (var peer in peers) {
  326. trs.filter(".P-"+peer).removeClass('P-'+peer).addClass('P-'+peers[peer]).find("td.peer").html(peers[peer]);
  327. }
  328. if (loc.length > 0)
  329. loc.after(trs);
  330. else {
  331. $("#"+(last+1)).before(trs);
  332. }
  333. msg("Done loading " + (last-first+1) + " lines.");
  334. });
  335. //tr.nextUntil("."+tr.attr("class")).show();
  336. }
  337. function hide (btn)
  338. {
  339. var tr = $(btn).parents("tr");
  340. tr.nextUntil("."+tr.attr("class")).hide();
  341. }
  342. $(function() {
  343. $(".btn-showup").on ("click", function(){ load_debug(this, true) });
  344. $(".btn-showdown").on ("click", function(){ load_debug(this, false) });
  345. $(".btn-showlevel").on ("click", function(){ showlevel(this.id) });
  346. $("#btn-showpeer > .btn-element").on ("click", function(){ showpeer(this.id) });
  347. $("#btn-showcomp > .btn-element").on ("click", function(){ showcomp(this.id) });
  348. $(".btn-showall").on ("click", function(){ showall(this) });
  349. $(".btn-shownone").on ("click", function(){ shownone(this) });
  350. });
  351. </script>
  352. </body>
  353. </html>