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