Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Side by Side Diff: components/browser_watcher/watcher_metrics_provider_win.cc

Issue 2344343002: Wire in postmortem report collection (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/browser_watcher/watcher_metrics_provider_win.h" 5 #include "components/browser_watcher/watcher_metrics_provider_win.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <limits> 9 #include <limits>
10 #include <memory>
11 #include <set>
10 #include <vector> 12 #include <vector>
11 13
12 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/feature_list.h"
16 #include "base/metrics/histogram_macros.h"
13 #include "base/metrics/sparse_histogram.h" 17 #include "base/metrics/sparse_histogram.h"
14 #include "base/process/process.h" 18 #include "base/process/process.h"
15 #include "base/strings/string_number_conversions.h" 19 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_piece.h" 20 #include "base/strings/string_piece.h"
17 #include "base/strings/utf_string_conversions.h" 21 #include "base/strings/utf_string_conversions.h"
18 #include "base/win/registry.h" 22 #include "base/win/registry.h"
23 #include "components/browser_watcher/features.h"
24 #include "components/browser_watcher/postmortem_report_collector.h"
25 #include "components/browser_watcher/stability_debugging_win.h"
26 #include "third_party/crashpad/crashpad/client/crash_report_database.h"
19 27
20 namespace browser_watcher { 28 namespace browser_watcher {
21 29
22 namespace { 30 namespace {
23 31
24 // Process ID APIs on Windows talk in DWORDs, whereas for string formatting 32 // Process ID APIs on Windows talk in DWORDs, whereas for string formatting
25 // and parsing, this code uses int. In practice there are no process IDs with 33 // and parsing, this code uses int. In practice there are no process IDs with
26 // the high bit set on Windows, so there's no danger of overflow if this is 34 // the high bit set on Windows, so there's no danger of overflow if this is
27 // done consistently. 35 // done consistently.
28 static_assert(sizeof(DWORD) == sizeof(int), 36 static_assert(sizeof(DWORD) == sizeof(int),
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 DVLOG(1) << "Failed to delete exit code key " << registry_path; 193 DVLOG(1) << "Failed to delete exit code key " << registry_path;
186 } 194 }
187 195
188 } // namespace 196 } // namespace
189 197
190 const char WatcherMetricsProviderWin::kBrowserExitCodeHistogramName[] = 198 const char WatcherMetricsProviderWin::kBrowserExitCodeHistogramName[] =
191 "Stability.BrowserExitCodes"; 199 "Stability.BrowserExitCodes";
192 200
193 WatcherMetricsProviderWin::WatcherMetricsProviderWin( 201 WatcherMetricsProviderWin::WatcherMetricsProviderWin(
194 const base::string16& registry_path, 202 const base::string16& registry_path,
195 base::TaskRunner* cleanup_io_task_runner) 203 const base::FilePath& user_data_dir,
204 const base::FilePath& crash_dir,
205 base::TaskRunner* io_task_runner)
196 : recording_enabled_(false), 206 : recording_enabled_(false),
197 cleanup_scheduled_(false), 207 cleanup_scheduled_(false),
198 registry_path_(registry_path), 208 registry_path_(registry_path),
199 cleanup_io_task_runner_(cleanup_io_task_runner) { 209 user_data_dir_(user_data_dir),
200 DCHECK(cleanup_io_task_runner_); 210 crash_dir_(crash_dir),
211 io_task_runner_(io_task_runner),
212 weak_ptr_factory_(this) {
213 DCHECK(io_task_runner_);
201 } 214 }
202 215
203 WatcherMetricsProviderWin::~WatcherMetricsProviderWin() { 216 WatcherMetricsProviderWin::~WatcherMetricsProviderWin() {
204 } 217 }
205 218
206 void WatcherMetricsProviderWin::OnRecordingEnabled() { 219 void WatcherMetricsProviderWin::OnRecordingEnabled() {
207 recording_enabled_ = true; 220 recording_enabled_ = true;
208 } 221 }
209 222
210 void WatcherMetricsProviderWin::OnRecordingDisabled() { 223 void WatcherMetricsProviderWin::OnRecordingDisabled() {
211 if (!recording_enabled_ && !cleanup_scheduled_) { 224 if (!recording_enabled_ && !cleanup_scheduled_) {
212 // When metrics reporting is disabled, the providers get an 225 // When metrics reporting is disabled, the providers get an
213 // OnRecordingDisabled notification at startup. Use that first notification 226 // OnRecordingDisabled notification at startup. Use that first notification
214 // to issue the cleanup task. 227 // to issue the cleanup task.
215 cleanup_io_task_runner_->PostTask( 228 io_task_runner_->PostTask(
216 FROM_HERE, base::Bind(&DeleteExitCodeRegistryKey, registry_path_)); 229 FROM_HERE, base::Bind(&DeleteExitCodeRegistryKey, registry_path_));
217 230
218 cleanup_scheduled_ = true; 231 cleanup_scheduled_ = true;
219 } 232 }
220 } 233 }
221 234
222 void WatcherMetricsProviderWin::ProvideStabilityMetrics( 235 void WatcherMetricsProviderWin::ProvideStabilityMetrics(
223 metrics::SystemProfileProto* /* system_profile_proto */) { 236 metrics::SystemProfileProto* /* system_profile_proto */) {
224 // Note that if there are multiple instances of Chrome running in the same 237 // Note that if there are multiple instances of Chrome running in the same
225 // user account, there's a small race that will double-report the exit codes 238 // user account, there's a small race that will double-report the exit codes
226 // from both/multiple instances. This ought to be vanishingly rare and will 239 // from both/multiple instances. This ought to be vanishingly rare and will
227 // only manifest as low-level "random" noise. To work around this it would be 240 // only manifest as low-level "random" noise. To work around this it would be
228 // necessary to implement some form of global locking, which is not worth it 241 // necessary to implement some form of global locking, which is not worth it
229 // here. 242 // here.
230 RecordExitCodes(registry_path_); 243 RecordExitCodes(registry_path_);
231 DeleteExitFunnels(registry_path_); 244 DeleteExitFunnels(registry_path_);
232 } 245 }
233 246
247 void WatcherMetricsProviderWin::CollectPostmortemReports(
248 const base::Closure& done_callback) {
249 io_task_runner_->PostTaskAndReply(
250 FROM_HERE,
251 base::Bind(
252 &WatcherMetricsProviderWin::CollectPostmortemReportsOnBlockingPool,
253 weak_ptr_factory_.GetWeakPtr()),
254 done_callback);
255 }
256
257 void WatcherMetricsProviderWin::CollectPostmortemReportsOnBlockingPool() {
258 // Note: the feature controls both instrumentation and collection.
259 bool is_stability_debugging_on =
260 base::FeatureList::IsEnabled(browser_watcher::kStabilityDebuggingFeature);
261 if (!is_stability_debugging_on) {
262 // TODO(manzagop): delete possible leftover data.
263 return;
264 }
265
266 SCOPED_UMA_HISTOGRAM_TIMER("ActivityTracker.Collect.TotalTime");
267
268 if (user_data_dir_.empty() || crash_dir_.empty()) {
269 LOG(ERROR) << "User data directory or crash directory is unknown.";
Sigurður Ásgeirsson 2016/09/19 14:20:05 I would suggest a second UMA metric to count failu
manzagop (departed) 2016/09/21 22:00:43 Done.
270 return;
271 }
272
273 // Determine the stability directory and the stability file for the current
274 // process.
275 base::FilePath stability_dir = StabilityDebugging::GetDir(user_data_dir_);
276 base::FilePath current_stability_file;
277 if (!StabilityDebugging::GetFileForProcess(
278 base::Process::Current(), user_data_dir_, &current_stability_file)) {
279 LOG(ERROR) << "Failed to get the current stability file.";
280 return;
281 }
282 const std::set<base::FilePath>& excluded_debug_files = {
283 current_stability_file};
284
285 // Create a database. Note: Chrome already has a g_database in crashpad.cc but
286 // it has internal linkage. Create a new one.
287 std::unique_ptr<crashpad::CrashReportDatabase> crashpad_database =
288 crashpad::CrashReportDatabase::InitializeWithoutCreating(crash_dir_);
289 if (!crashpad_database) {
290 LOG(ERROR) << "Failed to initialize a CrashPad database.";
291 return;
292 }
293
294 // TODO(manzagop): fix incorrect version attribution on update.
295 PostmortemReportCollector collector;
296 collector.CollectAndSubmitForUpload(
297 stability_dir, StabilityDebugging::GetFilePattern(), excluded_debug_files,
298 crashpad_database.get());
299 }
300
234 } // namespace browser_watcher 301 } // namespace browser_watcher
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698