do topcrash by B2G version only; see to create a weekly report

This commit is contained in:
Robert Kaiser 2013-07-24 23:56:53 +02:00
Родитель 8e02ba18cd
Коммит cef1494cc3
1 изменённых файлов: 350 добавлений и 266 удалений

Просмотреть файл

@ -94,6 +94,7 @@ for ($daysback = $backlog_days + 1; $daysback > 0; $daysback--) {
$fbtc = 'b2g-topcrashes.json';
$fpages = 'pages.json';
$fweb = $anadir.'.b2g.crashes.html';
$fwebweek = $anadir.'.b2g.topcrashes.weekly.html';
$anafbcdata = $anadir.'/'.$fbcdata;
if (!file_exists($anafbcdata)) {
@ -147,6 +148,8 @@ for ($daysback = $backlog_days + 1; $daysback > 0; $daysback--) {
$bcd['total']++;
}
uasort($bcd['list'], 'b2glist_compare'); // sort by B2G version, build ID, and crash time
file_put_contents($anafbcdata, json_encode($bcd));
}
else {
@ -157,15 +160,14 @@ for ($daysback = $backlog_days + 1; $daysback > 0; $daysback--) {
if (!file_exists($anafbtc)) {
$btc = array();
foreach ($bcd['list'] as $crash) {
$report = $crash['version'].'::'.$crash['release_channel'].'::'.$crash['b2g_ver'];
$b2g_ver = strlen($crash['b2g_ver'])?$crash['b2g_ver']:'unknown';
$report = $b2g_ver;
$device = strlen($crash['device'])?$crash['device']:'unknown';
$buildday = substr($crash['build'], 0, 8);
$ptype = strlen($crash['process_type'])?$crash['process_type']:'gecko';
addCount($btc, $report);
if ($btc[$report]['.count'] == 1) {
$btc[$report]['version'] = $crash['version'];
$btc[$report]['release_channel'] = $crash['release_channel'];
$btc[$report]['b2g_ver'] = $crash['b2g_ver'];
$btc[$report]['b2g_ver'] = $b2g_ver;
$btc[$report]['.sigs'] = array();
}
addCount($btc[$report]['.sigs'], $crash['signature']);
@ -198,7 +200,7 @@ for ($daysback = $backlog_days + 1; $daysback > 0; $daysback--) {
}
}
krsort($btc); // sort by key (version::channel) in reverse order
krsort($btc); // sort by key (b2g_ver) in reverse order
foreach ($btc as $report=>$rdata) {
if (array_key_exists('.sigs', $rdata)) {
uasort($btc[$report]['.sigs'], 'count_compare'); // sort by count, highest-first
@ -216,293 +218,363 @@ for ($daysback = $backlog_days + 1; $daysback > 0; $daysback--) {
$btc = json_decode(file_get_contents($anafbtc), true);
}
$anafweb = $anadir.'/'.$fweb;
if (!file_exists($anafweb) &&
count($bcd) && $bcd['total']) {
// create out an HTML page
print('Writing HTML output'."\n");
$doc = new DOMDocument('1.0', 'utf-8');
$doc->formatOutput = true; // we want a nice output
$webreports = array('day' => $fweb, 'week' => $fwebweek);
$root = $doc->appendChild($doc->createElement('html'));
$head = $root->appendChild($doc->createElement('head'));
$title = $head->appendChild($doc->createElement('title',
$anadir.' B2G Crashes Report'));
foreach ($webreports as $type=>$fwebcur) {
$anafweb = $anadir.'/'.$fwebcur;
if ($type == 'week') {
if (!file_exists($anafweb)) {
// assemble 7-day "weekly" overview
print('Calculating weekly data'."\n");
$curbtc = $btc;
$style = $head->appendChild($doc->createElement('style'));
$style->setAttribute('type', 'text/css');
$style->appendChild($doc->createCDATASection(
'body {'."\n"
.' color: #000000;'."\n"
.' background-color: #FFFFFF;'."\n"
.'}'."\n"
.'.sig, .time {'."\n"
.' font-size: small;'."\n"
.'}'."\n"
.'.buildid > .timepart {'."\n"
.' color: #808080;'."\n"
.'}'."\n"
.'.device {'."\n"
.' color: #808080;'."\n"
.'}'."\n"
.'/* Shipped devices */'."\n"
.'.device.zte_roamer2,'."\n"
.'.device.unknown_alcatel_one_touch_fire {'."\n"
.' color: #000000;'."\n"
.' font-weight: bold;'."\n"
.'}'."\n"
.'/* Internal testing devices */'."\n"
.'.device.toro_unagi1,'."\n"
.'.device.toro_otoro1,'."\n"
.'.device.toro_inari1,'."\n"
.'.device.qcom_leo {'."\n"
.' color: #000000;'."\n"
.' font-style: italic;'."\n"
.'}'."\n"
.'/* Developer devices */'."\n"
.'.device.geeksphone_gp_peak,'."\n"
.'.device.geeksphone_gp_keon,'."\n"
.'.device.geeksphone_gp_twist {'."\n"
.' color: #000000;'."\n"
.'}'."\n"
.'.ptype.gecko {'."\n"
.'}'."\n"
.'.ptype.content {'."\n"
.' color: #808080;'."\n"
.'}'."\n"
.'.bug {'."\n"
.' font-size: small;'."\n"
.' empty-cells: show;'."\n"
.'}'."\n"
.'.resolved {'."\n"
.' text-decoration: line-through;'."\n"
.'}'."\n"
.'.num, .pct {'."\n"
.' text-align: right;'."\n"
.'}'."\n"
));
$body = $root->appendChild($doc->createElement('body'));
$h1 = $body->appendChild($doc->createElement('h1',
$anadir.' B2G Crashes Report'));
$list = $body->appendChild($doc->createElement('ul'));
$item = $list->appendChild($doc->createElement('li'));
$link = $item->appendChild($doc->createElement('a',
'Top Crashes By Signature'));
$link->setAttribute('href', '#tcbs');
$tlist = $item->appendChild($doc->createElement('ul'));
foreach ($btc as $report=>$rdata) {
$titem = $tlist->appendChild($doc->createElement('li'));
$tlink = $titem->appendChild($doc->createElement('a',
$rdata['version'].' '.$rdata['release_channel'].' ('.$rdata['b2g_ver'].')'));
$tlink->setAttribute('href', '#'.$rdata['version'].$rdata['release_channel'].'-'.$rdata['b2g_ver']);
for ($pastday = 1; $pastday < 7; $pastday++) {
$pasttime = strtotime($anadir.' -'.$pastday.' day');
$pastdir = date('Y-m-d', $pasttime);
print('Adding '.$pastdir);
$pastfbtc = $pastdir.'/'.$fbtc;
if (file_exists($pastfbtc)) {
// Load that data and merge it into $curcd.
$pastbtc = json_decode(file_get_contents($pastfbtc), true);
foreach ($pastbtc as $report=>$rdata) {
print(':');
if (array_key_exists($report, $curbtc)) {
$curbtc[$report]['.count'] += $rdata['.count'];
foreach ($rdata['.sigs'] as $sig=>$sdata) {
print('.');
if (array_key_exists($sig, $curbtc[$report]['.sigs'])) {
$curbtc[$report]['.sigs'][$sig]['.count'] += $sdata['.count'];
$curbtc[$report]['.sigs'][$sig]['devices'] =
array_unique(array_merge($curbtc[$report]['.sigs'][$sig]['devices'], $sdata['devices']));
$curbtc[$report]['.sigs'][$sig]['bdates'] =
array_unique(array_merge($curbtc[$report]['.sigs'][$sig]['bdates'], $sdata['bdates']));
$curbtc[$report]['.sigs'][$sig]['proctypes'] =
array_unique(array_merge($curbtc[$report]['.sigs'][$sig]['proctypes'], $sdata['proctypes']));
}
else {
$curbtc[$report]['.sigs'][$sig] = $sdata;
}
}
}
else {
print('.');
$curbtc[$report] = $rdata;
}
}
print("\n");
}
else { print(' - '.$pastfbtc.' not found.'."\n"); }
}
if (count($curbtc)) {
krsort($curbtc); // sort by key (b2g_ver) in reverse order
foreach ($curbtc as $report=>$rdata) {
if (array_key_exists('.sigs', $rdata)) {
uasort($curbtc[$report]['.sigs'], 'count_compare'); // sort by count, highest-first
foreach ($rdata['.sigs'] as $sig=>$sdata) {
sort($curbtc[$report]['.sigs'][$sig]['devices']);
rsort($curbtc[$report]['.sigs'][$sig]['bdates']);
sort($curbtc[$report]['.sigs'][$sig]['proctypes']);
}
}
}
}
}
}
else {
// single-day data
$curbtc = $btc;
}
$list = $body->appendChild($doc->createElement('ul'));
$item = $list->appendChild($doc->createElement('li'));
$link = $item->appendChild($doc->createElement('a',
'Raw Crash List'));
$link->setAttribute('href', '#crashlist');
$h2 = $body->appendChild($doc->createElement('h2',
'Top Crashes By Signature'));
$link->setAttribute('id', 'tcbs');
if (!file_exists($anafweb) && count($curbtc)) {
// create out an HTML page
print('Writing HTML output'."\n");
$doc = new DOMDocument('1.0', 'utf-8');
$doc->formatOutput = true; // we want a nice output
foreach ($btc as $report=>$rdata) {
$h3 = $body->appendChild($doc->createElement('h3',
$rdata['version'].' '.$rdata['release_channel'].' ('.$rdata['b2g_ver'].')'));
$link->setAttribute('id', $rdata['version'].$rdata['release_channel'].'-'.$rdata['b2g_ver']);
$root = $doc->appendChild($doc->createElement('html'));
$head = $root->appendChild($doc->createElement('head'));
$title = $head->appendChild($doc->createElement('title',
$anadir.($type == 'week'?' Weekly':'').' B2G Crashes Report'));
$table = $body->appendChild($doc->createElement('table'));
$table->setAttribute('border', '1');
$style = $head->appendChild($doc->createElement('style'));
$style->setAttribute('type', 'text/css');
$style->appendChild($doc->createCDATASection(''
.'body {'."\n"
.' color: #000000;'."\n"
.' background-color: #FFFFFF;'."\n"
.'}'."\n"
.'.sig, .time {'."\n"
.' font-size: small;'."\n"
.'}'."\n"
.'.buildid > .timepart {'."\n"
.' color: #808080;'."\n"
.'}'."\n"
.'.device {'."\n"
.' color: #808080;'."\n"
.'}'."\n"
.'/* Shipped devices */'."\n"
.'.device.zte_roamer2,'."\n"
.'.device.unknown_alcatel_one_touch_fire {'."\n"
.' color: #000000;'."\n"
.' font-weight: bold;'."\n"
.'}'."\n"
.'/* Internal testing devices */'."\n"
.'.device.toro_unagi1,'."\n"
.'.device.toro_otoro1,'."\n"
.'.device.toro_inari1,'."\n"
.'.device.qcom_leo,'."\n"
.'.device.lge_lg_d300 {'."\n"
.' color: #000000;'."\n"
.' font-style: italic;'."\n"
.'}'."\n"
.'/* Developer devices */'."\n"
.'.device.geeksphone_gp_peak,'."\n"
.'.device.geeksphone_gp_keon,'."\n"
.'.device.geeksphone_gp_twist {'."\n"
.' color: #000000;'."\n"
.'}'."\n"
.'.ptype.gecko {'."\n"
.'}'."\n"
.'.ptype.content {'."\n"
.' color: #808080;'."\n"
.'}'."\n"
.'.bug {'."\n"
.' font-size: small;'."\n"
.' empty-cells: show;'."\n"
.'}'."\n"
.'.resolved {'."\n"
.' text-decoration: line-through;'."\n"
.'}'."\n"
.'.num, .pct {'."\n"
.' text-align: right;'."\n"
.'}'."\n"
));
// table head
$tr = $table->appendChild($doc->createElement('tr'));
$th = $tr->appendChild($doc->createElement('th', 'Signature'));
$th = $tr->appendChild($doc->createElement('th', 'Devices'));
$th = $tr->appendChild($doc->createElement('th', 'Build Dates'));
$th = $tr->appendChild($doc->createElement('th', 'Process Types'));
$th = $tr->appendChild($doc->createElement('th', 'Count'));
$th = $tr->appendChild($doc->createElement('th', 'Pct'));
$th = $tr->appendChild($doc->createElement('th', 'Bugs'));
$body = $root->appendChild($doc->createElement('body'));
$h1 = $body->appendChild($doc->createElement('h1',
$anadir.($type == 'week'?' Weekly':'').' B2G Crashes Report'));
foreach ($rdata['.sigs'] as $sig=>$sdata) {
$pct = $rdata['.count'] ?
$sdata['.count'] / $rdata['.count'] : 0;
$list = $body->appendChild($doc->createElement('ul'));
$item = $list->appendChild($doc->createElement('li'));
$link = $item->appendChild($doc->createElement('a',
'Top Crashes By Signature'));
$link->setAttribute('href', '#tcbs');
$tlist = $item->appendChild($doc->createElement('ul'));
foreach ($curbtc as $report=>$rdata) {
$titem = $tlist->appendChild($doc->createElement('li'));
$tlink = $titem->appendChild($doc->createElement('a',
$rdata['b2g_ver']));
$tlink->setAttribute('href', '#b2g-'.$rdata['b2g_ver']);
}
if ($type != 'week') {
$item = $list->appendChild($doc->createElement('li'));
$link = $item->appendChild($doc->createElement('a',
'Raw Crash List'));
$link->setAttribute('href', '#crashlist');
}
$h2 = $body->appendChild($doc->createElement('h2',
'Top Crashes By Signature'));
$link->setAttribute('id', 'tcbs');
foreach ($curbtc as $report=>$rdata) {
$h3 = $body->appendChild($doc->createElement('h3',
$rdata['b2g_ver']));
$link->setAttribute('id', 'b2g-'.$rdata['b2g_ver']);
$table = $body->appendChild($doc->createElement('table'));
$table->setAttribute('border', '1');
// table head
$tr = $table->appendChild($doc->createElement('tr'));
$td = $tr->appendChild($doc->createElement('td'));
$td->setAttribute('class', 'sig');
if (!strlen($sig)) {
$link = $td->appendChild($doc->createElement('a', '(empty signature)'));
$link->setAttribute('href', $url_nullsiglink);
}
elseif ($sig == '\N') {
$td->appendChild($doc->createTextNode('(processing failure - "'.$sig.'")'));
}
else {
// common case, useful signature
$sigdisplay = preg_replace('/_+\.*$/', '', $sig);
$link = $td->appendChild($doc->createElement('a',
htmlentities($sigdisplay, ENT_COMPAT, 'UTF-8')));
$link->setAttribute('href', $url_siglinkbase.rawurlencode($sig));
}
$td = $tr->appendChild($doc->createElement('td'));
foreach ($sdata['devices'] as $device) {
if (strlen($td->textContent)) {
$td->appendChild($doc->createTextNode(', '));
$th = $tr->appendChild($doc->createElement('th', 'Signature'));
$th = $tr->appendChild($doc->createElement('th', 'Devices'));
$th = $tr->appendChild($doc->createElement('th', 'Build Dates'));
$th = $tr->appendChild($doc->createElement('th', 'Process Types'));
$th = $tr->appendChild($doc->createElement('th', 'Count'));
$th = $tr->appendChild($doc->createElement('th', 'Pct'));
$th = $tr->appendChild($doc->createElement('th', 'Bugs'));
foreach ($rdata['.sigs'] as $sig=>$sdata) {
$pct = $rdata['.count'] ?
$sdata['.count'] / $rdata['.count'] : 0;
$tr = $table->appendChild($doc->createElement('tr'));
$td = $tr->appendChild($doc->createElement('td'));
$td->setAttribute('class', 'sig');
if (!strlen($sig)) {
$link = $td->appendChild($doc->createElement('a', '(empty signature)'));
$link->setAttribute('href', $url_nullsiglink);
}
$span = $td->appendChild($doc->createElement('span', $device));
$span->setAttribute('class', 'device '.deviceClass($device));
}
$td = $tr->appendChild($doc->createElement('td', implode(', ', $sdata['bdates'])));
$td = $tr->appendChild($doc->createElement('td'));
foreach ($sdata['proctypes'] as $ptype) {
if (strlen($td->textContent)) {
$td->appendChild($doc->createTextNode(', '));
elseif ($sig == '\N') {
$td->appendChild($doc->createTextNode('(processing failure - "'.$sig.'")'));
}
$span = $td->appendChild($doc->createElement('span', $ptype));
$span->setAttribute('class', 'ptype '.$ptype);
}
$td = $tr->appendChild($doc->createElement('td', $sdata['.count']));
$td->setAttribute('class', 'num');
$td = $tr->appendChild($doc->createElement('td',
sprintf('%.1f', 100 * $pct).'%'));
$td->setAttribute('class', 'pct');
$td = $tr->appendChild($doc->createElement('td'));
if (array_key_exists('bugs', $sdata) && count($sdata['bugs'])) {
foreach ($sdata['bugs'] as $bug => $bugdata) {
else {
// common case, useful signature
$sigdisplay = preg_replace('/_+\.*$/', '', $sig);
$link = $td->appendChild($doc->createElement('a',
htmlentities($sigdisplay, ENT_COMPAT, 'UTF-8')));
$link->setAttribute('href', $url_siglinkbase.rawurlencode($sig));
}
$td = $tr->appendChild($doc->createElement('td'));
foreach ($sdata['devices'] as $device) {
if (strlen($td->textContent)) {
$td->appendChild($doc->createTextNode(', '));
}
$link = $td->appendChild($doc->createElement('a', $bug));
$link->setAttribute('href', $url_buglinkbase.$bug);
$link->setAttribute('title',
$bugdata['status'].' '.$bugdata['resolution'].' - '
.htmlentities($bugdata['short_desc'], ENT_COMPAT, 'UTF-8'));
if ($bugdata['status'] == 'RESOLVED' || $bugdata['status'] == 'VERIFIED') {
$link->setAttribute('class', 'bug resolved');
}
else {
$link->setAttribute('class', 'bug');
}
$span = $td->appendChild($doc->createElement('span', $device));
$span->setAttribute('class', 'device '.deviceClass($device));
}
}
else {
$td->appendChild($doc->createTextNode('-'));
}
}
}
$h2 = $body->appendChild($doc->createElement('h2',
'Raw Crash List'));
$link->setAttribute('id', 'crashlist');
// description
$para = $body->appendChild($doc->createElement('p',
'List of all '.$bcd['total'].' crashes for B2G on actual devices.'
.' (Times in the "Crash" column are UTC and link to the detailed crash'
.' reports on Socorro.)'));
$table = $body->appendChild($doc->createElement('table'));
$table->setAttribute('border', '1');
// table head
$tr = $table->appendChild($doc->createElement('tr'));
$th = $tr->appendChild($doc->createElement('th', 'Ver'));
$th = $tr->appendChild($doc->createElement('th', 'Build ID'));
$th = $tr->appendChild($doc->createElement('th', 'Channel'));
$th = $tr->appendChild($doc->createElement('th', 'B2G-Ver'));
$th = $tr->appendChild($doc->createElement('th', 'Crash'));
$th = $tr->appendChild($doc->createElement('th', 'Device'));
$th = $tr->appendChild($doc->createElement('th', 'Process'));
$th = $tr->appendChild($doc->createElement('th', 'Signature'));
$th = $tr->appendChild($doc->createElement('th', 'Bugs'));
foreach ($bcd['list'] as $crash) {
$tr = $table->appendChild($doc->createElement('tr'));
$td = $tr->appendChild($doc->createElement('td', $crash['version']));
$td->setAttribute('class', 'version');
$td = $tr->appendChild($doc->createElement('td'));
$td->setAttribute('class', 'buildid');
$span = $td->appendChild($doc->createElement('span', substr($crash['build'], 0, 8)));
$span->setAttribute('class', 'datepart');
$span = $td->appendChild($doc->createElement('span', substr($crash['build'], 8)));
$span->setAttribute('class', 'timepart');
$td = $tr->appendChild($doc->createElement('td', $crash['release_channel']));
$td->setAttribute('class', 'channel');
$td = $tr->appendChild($doc->createElement('td', $crash['b2g_ver']));
$td->setAttribute('class', 'version');
$td = $tr->appendChild($doc->createElement('td'));
$td->setAttribute('class', 'time');
$link = $td->appendChild($doc->createElement('a',
gmdate('H:i:s', strtotime($crash['date_processed']))));
$link->setAttribute('href', $url_replinkbase.$crash['uuid']);
$device = strlen($crash['device'])?$crash['device']:'unknown';
$td = $tr->appendChild($doc->createElement('td', $device));
$td->setAttribute('class', 'device '.deviceClass($device));
$ptype = strlen($crash['process_type'])?$crash['process_type']:'gecko';
$td = $tr->appendChild($doc->createElement('td', $ptype));
$td->setAttribute('class', 'ptype '.$ptype);
$td = $tr->appendChild($doc->createElement('td'));
$td->setAttribute('class', 'sig');
if (!strlen($crash['signature'])) {
$link = $td->appendChild($doc->createElement('a', '(empty signature)'));
$link->setAttribute('href', $url_nullsiglink);
}
elseif ($crash['signature'] == '\N') {
$td->appendChild($doc->createTextNode('(processing failure - "'.$crash['signature'].'")'));
}
else {
// common case, useful signature
$sigdisplay = preg_replace('/_+\.*$/', '', $crash['signature']);
$link = $td->appendChild($doc->createElement('a',
htmlentities($sigdisplay, ENT_COMPAT, 'UTF-8')));
$link->setAttribute('href', $url_siglinkbase.rawurlencode($crash['signature']));
}
$td = $tr->appendChild($doc->createElement('td'));
if (array_key_exists('bugs', $crash) && count($crash['bugs'])) {
foreach ($crash['bugs'] as $bug => $bugdata) {
if (strlen($td->textContent)) {
$td->appendChild($doc->createTextNode(', '));
$td = $tr->appendChild($doc->createElement('td', implode(', ', $sdata['bdates'])));
$td = $tr->appendChild($doc->createElement('td'));
foreach ($sdata['proctypes'] as $ptype) {
if (strlen($td->textContent)) {
$td->appendChild($doc->createTextNode(', '));
}
$span = $td->appendChild($doc->createElement('span', $ptype));
$span->setAttribute('class', 'ptype '.$ptype);
}
$link = $td->appendChild($doc->createElement('a', $bug));
$link->setAttribute('href', $url_buglinkbase.$bug);
$link->setAttribute('title',
$bugdata['status'].' '.$bugdata['resolution'].' - '
.htmlentities($bugdata['short_desc'], ENT_COMPAT, 'UTF-8'));
if ($bugdata['status'] == 'RESOLVED' || $bugdata['status'] == 'VERIFIED') {
$link->setAttribute('class', 'bug resolved');
$td = $tr->appendChild($doc->createElement('td', $sdata['.count']));
$td->setAttribute('class', 'num');
$td = $tr->appendChild($doc->createElement('td',
sprintf('%.1f', 100 * $pct).'%'));
$td->setAttribute('class', 'pct');
$td = $tr->appendChild($doc->createElement('td'));
if (array_key_exists('bugs', $sdata) && count($sdata['bugs'])) {
foreach ($sdata['bugs'] as $bug => $bugdata) {
if (strlen($td->textContent)) {
$td->appendChild($doc->createTextNode(', '));
}
$link = $td->appendChild($doc->createElement('a', $bug));
$link->setAttribute('href', $url_buglinkbase.$bug);
$link->setAttribute('title',
$bugdata['status'].' '.$bugdata['resolution'].' - '
.htmlentities($bugdata['short_desc'], ENT_COMPAT, 'UTF-8'));
if ($bugdata['status'] == 'RESOLVED' || $bugdata['status'] == 'VERIFIED') {
$link->setAttribute('class', 'bug resolved');
}
else {
$link->setAttribute('class', 'bug');
}
}
}
else {
$link->setAttribute('class', 'bug');
$td->appendChild($doc->createTextNode('-'));
}
}
}
else {
$td->appendChild($doc->createTextNode('-'));
if ($type != 'week') {
$h2 = $body->appendChild($doc->createElement('h2',
'Raw Crash List'));
$link->setAttribute('id', 'crashlist');
// description
$para = $body->appendChild($doc->createElement('p',
'List of all '.$bcd['total'].' crashes for B2G on actual devices.'
.' (Times in the "Crash" column are UTC and link to the detailed crash'
.' reports on Socorro.)'));
$table = $body->appendChild($doc->createElement('table'));
$table->setAttribute('border', '1');
// table head
$tr = $table->appendChild($doc->createElement('tr'));
$th = $tr->appendChild($doc->createElement('th', 'B2G-Ver'));
$th = $tr->appendChild($doc->createElement('th', 'Build ID'));
$th = $tr->appendChild($doc->createElement('th', 'Ver'));
$th = $tr->appendChild($doc->createElement('th', 'Channel'));
$th = $tr->appendChild($doc->createElement('th', 'Crash'));
$th = $tr->appendChild($doc->createElement('th', 'Device'));
$th = $tr->appendChild($doc->createElement('th', 'Process'));
$th = $tr->appendChild($doc->createElement('th', 'Signature'));
$th = $tr->appendChild($doc->createElement('th', 'Bugs'));
foreach ($bcd['list'] as $crash) {
$tr = $table->appendChild($doc->createElement('tr'));
$td = $tr->appendChild($doc->createElement('td', $crash['b2g_ver']));
$td->setAttribute('class', 'version');
$td = $tr->appendChild($doc->createElement('td'));
$td->setAttribute('class', 'buildid');
$span = $td->appendChild($doc->createElement('span', substr($crash['build'], 0, 8)));
$span->setAttribute('class', 'datepart');
$span = $td->appendChild($doc->createElement('span', substr($crash['build'], 8)));
$span->setAttribute('class', 'timepart');
$td = $tr->appendChild($doc->createElement('td', $crash['version']));
$td->setAttribute('class', 'version');
$td = $tr->appendChild($doc->createElement('td', $crash['release_channel']));
$td->setAttribute('class', 'channel');
$td = $tr->appendChild($doc->createElement('td'));
$td->setAttribute('class', 'time');
$link = $td->appendChild($doc->createElement('a',
gmdate('H:i:s', strtotime($crash['date_processed']))));
$link->setAttribute('href', $url_replinkbase.$crash['uuid']);
$device = strlen($crash['device'])?$crash['device']:'unknown';
$td = $tr->appendChild($doc->createElement('td', $device));
$td->setAttribute('class', 'device '.deviceClass($device));
$ptype = strlen($crash['process_type'])?$crash['process_type']:'gecko';
$td = $tr->appendChild($doc->createElement('td', $ptype));
$td->setAttribute('class', 'ptype '.$ptype);
$td = $tr->appendChild($doc->createElement('td'));
$td->setAttribute('class', 'sig');
if (!strlen($crash['signature'])) {
$link = $td->appendChild($doc->createElement('a', '(empty signature)'));
$link->setAttribute('href', $url_nullsiglink);
}
elseif ($crash['signature'] == '\N') {
$td->appendChild($doc->createTextNode('(processing failure - "'.$crash['signature'].'")'));
}
else {
// common case, useful signature
$sigdisplay = preg_replace('/_+\.*$/', '', $crash['signature']);
$link = $td->appendChild($doc->createElement('a',
htmlentities($sigdisplay, ENT_COMPAT, 'UTF-8')));
$link->setAttribute('href', $url_siglinkbase.rawurlencode($crash['signature']));
}
$td = $tr->appendChild($doc->createElement('td'));
if (array_key_exists('bugs', $crash) && count($crash['bugs'])) {
foreach ($crash['bugs'] as $bug => $bugdata) {
if (strlen($td->textContent)) {
$td->appendChild($doc->createTextNode(', '));
}
$link = $td->appendChild($doc->createElement('a', $bug));
$link->setAttribute('href', $url_buglinkbase.$bug);
$link->setAttribute('title',
$bugdata['status'].' '.$bugdata['resolution'].' - '
.htmlentities($bugdata['short_desc'], ENT_COMPAT, 'UTF-8'));
if ($bugdata['status'] == 'RESOLVED' || $bugdata['status'] == 'VERIFIED') {
$link->setAttribute('class', 'bug resolved');
}
else {
$link->setAttribute('class', 'bug');
}
}
}
else {
$td->appendChild($doc->createTextNode('-'));
}
}
}
}
$doc->saveHTMLFile($anafweb);
$doc->saveHTMLFile($anafweb);
// add the page to the pages index
$anafpages = $anadir.'/'.$fpages;
if (file_exists($anafpages)) {
$pages = json_decode(file_get_contents($anafpages), true);
// add the page to the pages index
$anafpages = $anadir.'/'.$fpages;
if (file_exists($anafpages)) {
$pages = json_decode(file_get_contents($anafpages), true);
}
else {
$pages = array();
}
$pages[$fweb] =
array('product' => 'B2G',
'channel' => null,
'version' => null,
'report' => 'b2gcrash',
'report_sub' => $type,
'display_ver' => 'B2G',
'display_rep' => 'Crashes Report');
file_put_contents($anafpages, json_encode($pages));
}
else {
$pages = array();
}
$pages[$fweb] =
array('product' => 'B2G',
'channel' => null,
'version' => null,
'report' => 'b2gcrash',
'report_sub' => null,
'display_ver' => 'B2G',
'display_rep' => 'Crashes Report');
file_put_contents($anafpages, json_encode($pages));
}
}
print("\n");
@ -515,6 +587,18 @@ function count_compare($a, $b) {
return ($a['.count'] > $b['.count']) ? -1 : 1;
}
// Comparison function on B2G version, build ID and time (reverse sort!)
function b2glist_compare($a, $b) {
if ($a['b2g_ver'] == $b['b2g_ver']) {
if ($a['build'] == $b['build']) {
if ($a['date_processed'] == $b['date_processed']) { return 0; }
return ($a['date_processed'] > $b['date_processed']) ? -1 : 1;
}
return ($a['build'] > $b['build']) ? -1 : 1;
}
return ($a['b2g_ver'] > $b['b2g_ver']) ? -1 : 1;
}
// Bump the counter of an element or initialize it.
function addCount(&$basevar, $sub, $addnum = 1) {
if (array_key_exists($sub, $basevar)) {