Finished top crashers stat page
This commit is contained in:
@@ -17,6 +17,101 @@ Layout::header();
|
|||||||
$filter->render();
|
$filter->render();
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
var tag = $("<div></div>");
|
||||||
|
var $dialog = tag.dialog({
|
||||||
|
autoOpen: false,
|
||||||
|
show: 100,
|
||||||
|
hide: 50,
|
||||||
|
resizable: false,
|
||||||
|
minHeight: 0,
|
||||||
|
});
|
||||||
|
$(".ui-dialog-titlebar-close", $dialog.parent()).hide();
|
||||||
|
$dialog.css('padding','0px 0px 0px 4px');
|
||||||
|
|
||||||
|
var sumbmitted = [];
|
||||||
|
var data = [];
|
||||||
|
|
||||||
|
$(".rowhighlight").each(function() {
|
||||||
|
var $link = $(this);
|
||||||
|
var id = $link.data("id");
|
||||||
|
var signature_id = $link.data("signature-id");
|
||||||
|
|
||||||
|
function setDialog(report_id) {
|
||||||
|
if (data[report_id]) {
|
||||||
|
tag.html(data[report_id]);
|
||||||
|
} else {
|
||||||
|
if (!sumbmitted[report_id])
|
||||||
|
{
|
||||||
|
sumbmitted[report_id] = true;
|
||||||
|
tag.html("Loading ...");
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "report_tip.php?id=" + id + "&signature_id=" + signature_id,
|
||||||
|
success: function(res){
|
||||||
|
data[report_id] = res;
|
||||||
|
tag.html(res);
|
||||||
|
},
|
||||||
|
error: function(){
|
||||||
|
sumbmitted[report_id] = false;
|
||||||
|
tag.html("Failed to fetch data");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function getPos(e) {
|
||||||
|
var x = e.pageX;
|
||||||
|
var dwidth = $dialog.dialog("option", "width");
|
||||||
|
if (x < $(window).width() - dwidth - 40) {
|
||||||
|
x += 15;
|
||||||
|
} else {
|
||||||
|
x -= dwidth + 40;
|
||||||
|
}
|
||||||
|
|
||||||
|
var y = e.pageY + $(document).scrollTop();
|
||||||
|
var dheight = $dialog.height();
|
||||||
|
if (dheight < 40) dheight = 40;
|
||||||
|
//console.debug("y=" + y + "; wheight=" + $(window).height() + ": dheight=" + dheight);
|
||||||
|
if (y < $(window).height() - dheight - 40)
|
||||||
|
{
|
||||||
|
y += 15;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
y -= dheight + 40;
|
||||||
|
}
|
||||||
|
return [x, y];
|
||||||
|
};
|
||||||
|
|
||||||
|
$link.on("mouseenter", function(e) {
|
||||||
|
setDialog($link.data("id"));
|
||||||
|
$dialog.dialog("option","position", getPos(e));
|
||||||
|
$dialog.dialog("option","title", "Crash signature " + signature_id);
|
||||||
|
$link.delay(300).queue(function() {
|
||||||
|
if (!$dialog.dialog("isOpen"))
|
||||||
|
{
|
||||||
|
$dialog.dialog("open");
|
||||||
|
}
|
||||||
|
$link.dequeue();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$link.on("mousemove", function(e) {
|
||||||
|
//console.debug(e.x);
|
||||||
|
$dialog.dialog("option","position", getPos(e));
|
||||||
|
});
|
||||||
|
$link.on("mouseleave", function() {
|
||||||
|
$link.clearQueue();
|
||||||
|
if ($dialog.dialog("isOpen"))
|
||||||
|
{
|
||||||
|
$dialog.dialog("close");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
<p>Reports <strong><?php echo $total ?></strong></p>
|
<p>Reports <strong><?php echo $total ?></strong></p>
|
||||||
|
|
||||||
<table width="100%" class="jtable">
|
<table width="100%" class="jtable">
|
||||||
@@ -26,14 +121,16 @@ $filter->render();
|
|||||||
<th>Operating System</th>
|
<th>Operating System</th>
|
||||||
<th>GPU</th>
|
<th>GPU</th>
|
||||||
<th>Grid (region)</th>
|
<th>Grid (region)</th>
|
||||||
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
<?php for ($i=0; $i<count($reports); $i++): ?>
|
<?php for ($i=0; $i<count($reports); $i++): ?>
|
||||||
<tr class="rowhighlight">
|
<tr class="rowhighlight" data-signature-id="<?php echo $reports[$i]->signature_id ?>" data-id="<?php echo $reports[$i]->id ?>">
|
||||||
<td><?php lk($reports[$i]->id, $reports[$i]->id) ?></td>
|
<td><?php lk($reports[$i]->id, $reports[$i]->id) ?></td>
|
||||||
<td><?php lk($reports[$i]->id, $reports[$i]->client_channel . " " . $reports[$i]->client_version) ?></td>
|
<td><?php lk($reports[$i]->id, $reports[$i]->client_channel . " " . $reports[$i]->client_version) ?></td>
|
||||||
<td><?php lk($reports[$i]->id, $reports[$i]->os) ?></td>
|
<td><?php lk($reports[$i]->id, $reports[$i]->os) ?></td>
|
||||||
<td><?php lk($reports[$i]->id, $reports[$i]->gpu) ?></td>
|
<td><?php lk($reports[$i]->id, $reports[$i]->gpu) ?></td>
|
||||||
<td><?php lk($reports[$i]->id, $reports[$i]->grid . " (" . $reports[$i]->region . ")") ?></td>
|
<td><?php lk($reports[$i]->id, $reports[$i]->grid . " (" . $reports[$i]->region . ")") ?></td>
|
||||||
|
<td style="text-align: right"><a href="<?php echo URL_ROOT . "/crashes.php?signature_id=" . $reports[$i]->signature_id ?>">Similar</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endfor ?>
|
<?php endfor ?>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ class CrashReport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getReports($filter, $fields = "id, reported, client_version, client_channel, os, gpu, grid, region")
|
function getReports($filter, $fields = "id, reported, client_version, client_channel, os, gpu, grid, region, signature_id")
|
||||||
{
|
{
|
||||||
$ret = array();
|
$ret = array();
|
||||||
$q = "select $fields from reports " . $filter->getWhere() . kl_str_sql(" order by id desc limit !i offset !i", $filter->limit, $filter->offset);
|
$q = "select $fields from reports " . $filter->getWhere() . kl_str_sql(" order by id desc limit !i offset !i", $filter->limit, $filter->offset);
|
||||||
@@ -305,7 +305,15 @@ class CrashReport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($function == $singu_function) $function = "";
|
if ($function == $singu_function)
|
||||||
|
{
|
||||||
|
$function = "";
|
||||||
|
}
|
||||||
|
if (!$singu_function && strpos($function, "LL") !== false)
|
||||||
|
{
|
||||||
|
$singu_function = $function;
|
||||||
|
$function = "";
|
||||||
|
}
|
||||||
$this->signature_text = "$module|$function|$singu_function";
|
$this->signature_text = "$module|$function|$singu_function";
|
||||||
$this->signature = md5($this->signature_text);
|
$this->signature = md5($this->signature_text);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,14 @@ class CrashStats
|
|||||||
|
|
||||||
function __construct($filter = null)
|
function __construct($filter = null)
|
||||||
{
|
{
|
||||||
$this->filter = $filter;
|
if ($filter)
|
||||||
|
{
|
||||||
|
$this->filter = $filter;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->filter = new SearchFilter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setFilter($filter)
|
function setFilter($filter)
|
||||||
@@ -14,6 +21,49 @@ class CrashStats
|
|||||||
$this->filter = $filter;
|
$this->filter = $filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTopCrashers()
|
||||||
|
{
|
||||||
|
$ret = array();
|
||||||
|
$where = $this->filter->getWhere();
|
||||||
|
$q = "select count(r.id) as nr, s.id as signature_id, s.signature as signature_text from reports r join signature s on r.signature_id = s.id $where group by signature_id order by nr desc";
|
||||||
|
$q .= kl_str_sql(" limit !i", 100);
|
||||||
|
if (false !== $cached = Memc::getq($q)) return $cached;
|
||||||
|
|
||||||
|
if (!$res = DBH::$db->query($q))
|
||||||
|
{
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ($row = DBH::$db->fetchRow($res))
|
||||||
|
{
|
||||||
|
$r = new stdClass;
|
||||||
|
DBH::$db->loadFromDbRow($r, $res, $row);
|
||||||
|
$ret[] = $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
Memc::setq($q, $ret);
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSignature($id)
|
||||||
|
{
|
||||||
|
$ret = new stdClass;
|
||||||
|
$q = kl_str_sql("select * from signature where id=!i", $id);
|
||||||
|
|
||||||
|
if (!$res = DBH::$db->query($q))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($row = DBH::$db->fetchRow($res))
|
||||||
|
{
|
||||||
|
DBH::$db->loadFromDbRow($ret, $res, $row);
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function getGPUStats()
|
function getGPUStats()
|
||||||
{
|
{
|
||||||
$ret = array();
|
$ret = array();
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ class SearchFilter
|
|||||||
public $region;
|
public $region;
|
||||||
public $gpu;
|
public $gpu;
|
||||||
public $stacktrace;
|
public $stacktrace;
|
||||||
|
public $signature_id;
|
||||||
|
|
||||||
public $sort_by;
|
public $sort_by;
|
||||||
public $sort_order;
|
public $sort_order;
|
||||||
@@ -18,7 +19,7 @@ class SearchFilter
|
|||||||
public $offset = 0;
|
public $offset = 0;
|
||||||
public $page = 0;
|
public $page = 0;
|
||||||
|
|
||||||
var $fields = array("os", "chan", "version", "grid", "region", "gpu", "stacktrace");
|
var $fields = array("os", "chan", "version", "grid", "region", "gpu", "stacktrace", "signature_id");
|
||||||
|
|
||||||
function __construct()
|
function __construct()
|
||||||
{
|
{
|
||||||
@@ -76,6 +77,7 @@ class SearchFilter
|
|||||||
if ($this->grid) $cond[] = kl_str_sql("grid=!s", $this->grid);
|
if ($this->grid) $cond[] = kl_str_sql("grid=!s", $this->grid);
|
||||||
if ($this->region) $cond[] = kl_str_sql("region=!s", $this->region);
|
if ($this->region) $cond[] = kl_str_sql("region=!s", $this->region);
|
||||||
if ($this->gpu) $cond[] = kl_str_sql("gpu=!s", $this->gpu);
|
if ($this->gpu) $cond[] = kl_str_sql("gpu=!s", $this->gpu);
|
||||||
|
if ($this->signature_id) $cond[] = kl_str_sql("signature_id=!s", $this->signature_id);
|
||||||
|
|
||||||
if ($this->stacktrace)
|
if ($this->stacktrace)
|
||||||
{
|
{
|
||||||
@@ -213,6 +215,10 @@ for($i = 0; $i < count($grids); $i++)
|
|||||||
<input type="hidden" name="gpu" value="<?php echo htmlentities($this->gpu) ?>" />
|
<input type="hidden" name="gpu" value="<?php echo htmlentities($this->gpu) ?>" />
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
|
|
||||||
|
<?php if ($this->signature_id): ?>
|
||||||
|
<input type="hidden" name="signature_id" value="<?php echo htmlentities($this->signature_id) ?>" />
|
||||||
|
<?php endif ?>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
4
htdocs/lib/update_signatures.php
Executable file → Normal file
4
htdocs/lib/update_signatures.php
Executable file → Normal file
@@ -17,8 +17,8 @@ while ($row = DBH::$db->fetchRow($res))
|
|||||||
DBH::$db->loadFromDbRow($r, $res, $row);
|
DBH::$db->loadFromDbRow($r, $res, $row);
|
||||||
$r->parseStackTrace();
|
$r->parseStackTrace();
|
||||||
$r->updateSignature();
|
$r->updateSignature();
|
||||||
var_dump($r);
|
|
||||||
print "Updating signature for {$r->id}\n";
|
print "Updating signature for {$r->id}\n";
|
||||||
$r->saveSignature();
|
$r->saveSignature();
|
||||||
}
|
}
|
||||||
DBH::$db->commit();
|
DBH::$db->commit();
|
||||||
|
Memc::flush();
|
||||||
36
htdocs/report_tip.php
Normal file
36
htdocs/report_tip.php
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
define("SITE_ROOT", realpath(dirname(__file__)));
|
||||||
|
require_once SITE_ROOT . "/lib/init.php";
|
||||||
|
$S->requireUser();
|
||||||
|
|
||||||
|
/*
|
||||||
|
$report = CrashReport::getReport((int)$_GET["id"]);
|
||||||
|
if (!$report)
|
||||||
|
{
|
||||||
|
print "<p>No such report</p>";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$full = ReportParser::parse($report->id);
|
||||||
|
//print_r (array_keys($full));
|
||||||
|
|
||||||
|
print "<p> Reported: " . date("r", (int)$report->reported). "</p>";
|
||||||
|
*/
|
||||||
|
|
||||||
|
$stats = new CrashStats($filter);
|
||||||
|
|
||||||
|
if (false === $r = $stats->getSignature((int)$_GET["signature_id"]))
|
||||||
|
{
|
||||||
|
print "<p>No such signature</p>";
|
||||||
|
}
|
||||||
|
|
||||||
|
$parts = explode("|", $r->signature);
|
||||||
|
$txt = "";
|
||||||
|
if ($parts[1]) $txt .= preg_replace("/((::|<|>|,|\\(|\\)))/", "<wbr/>\\1<wbr/>", htmlentities($parts[1]));
|
||||||
|
if ($txt) $txt .= "<br/><br/>";
|
||||||
|
if ($parts[2]) $txt .= preg_replace("/((::|<|>|,|\\(|\\)))/", "<wbr/>\\1<wbr/>", htmlentities($parts[2]));
|
||||||
|
|
||||||
|
print "<p>Module: " . $parts[0];
|
||||||
|
if ($txt) print "<br/><br/>" . $txt . "</p>";
|
||||||
@@ -28,7 +28,39 @@ $filter->render();
|
|||||||
|
|
||||||
<!-- top crashers tab -->
|
<!-- top crashers tab -->
|
||||||
<div id="tab-1">
|
<div id="tab-1">
|
||||||
<p>Working on it</p>
|
<?php
|
||||||
|
function rl_s($r)
|
||||||
|
{
|
||||||
|
global $filter;
|
||||||
|
return URL_ROOT . "/crashes.php?" . $filter->getURLArgs() . "&signature_id=" . urlencode($r->signature_id);
|
||||||
|
}
|
||||||
|
$sigs = $stats->getTopCrashers();
|
||||||
|
$c = count($sigs);
|
||||||
|
if ($c) :
|
||||||
|
?>
|
||||||
|
<table class="jtable noborder" style="width: 100%">
|
||||||
|
<tr>
|
||||||
|
<th style="width: 3%">Nr</th>
|
||||||
|
<th style="width: 10%">Module</th>
|
||||||
|
<th style="width: 80%">Stack Top</th>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
foreach($sigs as $r):
|
||||||
|
$parts = explode("|", $r->signature_text);
|
||||||
|
$txt = "";
|
||||||
|
if ($parts[1]) $txt .= preg_replace("/((<|>|,|\\(|\\)))/", " \\1 ", htmlentities($parts[1]));
|
||||||
|
if ($txt) $txt .= "<br/><br/>";
|
||||||
|
if ($parts[2]) $txt .= preg_replace("/((<|>|,|\\(|\\)))/", " \\1 ", htmlentities($parts[2]));
|
||||||
|
?>
|
||||||
|
<tr class="rowhighlight">
|
||||||
|
<td style="text-align: right"><a href="<?php echo rl_s($r) ?>"><?php echo htmlentities($r->nr) ?></a></td>
|
||||||
|
<td><a href="<?php echo rl_s($r) ?>"><?php echo htmlentities($parts[0]) ?></a></td>
|
||||||
|
<td><a href="<?php echo rl_s($r) ?>"><?php echo $txt ?></a></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<?php endif ?>
|
||||||
</div>
|
</div>
|
||||||
<!-- /top crashers tab -->
|
<!-- /top crashers tab -->
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user