2012-02-17 21:50:54 +04:00
|
|
|
#!/usr/bin/php
|
|
|
|
<?php
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
// This script retrieves explosiveness stats for crash signatures.
|
|
|
|
|
|
|
|
// *** non-commandline handling ***
|
|
|
|
|
|
|
|
if (php_sapi_name() != 'cli') {
|
|
|
|
// not commandline, assume apache and output own source
|
|
|
|
header('Content-Type: text/plain; charset=utf8');
|
|
|
|
print(file_get_contents($_SERVER['SCRIPT_FILENAME']));
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
2012-03-01 04:01:19 +04:00
|
|
|
include_once('datautils.php');
|
|
|
|
|
2012-02-17 21:50:54 +04:00
|
|
|
// *** script settings ***
|
|
|
|
|
|
|
|
// turn on error reporting in the script output
|
|
|
|
ini_set('display_errors', 1);
|
|
|
|
|
|
|
|
// make sure new files are set to -rw-r--r-- permissions
|
|
|
|
umask(022);
|
|
|
|
|
|
|
|
// set default time zone - right now, always the one the server is in!
|
|
|
|
date_default_timezone_set('America/Los_Angeles');
|
|
|
|
|
|
|
|
|
|
|
|
// *** data gathering variables ***
|
|
|
|
|
2012-08-17 00:52:58 +04:00
|
|
|
// products to gather data from
|
2013-10-30 06:37:55 +04:00
|
|
|
$products = array('Firefox', 'MetroFirefox', 'Fennec', 'FennecAndroid');
|
2012-02-17 21:50:54 +04:00
|
|
|
|
2013-10-31 03:04:05 +04:00
|
|
|
// products and channels to gather data per-type from
|
2014-11-15 00:37:34 +03:00
|
|
|
$prodchannels = array('Firefox' => array('release', 'beta', 'aurora', 'nightly'),
|
|
|
|
'FennecAndroid' => array('release', 'beta', 'aurora', 'nightly'));
|
2014-11-15 00:23:53 +03:00
|
|
|
|
2012-02-17 21:50:54 +04:00
|
|
|
// for how many days back to get the data
|
2014-11-15 00:37:34 +03:00
|
|
|
$backlog_days = -1; // 15;
|
2012-02-17 21:50:54 +04:00
|
|
|
|
|
|
|
// *** URLs and paths ***
|
|
|
|
|
|
|
|
$on_moz_server = file_exists('/mnt/crashanalysis/rkaiser/');
|
|
|
|
|
2012-04-06 03:02:29 +04:00
|
|
|
// File storing the DB access data - including password!
|
|
|
|
$fdbsecret = '/home/rkaiser/.socorro-prod-dbsecret.json';
|
|
|
|
|
2012-02-17 21:50:54 +04:00
|
|
|
if ($on_moz_server) { chdir('/mnt/crashanalysis/rkaiser/'); }
|
|
|
|
else { chdir('/mnt/mozilla/projects/socorro/'); }
|
|
|
|
|
|
|
|
|
|
|
|
// *** code start ***
|
|
|
|
|
2012-04-28 03:12:09 +04:00
|
|
|
// Get start and end dates
|
2012-09-19 05:24:32 +04:00
|
|
|
$day_start = date('Y-m-d', strtotime($backlog_days.' days ago'));
|
2012-04-28 03:12:09 +04:00
|
|
|
$day_end = date('Y-m-d', strtotime('yesterday'));
|
2012-02-17 21:50:54 +04:00
|
|
|
|
2012-04-06 03:02:29 +04:00
|
|
|
if (file_exists($fdbsecret)) {
|
|
|
|
$dbsecret = json_decode(file_get_contents($fdbsecret), true);
|
2012-04-28 03:30:35 +04:00
|
|
|
if (!is_array($dbsecret) || !count($dbsecret)) {
|
|
|
|
print('ERROR: No DB secrets found, aborting!'."\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2012-05-17 03:28:28 +04:00
|
|
|
$db_conn = pg_pconnect('host='.$dbsecret['host']
|
2012-05-30 22:34:11 +04:00
|
|
|
.' port='.$dbsecret['port']
|
|
|
|
.' dbname=breakpad'
|
|
|
|
.' user='.$dbsecret['user']
|
|
|
|
.' password='.$dbsecret['password']);
|
2012-05-17 03:28:28 +04:00
|
|
|
if (!$db_conn) {
|
|
|
|
print('ERROR: DB connection failed, aborting!'."\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2012-04-06 03:02:29 +04:00
|
|
|
// For info on what data can be accessed, see also
|
|
|
|
// http://socorro.readthedocs.org/en/latest/databasetabledesc.html
|
2012-05-16 15:36:21 +04:00
|
|
|
// For the DB schema, see
|
|
|
|
// https://github.com/mozilla/socorro/blob/master/sql/schema.sql
|
2012-04-06 03:02:29 +04:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Won't work! (Set just for documenting what fields are in the file.)
|
2012-04-28 03:12:09 +04:00
|
|
|
$dbsecret = array('host' => 'host.m.c', 'port' => '6432',
|
|
|
|
'user' => 'analyst', 'password' => 'foo');
|
2012-04-28 03:30:35 +04:00
|
|
|
print('ERROR: No DB secrets found, aborting!'."\n");
|
2012-04-06 03:02:29 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2012-08-17 00:52:58 +04:00
|
|
|
foreach ($products as $product) {
|
2012-02-17 21:50:54 +04:00
|
|
|
$fproddata = $product.'-daily.json';
|
|
|
|
|
|
|
|
if (file_exists($fproddata)) {
|
|
|
|
print('Read stored '.$product.' daily data'."\n");
|
|
|
|
$proddata = json_decode(file_get_contents($fproddata), true);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$proddata = array();
|
2012-04-28 03:12:09 +04:00
|
|
|
}
|
|
|
|
|
2012-08-17 00:52:58 +04:00
|
|
|
// Get all active versions for that product.
|
|
|
|
$versions = array();
|
|
|
|
$ver_query =
|
|
|
|
'SELECT version_string '
|
|
|
|
.'FROM product_versions '
|
|
|
|
."WHERE product_name = '".$product."'"
|
2012-08-17 01:03:40 +04:00
|
|
|
." AND sunset_date > '".$day_start."';";
|
2012-08-17 00:52:58 +04:00
|
|
|
$ver_result = pg_query($db_conn, $ver_query);
|
|
|
|
if (!$ver_result) {
|
|
|
|
print('--- ERROR: versions query failed!'."\n");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
while ($ver_row = pg_fetch_array($ver_result)) {
|
|
|
|
$versions[] = $ver_row['version_string'];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-17 03:28:28 +04:00
|
|
|
print('Fetch daily data for '.$product.' '.implode(', ', $versions)."\n");
|
2012-04-28 03:12:09 +04:00
|
|
|
// See https://bugzilla.mozilla.org/show_bug.cgi?id=733489#c1
|
|
|
|
// for example queries to get /daily numbers.
|
|
|
|
|
|
|
|
/* Query for numbers that exactly match /daily (only matching major OSes):
|
|
|
|
SELECT adu_date, product_name as Product, version_string as Version,
|
|
|
|
SUM(adjusted_crashes) as Crashes, SUM(adu_count) as ADU
|
|
|
|
FROM product_os_crash_ratio
|
|
|
|
WHERE product_name = 'Firefox'
|
2013-01-04 17:03:34 +04:00
|
|
|
and version_string = '17.0'
|
|
|
|
and adu_date between '2012-12-24' and '2013-01-02'
|
2012-04-28 03:12:09 +04:00
|
|
|
and os_name in ('Windows', 'Mac OS X', 'Linux')
|
|
|
|
GROUP BY adu_date, Product, Version
|
|
|
|
ORDER BY adu_date desc;
|
|
|
|
*/
|
|
|
|
|
2013-03-13 20:26:18 +04:00
|
|
|
$maxday = null;
|
|
|
|
|
2012-04-28 03:12:09 +04:00
|
|
|
$db_query = 'SELECT adu_date, version_string as version, '
|
|
|
|
.'adjusted_crashes as crashes, adu_count as adu '
|
|
|
|
.'FROM product_crash_ratio '
|
|
|
|
."WHERE product_name = '".$product."' "
|
|
|
|
."AND version_string IN ('".implode("','", $versions)."') "
|
|
|
|
."AND adu_date BETWEEN '".$day_start."' AND '".$day_end."' "
|
|
|
|
.'ORDER BY adu_date DESC, version DESC;';
|
|
|
|
|
|
|
|
$result = pg_query($db_conn, $db_query);
|
|
|
|
if (!$result) {
|
|
|
|
print('--- ERROR: query failed!'."\n");
|
2012-02-17 21:50:54 +04:00
|
|
|
}
|
|
|
|
|
2012-04-28 03:30:35 +04:00
|
|
|
while ($row = pg_fetch_array($result)) {
|
2012-04-28 03:12:09 +04:00
|
|
|
$ver = $row['version'];
|
|
|
|
$day = $row['adu_date'];
|
|
|
|
$crashes = intval($row['crashes']);
|
|
|
|
$adu = intval($row['adu']);
|
2012-11-26 18:36:09 +04:00
|
|
|
if ($crashes || $adu) {
|
2012-04-28 03:12:09 +04:00
|
|
|
$proddata[$ver][$day] = array('crashes' => $crashes,
|
|
|
|
'adu' => $adu);
|
2012-02-17 21:50:54 +04:00
|
|
|
}
|
2013-03-13 20:26:18 +04:00
|
|
|
if (is_null($maxday) || $maxday < $day) { $maxday = $day; }
|
|
|
|
}
|
|
|
|
if ($maxday < $day_end) {
|
|
|
|
print('--- ERROR: Last day retrieved is '.$maxday.' while yesterday was '.$day_end.'!'."\n");
|
2012-02-17 21:50:54 +04:00
|
|
|
}
|
|
|
|
file_put_contents($fproddata, json_encode($proddata));
|
|
|
|
}
|
2013-10-31 03:04:05 +04:00
|
|
|
|
2013-11-02 05:35:25 +04:00
|
|
|
// uncomment for backfilling
|
2014-11-15 00:37:34 +03:00
|
|
|
$day_start = '2011-01-01';
|
2013-11-02 05:35:25 +04:00
|
|
|
|
2013-10-31 03:04:05 +04:00
|
|
|
foreach ($prodchannels as $product=>$channels) {
|
|
|
|
foreach ($channels as $channel) {
|
2014-01-22 20:53:51 +04:00
|
|
|
$fprodtypedata = $product.'-'.$channel.'-bytype.json';
|
2013-10-31 03:04:05 +04:00
|
|
|
|
|
|
|
if (file_exists($fprodtypedata)) {
|
2014-01-22 20:53:51 +04:00
|
|
|
print('Read stored '.$product.' '.ucfirst($channel).' per-type data'."\n");
|
2013-10-31 03:04:05 +04:00
|
|
|
$prodtypedata = json_decode(file_get_contents($fprodtypedata), true);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$prodtypedata = array();
|
|
|
|
}
|
|
|
|
|
2014-01-22 20:53:51 +04:00
|
|
|
print('Fetch per-type daily data for '.$product.' '.ucfirst($channel)."\n");
|
2013-10-31 03:04:05 +04:00
|
|
|
/* Query for numbers per crash type for "recent releases":
|
|
|
|
SELECT product_versions.product_name,product_versions.version_string,crashes_by_user.report_date,crash_types.crash_type,SUM(report_count) AS crashes, SUM(adu) AS adi
|
|
|
|
FROM crashes_by_user JOIN product_versions ON (crashes_by_user.product_version_id=product_versions.product_version_id) JOIN crash_types ON (crashes_by_user.crash_type_id=crash_types.crash_type_id)
|
|
|
|
WHERE product_versions.product_name = 'Firefox' AND product_versions.build_type='Release' AND crashes_by_user.report_date<(product_versions.build_date + interval '9 weeks') AND crashes_by_user.report_date BETWEEN '2013-10-22' AND '2013-10-30'
|
|
|
|
GROUP BY product_versions.product_name,product_versions.version_string,crashes_by_user.report_date,crash_types.crash_type
|
|
|
|
ORDER BY report_date DESC;
|
|
|
|
*/
|
|
|
|
|
|
|
|
$maxday = null;
|
|
|
|
|
2014-01-22 21:56:11 +04:00
|
|
|
$max_build_age = getMaxBuildAge($channel, true);
|
2013-11-12 17:32:03 +04:00
|
|
|
|
2013-10-31 03:04:05 +04:00
|
|
|
$db_query = 'SELECT crashes_by_user.report_date, crash_types.crash_type, '
|
2013-12-16 20:44:23 +04:00
|
|
|
.'SUM(crashes_by_user.report_count) AS crashes, SUM(crashes_by_user.adu) AS adi, '
|
|
|
|
."string_agg(product_versions.version_string,',') as versions "
|
2013-10-31 03:04:05 +04:00
|
|
|
.'FROM crashes_by_user JOIN product_versions'
|
|
|
|
.' ON (crashes_by_user.product_version_id=product_versions.product_version_id)'
|
|
|
|
.' JOIN crash_types ON (crashes_by_user.crash_type_id=crash_types.crash_type_id) '
|
|
|
|
."WHERE product_versions.product_name = '".$product."'"
|
2014-01-22 21:05:38 +04:00
|
|
|
." AND product_versions.build_type='".$channel."'"
|
2014-01-22 20:53:51 +04:00
|
|
|
." AND product_versions.is_rapid_beta='f'"
|
2013-11-02 05:12:48 +04:00
|
|
|
.(($product == 'Firefox')?" AND major_version!='3.6'":'') // 3.6 has ADI but no crashes and disturbs the stats.
|
2013-11-12 17:32:03 +04:00
|
|
|
." AND crashes_by_user.report_date < (product_versions.build_date + interval '".$max_build_age."')"
|
2013-10-31 03:04:05 +04:00
|
|
|
." AND crashes_by_user.report_date BETWEEN '".$day_start."' AND '".$day_end."' "
|
|
|
|
.'GROUP BY crashes_by_user.report_date, crash_types.crash_type '
|
2014-02-06 21:29:12 +04:00
|
|
|
.'ORDER BY crashes_by_user.report_date ASC;';
|
2013-10-31 03:04:05 +04:00
|
|
|
|
|
|
|
$result = pg_query($db_conn, $db_query);
|
|
|
|
if (!$result) {
|
|
|
|
print('--- ERROR: query failed!'."\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
while ($row = pg_fetch_array($result)) {
|
|
|
|
$day = $row['report_date'];
|
|
|
|
$type = $row['crash_type'];
|
2014-01-22 20:53:51 +04:00
|
|
|
$crashes = intval($row['crashes']) * (($product == 'Firefox' && $channel == 'release') ? 10 : 1);
|
2013-10-31 03:04:05 +04:00
|
|
|
$adi = intval($row['adi']);
|
2013-12-18 00:34:38 +04:00
|
|
|
// The SQL query can give us the same version multiple times, so we take
|
|
|
|
// out redundant elements with array_unique and then do a primitive sort
|
|
|
|
// for re-setting array indexes and giving a consistent output.
|
2013-12-17 18:16:04 +04:00
|
|
|
$versions = array_unique(explode(',', $row['versions']));
|
2013-12-18 00:34:38 +04:00
|
|
|
sort($versions);
|
2013-10-31 03:04:05 +04:00
|
|
|
if ($crashes || $adi) {
|
2013-12-18 00:34:38 +04:00
|
|
|
$prodtypedata[$day]['versions'] = array_values($versions);
|
2013-10-31 03:07:06 +04:00
|
|
|
$prodtypedata[$day]['adi'] = $adi;
|
2013-10-31 03:12:19 +04:00
|
|
|
if (!array_key_exists('crashes', $prodtypedata[$day])) {
|
2013-10-31 03:07:06 +04:00
|
|
|
$prodtypedata[$day]['crashes'] = array();
|
2013-10-31 03:04:05 +04:00
|
|
|
}
|
2013-10-31 03:27:27 +04:00
|
|
|
if ($crashes && ($type != 'Hang Browser')) {
|
2013-10-31 03:07:06 +04:00
|
|
|
$prodtypedata[$day]['crashes'][$type] = $crashes;
|
2013-10-31 03:04:05 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (is_null($maxday) || $maxday < $day) { $maxday = $day; }
|
|
|
|
}
|
|
|
|
if ($maxday < $day_end) {
|
|
|
|
print('--- ERROR: Last day retrieved is '.$maxday.' while yesterday was '.$day_end.'!'."\n");
|
|
|
|
}
|
|
|
|
file_put_contents($fprodtypedata, json_encode($prodtypedata));
|
|
|
|
}
|
|
|
|
}
|
2013-04-20 18:41:38 +04:00
|
|
|
print("\n");
|
2012-02-17 21:50:54 +04:00
|
|
|
?>
|