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

Side by Side Diff: chrome/browser/metrics/chrome_stability_metrics_provider.cc

Issue 289283011: Introduce ChromeStabilityMetricsProvider (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Response to review Created 6 years, 7 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/metrics/chrome_stability_metrics_provider.h"
6
7 #include <vector>
8
9 #include "base/logging.h"
10 #include "base/metrics/histogram.h"
11 #include "base/metrics/sparse_histogram.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/strings/string_util.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/common/pref_names.h"
17 #include "content/public/browser/notification_service.h"
18 #include "content/public/browser/render_process_host.h"
19 #include "content/public/browser/user_metrics.h"
20 #include "content/public/browser/web_contents.h"
21 #include "extensions/browser/process_map.h"
22
23 #if defined(OS_WIN)
24 #include <windows.h> // Needed for STATUS_* codes
25 #endif
26
27 namespace {
28
29 void IncrementPrefValue(const char* path) {
30 PrefService* pref = g_browser_process->local_state();
31 DCHECK(pref);
32 int value = pref->GetInteger(path);
33 pref->SetInteger(path, value + 1);
34 }
35
36 void IncrementLongPrefsValue(const char* path) {
37 PrefService* pref = g_browser_process->local_state();
38 DCHECK(pref);
39 int64 value = pref->GetInt64(path);
40 pref->SetInt64(path, value + 1);
41 }
42
43 // Converts an exit code into something that can be inserted into our
44 // histograms (which expect non-negative numbers less than MAX_INT).
45 int MapCrashExitCodeForHistogram(int exit_code) {
46 #if defined(OS_WIN)
47 // Since |abs(STATUS_GUARD_PAGE_VIOLATION) == MAX_INT| it causes problems in
48 // histograms.cc. Solve this by remapping it to a smaller value, which
49 // hopefully doesn't conflict with other codes.
50 if (exit_code == STATUS_GUARD_PAGE_VIOLATION)
51 return 0x1FCF7EC3; // Randomly picked number.
52 #endif
53
54 return std::abs(exit_code);
55 }
56
57 } // namespace
58
59 ChromeStabilityMetricsProvider::ChromeStabilityMetricsProvider() {
60 }
61
62 ChromeStabilityMetricsProvider::~ChromeStabilityMetricsProvider() {
63 }
64
65 void ChromeStabilityMetricsProvider::OnRecordingEnabled() {
66 registrar_.Add(this,
67 content::NOTIFICATION_LOAD_START,
68 content::NotificationService::AllSources());
69 registrar_.Add(this,
70 content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
71 content::NotificationService::AllSources());
72 registrar_.Add(this,
73 content::NOTIFICATION_RENDER_WIDGET_HOST_HANG,
74 content::NotificationService::AllSources());
75 }
76
77 void ChromeStabilityMetricsProvider::OnRecordingDisabled() {
78 registrar_.RemoveAll();
79 }
80
81 void ChromeStabilityMetricsProvider::ProvideStabilityMetrics(
82 metrics::SystemProfileProto_Stability* stability_proto) {
83 PrefService* pref = g_browser_process->local_state();
84
85 int count = pref->GetInteger(prefs::kStabilityPageLoadCount);
86 if (count) {
87 stability_proto->set_page_load_count(count);
88 pref->SetInteger(prefs::kStabilityPageLoadCount, 0);
89 }
90
91 count = pref->GetInteger(prefs::kStabilityRendererCrashCount);
92 if (count) {
93 stability_proto->set_renderer_crash_count(count);
94 pref->SetInteger(prefs::kStabilityRendererCrashCount, 0);
95 }
96
97 count = pref->GetInteger(prefs::kStabilityExtensionRendererCrashCount);
98 if (count) {
99 stability_proto->set_extension_renderer_crash_count(count);
100 pref->SetInteger(prefs::kStabilityExtensionRendererCrashCount, 0);
101 }
102
103 count = pref->GetInteger(prefs::kStabilityRendererHangCount);
104 if (count) {
105 stability_proto->set_renderer_hang_count(count);
106 pref->SetInteger(prefs::kStabilityRendererHangCount, 0);
107 }
108 }
109
110 void ChromeStabilityMetricsProvider::Observe(
111 int type,
112 const content::NotificationSource& source,
113 const content::NotificationDetails& details) {
114 switch (type) {
115 case content::NOTIFICATION_LOAD_START: {
116 content::NavigationController* controller =
117 content::Source<content::NavigationController>(source).ptr();
118 content::WebContents* web_contents = controller->GetWebContents();
119 LogLoadStarted(web_contents);
120 break;
121 }
122
123 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
124 content::RenderProcessHost::RendererClosedDetails* process_details =
125 content::Details<content::RenderProcessHost::RendererClosedDetails>(
126 details).ptr();
127 content::RenderProcessHost* host =
128 content::Source<content::RenderProcessHost>(source).ptr();
129 LogRendererCrash(
130 host, process_details->status, process_details->exit_code);
131 break;
132 }
133
134 case content::NOTIFICATION_RENDER_WIDGET_HOST_HANG:
135 LogRendererHang();
136 break;
137
138 default:
139 NOTREACHED();
140 break;
141 }
142 }
143
144 void ChromeStabilityMetricsProvider::LogLoadStarted(
145 content::WebContents* web_contents) {
146 content::RecordAction(base::UserMetricsAction("PageLoad"));
147 HISTOGRAM_ENUMERATION("Chrome.UmaPageloadCounter", 1, 2);
148 IncrementPrefValue(prefs::kStabilityPageLoadCount);
149 IncrementLongPrefsValue(prefs::kUninstallMetricsPageLoadCount);
150 // We need to save the prefs, as page load count is a critical stat, and it
151 // might be lost due to a crash :-(.
152 }
153
154 void ChromeStabilityMetricsProvider::LogRendererCrash(
155 content::RenderProcessHost* host,
156 base::TerminationStatus status,
157 int exit_code) {
158 bool was_extension_process =
159 extensions::ProcessMap::Get(host->GetBrowserContext())
160 ->Contains(host->GetID());
161 if (status == base::TERMINATION_STATUS_PROCESS_CRASHED ||
162 status == base::TERMINATION_STATUS_ABNORMAL_TERMINATION) {
163 if (was_extension_process) {
164 IncrementPrefValue(prefs::kStabilityExtensionRendererCrashCount);
165
166 UMA_HISTOGRAM_SPARSE_SLOWLY("CrashExitCodes.Extension",
167 MapCrashExitCodeForHistogram(exit_code));
168 } else {
169 IncrementPrefValue(prefs::kStabilityRendererCrashCount);
170
171 UMA_HISTOGRAM_SPARSE_SLOWLY("CrashExitCodes.Renderer",
172 MapCrashExitCodeForHistogram(exit_code));
173 }
174
175 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildCrashes",
176 was_extension_process ? 2 : 1);
177 } else if (status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
178 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildKills",
179 was_extension_process ? 2 : 1);
180 } else if (status == base::TERMINATION_STATUS_STILL_RUNNING) {
181 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.DisconnectedAlive",
182 was_extension_process ? 2 : 1);
183 }
184 }
185
186 void ChromeStabilityMetricsProvider::LogRendererHang() {
187 IncrementPrefValue(prefs::kStabilityRendererHangCount);
188 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698