diff options
Diffstat (limited to 'contrib/web/log.php')
-rw-r--r-- | contrib/web/log.php | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/contrib/web/log.php b/contrib/web/log.php new file mode 100644 index 0000000000..b2ca9ed6cd --- /dev/null +++ b/contrib/web/log.php @@ -0,0 +1,379 @@ +<?php + +$path='log'; +$lines = array(); +$peers = array(); +$comps = array(); +$ajax = FALSE; +$colors = array('#F00', '#F80', '#FF0', + '#4F0', '#0A0', + '#22F', '#ADF', '#0FF', '#F0F', '#508', '#FAA', + '#FFF', '#AAA', '#666', '#222'); + +function render_row ($d, $component, $pid, $level, $msg, $c) +{ + global $ajax; + global $peers; + if (!$ajax && $level == "DEBUG") + return; + + list($comp,$peer) = explode (',', preg_replace ('/(.*)-(\d*)/', '\1,\2', $component)); + $peer = array_key_exists ($peer, $peers) ? $peers[$peer] : $peer; + $date = $d ? $d->format('Y-m-d'). $d->format('H:i:s') : ""; + echo "<tr class=\"$level P-$peer C-$comp\" id=\"$c\">"; + echo "<td class=\"date\"><small>$date</td>"; + echo '<td class="usec"><small>'; + echo $d ? $d->format('u') : ""; + echo '</small></td>'; + echo "<td class=\"comp\">$comp</td><td class=\"peer\">$peer</td>"; + echo "<td class=\"level\">$level</td><td><pre>$msg</pre></td>"; + if ($level != "DEBUG") + { + echo '<td><div class="btn-group"><button class="btn btn-xs btn-default btn-showup"><span class="glyphicon glyphicon-chevron-up"></span></button>'; + echo '<button class="btn btn-xs btn-default btn-showdown"><span class="glyphicon glyphicon-chevron-down"></span></button></div></td>'; + } + else + echo '<td></td>'; + echo '</tr>'; +} + +function render_rows () +{ + global $lines; + foreach ($lines as $line) { + render_row ($line[0], $line[1], $line[2], $line[3], $line[4], $line[5]); + } +} + +function process ($line, $c) +{ + global $lines; + global $peers; + global $comps; + $a = explode (' ', $line); + if (count($a) < 6) + return; + $date = DateTime::createFromFormat ("M d H:i:s-u", implode (' ', array_slice ($a, 0, 3))); + $component = $a[3]; + $level = $a[4]; + $msg = implode (' ', array_slice ($a, 5)); + + if (FALSE !== strpos($line, "STARTING SERVICE")) { + $id = preg_replace ("/.*\[(....)\].*\n/", '\1', $line); + $pid = preg_replace ("/.*[a-z-]*-([0-9]*).*\n/", '\1', $line); + $peers[$pid] = $id; + } + + $lines[] = array ($date, $component, 0, $level, $msg, $c); + $comp = preg_replace ('/(.*)-\d*/', '\1', $component); + $comps[$comp] = 1; +} + +if (array_key_exists ('a', $_GET)) { + $start = (int)$_GET['a']; + $ajax= TRUE; +} +else +{ + $start = null; +} +if (array_key_exists ('z', $_GET)) { + $stop = (int)$_GET['z']; + $ajax= TRUE; +} +else +{ + $stop = null; +} +$t0 = microtime(true); +$handle = @fopen($path, 'r'); +if ($handle) { + $c = 0; + while (($line = fgets($handle)) !== false) { + if (!$start || $c >= $start) { + process ($line, $c); + } + $c++; + if ($stop && $c > $stop) + break; + } +} else { + echo "<div class=\"alert alert-danger\">Error opening file $path.</div>"; +} + +$t1 = microtime(true); +/* Ajax request: don't render container HTML, just table rows. */ +if ($start !== null || $stop !== null) { + render_rows(); + die(); +} +// echo $t1-$t0; +ksort($peers); +ksort($comps); +?> +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + + <title>GNUnet log view</title> + + <!-- Latest compiled and minified Bootstrap CSS --> + <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css"> + <!-- Optional theme --> + <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap-theme.min.css"> + + <style> + body { + font-family: arial,sans-serif; + } + table { + color:#000; + margin-top: 40px; + font-size:12px; + border-collapse:collapse; + } + pre { + padding: 0px; + margin: 0px; + border: 0px; + background-color: transparent; + } + .alert { + display: none; + position: fixed; + width: 75%; + left: 50%; + margin: 5% 0 0 -37.5%; + } + .btn-toolbar { + position: fixed; + top: 0px; + } + .btn-xs { + font-size: 9px; + padding: 0 5px; + } + .level { + display: none; + } + .DEBUG { + background-color:#CCC; + } + .WARNING { + background-color:#EB9316; + } + .ERROR { + background-color:#D2322D; + } + .btn-group { + min-width: 48px; + } + table.table tbody tr td, + table.table tbody th td { + padding: 0px 0px 0px 2px; + margin-bottom: 0px; + } +<?php + $c = 0; + foreach ($peers as $peer) { + echo "table.table tbody tr.P-$peer td.peer {\n"; + echo ' background-color: ' . $colors[$c] . ";\n"; + echo "}\n"; + echo "#P-$peer { color: " . $colors[$c++] . "}\n"; + } ?> + </style> +</head> + + +<body> +<div class="btn-toolbar" role="toolbar"> + <div class="btn-group"> + <button id="ERROR" class="btn btn-danger btn-showlevel"><span class="glyphicon glyphicon-fire"></span> Error</button> + <button id="WARNING" class="btn btn-warning btn-showlevel"><span class="glyphicon glyphicon-exclamation-sign"></span> Warning</button> + <button id="INFO" class="btn btn-default btn-showlevel active"><span class="glyphicon glyphicon glyphicon-info-sign"></span> Info</button> + <button id="DEBUG" class="btn btn-primary btn-showlevel"><span class="glyphicon glyphicon glyphicon-wrench"></span> Debug</button> + </div> + <div id="btn-showpeer" class="btn-group"> + <?php foreach($peers as $pid=>$id): ?> + <button id="P-<?php echo $id ?>" class="btn btn-default btn-element active"><?php echo $id ?></button> + <?php endforeach ?> + <button class="btn btn-default btn-showall">All</button> + <button class="btn btn-default btn-shownone">None</button> + </div> + <div id="btn-showcomp" class="btn-group"> + <?php foreach($comps as $c=>$one): ?> + <button id="C-<?php echo $c ?>" class="btn btn-default btn-element active"><?php echo $c ?></button> + <?php endforeach ?> + <button class="btn btn-default btn-showall">All</button> + <button class="btn btn-default btn-shownone">None</button> + </div> +</div> +<div id="msg" class="alert alert-success"></div> +<table class="table"> + <thead> + <tr> + <th>Date Time</th> + <th>uSec</th> + <th>Comp</th> + <th>Peer</th> + <th class="level">Level</th> + <th>Message</th> + <th></th> + </tr> + </thead> + <tbody> +<?php render_rows(); ?> + </tbody>default +</table> +<p>Processed in <?php echo $t1-$t0; ?> seconds.</p> +<p>Rendered in <?php echo microtime(true)-$t1; ?> seconds.</p> + <!-- jQuery --> + <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> + <!-- Latest compiled and minified Bootstrap JavaScript --> + <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.0/js/bootstrap.min.js"></script> + + <script> + + var types = ["ERROR", "WARNING", "INFO", "DEBUG"]; + var peers = {<?php foreach($peers as $pid=>$id) echo "'$pid': '$id', "; ?>}; + var msg_timeout; + + function msg (content) + { + $("#msg").html(content); + $("#msg").stop(true); + $("#msg").fadeTo(100, 1).fadeTo(3000, 0.90).fadeOut(1000); + } + + function showlevel (level) + { + $("tbody > tr").hide(); + $(".btn-showlevel").removeClass("active"); + $("#"+level).addClass("active"); + for (var index = 0; index < types.length; ++index) { + $("#btn-showpeer > .btn-element.active").each(function(){ + var peer = this.id; + $("#btn-showcomp > .btn-element.active").each(function(){ + $("."+types[index]+"."+peer+"."+this.id).show(); + }); + }); + if (types[index] == level) + return; + } + } + + function shownone(btn) + { + $(btn).parents(".btn-group").children(".btn-element.active").each(function(){$(this).click()}); + } + + function showall(btn) + { + $(btn).parents(".btn-group").children(".btn-element:not(.active)").each(function(){$(this).click()}); + } + + function showpeer (peer) + { + $("#"+peer).toggleClass("active"); + if ($("#"+peer).hasClass("active")) { + $("#btn-showcomp > .btn-element.active").each(function(){ + for (var index = 0; index < types.length; ++index) { + var className = "." + types[index] + "." + peer + "." + this.id; + $(className).show(); + if ($("#"+types[index]).hasClass("active")) + return; + } + }); + } else { + $("."+peer).hide(); + } + } + + function showcomp (comp) + { + $("#"+comp).toggleClass("active"); + if ($("#"+comp).hasClass("active")) { + $("#btn-showpeer > .btn-element.active").each(function(){ + for (var index = 0; index < types.length; ++index) { + var className = "." + types[index] + "." + comp + "." + this.id; + $(className).show(); + if ($("#"+types[index]).hasClass("active")) + return; + } + }); + } else { + $("."+comp).hide(); + } + } + + function load_debug (btn, up) + { + var tr = $(btn).parents("tr"); + var level; + var pos = parseInt(tr.attr("id")); + var first = pos + 1; + var last = pos - 1; + for (var index = 0; index < types.length; ++index) { + if (tr.hasClass(types[index])) + { + level = types[index]; + break; + } + } + if (up) { + if (parseInt(tr.prev().attr("id")) == last) { + msg ("Already loaded"); + return; + } + first = parseInt(tr.prevAll("."+level).first().attr("id")) + 1; + first = isNaN(first) ? 0 : first; + } else { + if (parseInt(tr.next().attr("id")) == first) { + msg ("Already loaded"); + return; + } + last = parseInt(tr.nextAll("."+level).first().attr("id")) - 1; + } + if (first > last) + return; + $.ajax({ + url: document.location, + data: { a: first, z: last } + }).done(function ( resp ) { + var loc = $("#"+(first-1)); + var trs = $(resp); + for (var peer in peers) { + trs.filter(".P-"+peer).removeClass('P-'+peer).addClass('P-'+peers[peer]).find("td.peer").html(peers[peer]); + } + if (loc.length > 0) + loc.after(trs); + else { + $("#"+(last+1)).before(trs); + } + msg("Done loading " + (last-first+1) + " lines."); + }); + //tr.nextUntil("."+tr.attr("class")).show(); + + } + + function hide (btn) + { + var tr = $(btn).parents("tr"); + tr.nextUntil("."+tr.attr("class")).hide(); + } + + $(function() { + $(".btn-showup").on ("click", function(){ load_debug(this, true) }); + $(".btn-showdown").on ("click", function(){ load_debug(this, false) }); + $(".btn-showlevel").on ("click", function(){ showlevel(this.id) }); + $("#btn-showpeer > .btn-element").on ("click", function(){ showpeer(this.id) }); + $("#btn-showcomp > .btn-element").on ("click", function(){ showcomp(this.id) }); + $(".btn-showall").on ("click", function(){ showall(this) }); + $(".btn-shownone").on ("click", function(){ shownone(this) }); + }); + </script> +</body> +</html> |