Merge pull request #1882 from atom/get_uploaded_report_api

Implement crash-reporter.getUploadedReports API
This commit is contained in:
Cheng Zhao 2015-06-09 16:35:08 +08:00
commit 4c48f0cd36
6 changed files with 56 additions and 33 deletions

View file

@ -41,23 +41,22 @@ class CrashReporter
start() start()
getLastCrashReport: -> getLastCrashReport: ->
if process.platform is 'darwin' reports = this.getUploadedReports()
reports = binding._getUploadedReports() if reports.length > 0 then reports[0] else null
return if reports.length > 0 then reports[0] else null
getUploadedReports: ->
tmpdir = tmpdir =
if process.platform is 'win32' if process.platform is 'win32'
os.tmpdir() os.tmpdir()
else else
'/tmp' '/tmp'
log = path.join tmpdir, "#{@productName} Crashes", 'uploads.log' log =
try if process.platform is 'darwin'
reports = String(fs.readFileSync(log)).split('\n') path.join tmpdir, "#{@productName} Crashes"
return null unless reports.length > 1 else
[time, id] = reports[reports.length - 2].split ',' path.join tmpdir, "#{@productName} Crashes", 'uploads.log'
return {date: new Date(parseInt(time) * 1000), id} binding._getUploadedReports log
catch e
return null
crashRepoter = new CrashReporter crashRepoter = new CrashReporter
module.exports = crashRepoter module.exports = crashRepoter

View file

@ -7,6 +7,9 @@
#include "atom/browser/browser.h" #include "atom/browser/browser.h"
#include "atom/common/atom_version.h" #include "atom/common/atom_version.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/strings/string_split.h"
#include "base/strings/string_number_conversions.h"
#include "content/public/common/content_switches.h" #include "content/public/common/content_switches.h"
namespace crash_reporter { namespace crash_reporter {
@ -40,8 +43,24 @@ void CrashReporter::SetUploadParameters(const StringMap& parameters) {
} }
std::vector<CrashReporter::UploadReportResult> std::vector<CrashReporter::UploadReportResult>
CrashReporter::GetUploadedReports() { CrashReporter::GetUploadedReports(const std::string& path) {
return std::vector<CrashReporter::UploadReportResult>(); std::string file_content;
std::vector<CrashReporter::UploadReportResult> result;
if (base::ReadFileToString(base::FilePath(path), &file_content)) {
std::vector<std::string> reports;
base::SplitString(file_content, '\n', &reports);
for (const std::string& report : reports) {
std::vector<std::string> report_item;
base::SplitString(report, ',', &report_item);
int report_time = 0;
if (report_item.size() >= 2 && base::StringToInt(report_item[0],
&report_time)) {
result.push_back(CrashReporter::UploadReportResult(report_time,
report_item[1]));
}
}
}
return result;
} }
} // namespace crash_reporter } // namespace crash_reporter

View file

@ -28,7 +28,8 @@ class CrashReporter {
bool skip_system_crash_handler, bool skip_system_crash_handler,
const StringMap& extra_parameters); const StringMap& extra_parameters);
virtual std::vector<CrashReporter::UploadReportResult> GetUploadedReports(); virtual std::vector<CrashReporter::UploadReportResult> GetUploadedReports(
const std::string& path);
protected: protected:
CrashReporter(); CrashReporter();

View file

@ -16,10 +16,6 @@
template <typename T> struct DefaultSingletonTraits; template <typename T> struct DefaultSingletonTraits;
namespace crashpad {
class CrashReportDatabase;
}
namespace crash_reporter { namespace crash_reporter {
class CrashReporterMac : public CrashReporter { class CrashReporterMac : public CrashReporter {
@ -44,10 +40,10 @@ class CrashReporterMac : public CrashReporter {
void SetCrashKeyValue(const base::StringPiece& key, void SetCrashKeyValue(const base::StringPiece& key,
const base::StringPiece& value); const base::StringPiece& value);
std::vector<UploadReportResult> GetUploadedReports() override; std::vector<UploadReportResult> GetUploadedReports(
const std::string& path) override;
scoped_ptr<crashpad::SimpleStringDictionary> simple_string_dictionary_; scoped_ptr<crashpad::SimpleStringDictionary> simple_string_dictionary_;
scoped_ptr<crashpad::CrashReportDatabase> crash_report_database_;
DISALLOW_COPY_AND_ASSIGN(CrashReporterMac); DISALLOW_COPY_AND_ASSIGN(CrashReporterMac);
}; };

View file

@ -5,6 +5,7 @@
#include "atom/common/crash_reporter/crash_reporter_mac.h" #include "atom/common/crash_reporter/crash_reporter_mac.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/mac/bundle_locations.h" #include "base/mac/bundle_locations.h"
#include "base/mac/mac_util.h" #include "base/mac/mac_util.h"
#include "base/memory/singleton.h" #include "base/memory/singleton.h"
@ -71,9 +72,11 @@ void CrashReporterMac::InitBreakpad(const std::string& product_name,
SetCrashKeyValue(upload_parameter.first, upload_parameter.second); SetCrashKeyValue(upload_parameter.first, upload_parameter.second);
} }
if (is_browser_) { if (is_browser_) {
crash_report_database_ = crashpad::CrashReportDatabase::Initialize( scoped_ptr<crashpad::CrashReportDatabase> database =
database_path); crashpad::CrashReportDatabase::Initialize(database_path);
SetUploadsEnabled(auto_submit); if (database) {
database->GetSettings()->SetUploadsEnabled(auto_submit);
}
} }
} }
@ -81,29 +84,27 @@ void CrashReporterMac::SetUploadParameters() {
upload_parameters_["platform"] = "darwin"; upload_parameters_["platform"] = "darwin";
} }
void CrashReporterMac::SetUploadsEnabled(bool enable_uploads) {
if (crash_report_database_) {
crashpad::Settings* settings = crash_report_database_->GetSettings();
settings->SetUploadsEnabled(enable_uploads);
}
}
void CrashReporterMac::SetCrashKeyValue(const base::StringPiece& key, void CrashReporterMac::SetCrashKeyValue(const base::StringPiece& key,
const base::StringPiece& value) { const base::StringPiece& value) {
simple_string_dictionary_->SetKeyValue(key.data(), value.data()); simple_string_dictionary_->SetKeyValue(key.data(), value.data());
} }
std::vector<CrashReporter::UploadReportResult> std::vector<CrashReporter::UploadReportResult>
CrashReporterMac::GetUploadedReports() { CrashReporterMac::GetUploadedReports(const std::string& path) {
std::vector<CrashReporter::UploadReportResult> uploaded_reports; std::vector<CrashReporter::UploadReportResult> uploaded_reports;
if (!crash_report_database_) { base::FilePath file_path(path);
if (!base::PathExists(file_path)) {
return uploaded_reports; return uploaded_reports;
} }
// Load crashpad database.
scoped_ptr<crashpad::CrashReportDatabase> database =
crashpad::CrashReportDatabase::Initialize(file_path);
DCHECK(database);
std::vector<crashpad::CrashReportDatabase::Report> completed_reports; std::vector<crashpad::CrashReportDatabase::Report> completed_reports;
crashpad::CrashReportDatabase::OperationStatus status = crashpad::CrashReportDatabase::OperationStatus status =
crash_report_database_->GetCompletedReports(&completed_reports); database->GetCompletedReports(&completed_reports);
if (status != crashpad::CrashReportDatabase::kNoError) { if (status != crashpad::CrashReportDatabase::kNoError) {
return uploaded_reports; return uploaded_reports;
} }

View file

@ -27,6 +27,9 @@ crashReporter.start({
* Only string properties are send correctly. * Only string properties are send correctly.
* Nested objects are not supported. * Nested objects are not supported.
Developers are required to call the API before using other crashReporter APIs.
**Note:** On OS X, electron uses a new `crashpad` client, which is different **Note:** On OS X, electron uses a new `crashpad` client, which is different
with the `breakpad` on Windows and Linux. To enable crash collection feature, with the `breakpad` on Windows and Linux. To enable crash collection feature,
you are required to call `crashReporter.start` API to initiliaze `crashpad` in you are required to call `crashReporter.start` API to initiliaze `crashpad` in
@ -37,6 +40,10 @@ main process, even you only collect crash report in renderer process.
Returns the date and ID of last crash report, when there was no crash report Returns the date and ID of last crash report, when there was no crash report
sent or the crash reporter is not started, `null` will be returned. sent or the crash reporter is not started, `null` will be returned.
## crashReporter.getUploadedReports()
Returns all uploaded crash reports, each report contains date and uploaded ID.
# crash-reporter payload # crash-reporter payload
The crash reporter will send the following data to the `submitUrl` as `POST`: The crash reporter will send the following data to the `submitUrl` as `POST`: