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