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