Chromium Code Reviews| Index: components/browser_watcher/watcher_metrics_provider_win.cc |
| diff --git a/components/browser_watcher/watcher_metrics_provider_win.cc b/components/browser_watcher/watcher_metrics_provider_win.cc |
| index efe177bb998905a42ad20de208bb3860e567963d..cdadb44155f2e9d0411807170f70b0f73ddbe111 100644 |
| --- a/components/browser_watcher/watcher_metrics_provider_win.cc |
| +++ b/components/browser_watcher/watcher_metrics_provider_win.cc |
| @@ -7,15 +7,25 @@ |
| #include <stddef.h> |
| #include <limits> |
| +#include <memory> |
| +#include <set> |
| #include <vector> |
| #include "base/bind.h" |
| +#include "base/feature_list.h" |
| +#include "base/metrics/histogram.h" |
| +#include "base/metrics/histogram_base.h" |
| +#include "base/metrics/histogram_macros.h" |
| #include "base/metrics/sparse_histogram.h" |
| #include "base/process/process.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/string_piece.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/win/registry.h" |
| +#include "components/browser_watcher/features.h" |
| +#include "components/browser_watcher/postmortem_report_collector.h" |
| +#include "components/browser_watcher/stability_debugging_win.h" |
| +#include "third_party/crashpad/crashpad/client/crash_report_database.h" |
| namespace browser_watcher { |
| @@ -185,6 +195,22 @@ void DeleteExitCodeRegistryKey(const base::string16& registry_path) { |
| DVLOG(1) << "Failed to delete exit code key " << registry_path; |
| } |
| +enum CollectionInitializationStatus { |
| + INIT_SUCCESS = 0, |
| + UNKNOWN_DIR = 1, |
| + GET_STABILITY_FILE_PATH_FAILED = 2, |
| + CRASHPAD_DATABASE_INIT_FAILED = 3, |
| + INIT_STATUS_MAX = 4 |
| +}; |
| + |
| +void LogCollectionInitStatusWithoutStaticVar( |
| + CollectionInitializationStatus status) { |
| + base::HistogramBase* init_status_hist = base::LinearHistogram::FactoryGet( |
| + "ActivityTracker.Collect.InitStatus", 1, INIT_STATUS_MAX, |
| + INIT_STATUS_MAX + 1, base::HistogramBase::kUmaTargetedHistogramFlag); |
|
Sigurður Ásgeirsson
2016/09/22 15:46:14
same comment here.
manzagop (departed)
2016/09/23 21:57:01
Done.
|
| + init_status_hist->Add(status); |
| +} |
| + |
| } // namespace |
| const char WatcherMetricsProviderWin::kBrowserExitCodeHistogramName[] = |
| @@ -192,12 +218,17 @@ const char WatcherMetricsProviderWin::kBrowserExitCodeHistogramName[] = |
| WatcherMetricsProviderWin::WatcherMetricsProviderWin( |
| const base::string16& registry_path, |
| - base::TaskRunner* cleanup_io_task_runner) |
| + const base::FilePath& user_data_dir, |
| + const base::FilePath& crash_dir, |
| + base::TaskRunner* io_task_runner) |
| : recording_enabled_(false), |
| cleanup_scheduled_(false), |
| registry_path_(registry_path), |
| - cleanup_io_task_runner_(cleanup_io_task_runner) { |
| - DCHECK(cleanup_io_task_runner_); |
| + user_data_dir_(user_data_dir), |
| + crash_dir_(crash_dir), |
| + io_task_runner_(io_task_runner), |
| + weak_ptr_factory_(this) { |
| + DCHECK(io_task_runner_); |
| } |
| WatcherMetricsProviderWin::~WatcherMetricsProviderWin() { |
| @@ -212,7 +243,7 @@ void WatcherMetricsProviderWin::OnRecordingDisabled() { |
| // When metrics reporting is disabled, the providers get an |
| // OnRecordingDisabled notification at startup. Use that first notification |
| // to issue the cleanup task. |
| - cleanup_io_task_runner_->PostTask( |
| + io_task_runner_->PostTask( |
| FROM_HERE, base::Bind(&DeleteExitCodeRegistryKey, registry_path_)); |
| cleanup_scheduled_ = true; |
| @@ -231,4 +262,65 @@ void WatcherMetricsProviderWin::ProvideStabilityMetrics( |
| DeleteExitFunnels(registry_path_); |
| } |
| +void WatcherMetricsProviderWin::CollectPostmortemReports( |
| + const base::Closure& done_callback) { |
| + io_task_runner_->PostTaskAndReply( |
| + FROM_HERE, |
| + base::Bind( |
| + &WatcherMetricsProviderWin::CollectPostmortemReportsOnBlockingPool, |
| + weak_ptr_factory_.GetWeakPtr()), |
| + done_callback); |
| +} |
| + |
| +void WatcherMetricsProviderWin::CollectPostmortemReportsOnBlockingPool() { |
| + // Note: the feature controls both instrumentation and collection. |
| + bool is_stability_debugging_on = |
| + base::FeatureList::IsEnabled(browser_watcher::kStabilityDebuggingFeature); |
| + if (!is_stability_debugging_on) { |
| + // TODO(manzagop): delete possible leftover data. |
| + return; |
| + } |
| + |
| + SCOPED_UMA_HISTOGRAM_TIMER("ActivityTracker.Collect.TotalTime"); |
| + |
| + if (user_data_dir_.empty() || crash_dir_.empty()) { |
| + LOG(ERROR) << "User data directory or crash directory is unknown."; |
| + LogCollectionInitStatusWithoutStaticVar(UNKNOWN_DIR); |
| + return; |
| + } |
| + |
| + // Determine the stability directory and the stability file for the current |
| + // process. |
| + base::FilePath stability_dir = StabilityDebugging::GetDir(user_data_dir_); |
| + base::FilePath current_stability_file; |
| + if (!StabilityDebugging::GetFileForProcess( |
| + base::Process::Current(), user_data_dir_, ¤t_stability_file)) { |
| + LOG(ERROR) << "Failed to get the current stability file."; |
| + LogCollectionInitStatusWithoutStaticVar(GET_STABILITY_FILE_PATH_FAILED); |
| + return; |
| + } |
| + const std::set<base::FilePath>& excluded_debug_files = { |
| + current_stability_file}; |
| + |
| + // Create a database. Note: Chrome already has a g_database in crashpad.cc but |
| + // it has internal linkage. Create a new one. |
| + std::unique_ptr<crashpad::CrashReportDatabase> crashpad_database = |
| + crashpad::CrashReportDatabase::InitializeWithoutCreating(crash_dir_); |
| + if (!crashpad_database) { |
| + LOG(ERROR) << "Failed to initialize a CrashPad database."; |
| + LogCollectionInitStatusWithoutStaticVar(CRASHPAD_DATABASE_INIT_FAILED); |
| + return; |
| + } |
| + |
| + // Note: not caching the histogram pointer as this function isn't expected to |
| + // be called multiple times. |
| + LogCollectionInitStatusWithoutStaticVar(INIT_SUCCESS); |
| + |
| + // TODO(manzagop): fix incorrect version attribution on update. |
| + PostmortemReportCollector collector; |
| + collector.CollectAndSubmitForUpload( |
| + stability_dir, StabilityDebugging::GetFilePattern(), excluded_debug_files, |
| + crashpad_database.get()); |
| +} |
| + |
| } // namespace browser_watcher |