OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 //------------------------------------------------------------------------------ | 5 //------------------------------------------------------------------------------ |
6 // Description of the life cycle of a instance of MetricsService. | 6 // Description of the life cycle of a instance of MetricsService. |
7 // | 7 // |
8 // OVERVIEW | 8 // OVERVIEW |
9 // | 9 // |
10 // A MetricsService instance is typically created at application startup. It is | 10 // A MetricsService instance is typically created at application startup. It is |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 #include "base/strings/utf_string_conversions.h" | 178 #include "base/strings/utf_string_conversions.h" |
179 #include "base/threading/platform_thread.h" | 179 #include "base/threading/platform_thread.h" |
180 #include "base/threading/thread.h" | 180 #include "base/threading/thread.h" |
181 #include "base/threading/thread_restrictions.h" | 181 #include "base/threading/thread_restrictions.h" |
182 #include "base/tracked_objects.h" | 182 #include "base/tracked_objects.h" |
183 #include "base/values.h" | 183 #include "base/values.h" |
184 #include "chrome/browser/browser_process.h" | 184 #include "chrome/browser/browser_process.h" |
185 #include "chrome/browser/chrome_notification_types.h" | 185 #include "chrome/browser/chrome_notification_types.h" |
186 #include "chrome/browser/io_thread.h" | 186 #include "chrome/browser/io_thread.h" |
187 #include "chrome/browser/memory_details.h" | 187 #include "chrome/browser/memory_details.h" |
| 188 #include "chrome/browser/metrics/chrome_stability_metrics_provider.h" |
188 #include "chrome/browser/metrics/compression_utils.h" | 189 #include "chrome/browser/metrics/compression_utils.h" |
189 #include "chrome/browser/metrics/metrics_log.h" | 190 #include "chrome/browser/metrics/metrics_log.h" |
190 #include "chrome/browser/metrics/metrics_state_manager.h" | 191 #include "chrome/browser/metrics/metrics_state_manager.h" |
191 #include "chrome/browser/metrics/omnibox_metrics_provider.h" | 192 #include "chrome/browser/metrics/omnibox_metrics_provider.h" |
192 #include "chrome/browser/metrics/time_ticks_experiment_win.h" | 193 #include "chrome/browser/metrics/time_ticks_experiment_win.h" |
193 #include "chrome/browser/metrics/tracking_synchronizer.h" | 194 #include "chrome/browser/metrics/tracking_synchronizer.h" |
194 #include "chrome/browser/net/http_pipelining_compatibility_client.h" | 195 #include "chrome/browser/net/http_pipelining_compatibility_client.h" |
195 #include "chrome/browser/net/network_stats.h" | 196 #include "chrome/browser/net/network_stats.h" |
196 #include "chrome/browser/ui/browser_otr_state.h" | 197 #include "chrome/browser/ui/browser_otr_state.h" |
197 #include "chrome/common/chrome_constants.h" | 198 #include "chrome/common/chrome_constants.h" |
(...skipping 11 matching lines...) Expand all Loading... |
209 #include "content/public/browser/child_process_data.h" | 210 #include "content/public/browser/child_process_data.h" |
210 #include "content/public/browser/histogram_fetcher.h" | 211 #include "content/public/browser/histogram_fetcher.h" |
211 #include "content/public/browser/load_notification_details.h" | 212 #include "content/public/browser/load_notification_details.h" |
212 #include "content/public/browser/notification_service.h" | 213 #include "content/public/browser/notification_service.h" |
213 #include "content/public/browser/plugin_service.h" | 214 #include "content/public/browser/plugin_service.h" |
214 #include "content/public/browser/render_process_host.h" | 215 #include "content/public/browser/render_process_host.h" |
215 #include "content/public/browser/user_metrics.h" | 216 #include "content/public/browser/user_metrics.h" |
216 #include "content/public/browser/web_contents.h" | 217 #include "content/public/browser/web_contents.h" |
217 #include "content/public/common/process_type.h" | 218 #include "content/public/common/process_type.h" |
218 #include "content/public/common/webplugininfo.h" | 219 #include "content/public/common/webplugininfo.h" |
219 #include "extensions/browser/process_map.h" | |
220 #include "net/base/load_flags.h" | 220 #include "net/base/load_flags.h" |
221 #include "net/url_request/url_fetcher.h" | 221 #include "net/url_request/url_fetcher.h" |
222 | 222 |
223 // TODO(port): port browser_distribution.h. | 223 // TODO(port): port browser_distribution.h. |
224 #if !defined(OS_POSIX) | 224 #if !defined(OS_POSIX) |
225 #include "chrome/installer/util/browser_distribution.h" | 225 #include "chrome/installer/util/browser_distribution.h" |
226 #endif | 226 #endif |
227 | 227 |
228 #if defined(OS_CHROMEOS) | 228 #if defined(OS_CHROMEOS) |
229 #include "chrome/browser/chromeos/settings/cros_settings.h" | 229 #include "chrome/browser/chromeos/settings/cros_settings.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 return SUCCESS; | 298 return SUCCESS; |
299 case 400: | 299 case 400: |
300 return BAD_REQUEST; | 300 return BAD_REQUEST; |
301 case net::URLFetcher::RESPONSE_CODE_INVALID: | 301 case net::URLFetcher::RESPONSE_CODE_INVALID: |
302 return NO_RESPONSE; | 302 return NO_RESPONSE; |
303 default: | 303 default: |
304 return UNKNOWN_FAILURE; | 304 return UNKNOWN_FAILURE; |
305 } | 305 } |
306 } | 306 } |
307 | 307 |
308 // Converts an exit code into something that can be inserted into our | |
309 // histograms (which expect non-negative numbers less than MAX_INT). | |
310 int MapCrashExitCodeForHistogram(int exit_code) { | |
311 #if defined(OS_WIN) | |
312 // Since |abs(STATUS_GUARD_PAGE_VIOLATION) == MAX_INT| it causes problems in | |
313 // histograms.cc. Solve this by remapping it to a smaller value, which | |
314 // hopefully doesn't conflict with other codes. | |
315 if (exit_code == STATUS_GUARD_PAGE_VIOLATION) | |
316 return 0x1FCF7EC3; // Randomly picked number. | |
317 #endif | |
318 | |
319 return std::abs(exit_code); | |
320 } | |
321 | |
322 void MarkAppCleanShutdownAndCommit() { | 308 void MarkAppCleanShutdownAndCommit() { |
323 PrefService* pref = g_browser_process->local_state(); | 309 PrefService* pref = g_browser_process->local_state(); |
324 pref->SetBoolean(prefs::kStabilityExitedCleanly, true); | 310 pref->SetBoolean(prefs::kStabilityExitedCleanly, true); |
325 pref->SetInteger(prefs::kStabilityExecutionPhase, | 311 pref->SetInteger(prefs::kStabilityExecutionPhase, |
326 MetricsService::SHUTDOWN_COMPLETE); | 312 MetricsService::SHUTDOWN_COMPLETE); |
327 // Start writing right away (write happens on a different thread). | 313 // Start writing right away (write happens on a different thread). |
328 pref->CommitPendingWrite(); | 314 pref->CommitPendingWrite(); |
329 } | 315 } |
330 | 316 |
331 } // namespace | 317 } // namespace |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 state_saver_factory_(this), | 462 state_saver_factory_(this), |
477 waiting_for_asynchronous_reporting_step_(false), | 463 waiting_for_asynchronous_reporting_step_(false), |
478 num_async_histogram_fetches_in_progress_(0) { | 464 num_async_histogram_fetches_in_progress_(0) { |
479 DCHECK(IsSingleThreaded()); | 465 DCHECK(IsSingleThreaded()); |
480 DCHECK(state_manager_); | 466 DCHECK(state_manager_); |
481 DCHECK(client_); | 467 DCHECK(client_); |
482 | 468 |
483 // TODO(asvitkine): Move this out of MetricsService. | 469 // TODO(asvitkine): Move this out of MetricsService. |
484 RegisterMetricsProvider( | 470 RegisterMetricsProvider( |
485 scoped_ptr<metrics::MetricsProvider>(new OmniboxMetricsProvider)); | 471 scoped_ptr<metrics::MetricsProvider>(new OmniboxMetricsProvider)); |
| 472 RegisterMetricsProvider( |
| 473 scoped_ptr<metrics::MetricsProvider>(new ChromeStabilityMetricsProvider)); |
486 | 474 |
487 BrowserChildProcessObserver::Add(this); | 475 BrowserChildProcessObserver::Add(this); |
488 } | 476 } |
489 | 477 |
490 MetricsService::~MetricsService() { | 478 MetricsService::~MetricsService() { |
491 DisableRecording(); | 479 DisableRecording(); |
492 | 480 |
493 BrowserChildProcessObserver::Remove(this); | 481 BrowserChildProcessObserver::Remove(this); |
494 } | 482 } |
495 | 483 |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 const content::NotificationDetails& details) { | 633 const content::NotificationDetails& details) { |
646 DCHECK(log_manager_.current_log()); | 634 DCHECK(log_manager_.current_log()); |
647 DCHECK(IsSingleThreaded()); | 635 DCHECK(IsSingleThreaded()); |
648 | 636 |
649 switch (type) { | 637 switch (type) { |
650 case chrome::NOTIFICATION_BROWSER_OPENED: | 638 case chrome::NOTIFICATION_BROWSER_OPENED: |
651 case chrome::NOTIFICATION_BROWSER_CLOSED: | 639 case chrome::NOTIFICATION_BROWSER_CLOSED: |
652 case chrome::NOTIFICATION_OMNIBOX_OPENED_URL: | 640 case chrome::NOTIFICATION_OMNIBOX_OPENED_URL: |
653 case chrome::NOTIFICATION_TAB_PARENTED: | 641 case chrome::NOTIFICATION_TAB_PARENTED: |
654 case chrome::NOTIFICATION_TAB_CLOSING: | 642 case chrome::NOTIFICATION_TAB_CLOSING: |
| 643 case content::NOTIFICATION_LOAD_START: |
655 case content::NOTIFICATION_LOAD_STOP: | 644 case content::NOTIFICATION_LOAD_STOP: |
| 645 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: |
| 646 case content::NOTIFICATION_RENDER_WIDGET_HOST_HANG: |
656 // These notifications are used only to break out of idle mode. | 647 // These notifications are used only to break out of idle mode. |
657 break; | 648 break; |
658 | |
659 case content::NOTIFICATION_LOAD_START: { | |
660 content::NavigationController* controller = | |
661 content::Source<content::NavigationController>(source).ptr(); | |
662 content::WebContents* web_contents = controller->GetWebContents(); | |
663 LogLoadStarted(web_contents); | |
664 break; | |
665 } | |
666 | |
667 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { | |
668 content::RenderProcessHost::RendererClosedDetails* process_details = | |
669 content::Details< | |
670 content::RenderProcessHost::RendererClosedDetails>( | |
671 details).ptr(); | |
672 content::RenderProcessHost* host = | |
673 content::Source<content::RenderProcessHost>(source).ptr(); | |
674 LogRendererCrash( | |
675 host, process_details->status, process_details->exit_code); | |
676 break; | |
677 } | |
678 | |
679 case content::NOTIFICATION_RENDER_WIDGET_HOST_HANG: | |
680 LogRendererHang(); | |
681 break; | |
682 | |
683 default: | 649 default: |
684 NOTREACHED(); | 650 NOTREACHED(); |
685 break; | 651 break; |
686 } | 652 } |
687 | 653 |
688 HandleIdleSinceLastTransmission(false); | 654 HandleIdleSinceLastTransmission(false); |
689 } | 655 } |
690 | 656 |
691 void MetricsService::HandleIdleSinceLastTransmission(bool in_idle) { | 657 void MetricsService::HandleIdleSinceLastTransmission(bool in_idle) { |
692 // If there wasn't a lot of action, maybe the computer was asleep, in which | 658 // If there wasn't a lot of action, maybe the computer was asleep, in which |
(...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1658 pref->SetInteger(path, value + 1); | 1624 pref->SetInteger(path, value + 1); |
1659 } | 1625 } |
1660 | 1626 |
1661 void MetricsService::IncrementLongPrefsValue(const char* path) { | 1627 void MetricsService::IncrementLongPrefsValue(const char* path) { |
1662 PrefService* pref = g_browser_process->local_state(); | 1628 PrefService* pref = g_browser_process->local_state(); |
1663 DCHECK(pref); | 1629 DCHECK(pref); |
1664 int64 value = pref->GetInt64(path); | 1630 int64 value = pref->GetInt64(path); |
1665 pref->SetInt64(path, value + 1); | 1631 pref->SetInt64(path, value + 1); |
1666 } | 1632 } |
1667 | 1633 |
1668 void MetricsService::LogLoadStarted(content::WebContents* web_contents) { | |
1669 content::RecordAction(base::UserMetricsAction("PageLoad")); | |
1670 HISTOGRAM_ENUMERATION("Chrome.UmaPageloadCounter", 1, 2); | |
1671 IncrementPrefValue(prefs::kStabilityPageLoadCount); | |
1672 IncrementLongPrefsValue(prefs::kUninstallMetricsPageLoadCount); | |
1673 // We need to save the prefs, as page load count is a critical stat, and it | |
1674 // might be lost due to a crash :-(. | |
1675 } | |
1676 | |
1677 void MetricsService::LogRendererCrash(content::RenderProcessHost* host, | |
1678 base::TerminationStatus status, | |
1679 int exit_code) { | |
1680 bool was_extension_process = | |
1681 extensions::ProcessMap::Get(host->GetBrowserContext()) | |
1682 ->Contains(host->GetID()); | |
1683 if (status == base::TERMINATION_STATUS_PROCESS_CRASHED || | |
1684 status == base::TERMINATION_STATUS_ABNORMAL_TERMINATION) { | |
1685 if (was_extension_process) { | |
1686 IncrementPrefValue(prefs::kStabilityExtensionRendererCrashCount); | |
1687 | |
1688 UMA_HISTOGRAM_SPARSE_SLOWLY("CrashExitCodes.Extension", | |
1689 MapCrashExitCodeForHistogram(exit_code)); | |
1690 } else { | |
1691 IncrementPrefValue(prefs::kStabilityRendererCrashCount); | |
1692 | |
1693 UMA_HISTOGRAM_SPARSE_SLOWLY("CrashExitCodes.Renderer", | |
1694 MapCrashExitCodeForHistogram(exit_code)); | |
1695 } | |
1696 | |
1697 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildCrashes", | |
1698 was_extension_process ? 2 : 1); | |
1699 } else if (status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED) { | |
1700 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildKills", | |
1701 was_extension_process ? 2 : 1); | |
1702 } else if (status == base::TERMINATION_STATUS_STILL_RUNNING) { | |
1703 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.DisconnectedAlive", | |
1704 was_extension_process ? 2 : 1); | |
1705 } | |
1706 } | |
1707 | |
1708 void MetricsService::LogRendererHang() { | |
1709 IncrementPrefValue(prefs::kStabilityRendererHangCount); | |
1710 } | |
1711 | |
1712 bool MetricsService::UmaMetricsProperlyShutdown() { | 1634 bool MetricsService::UmaMetricsProperlyShutdown() { |
1713 CHECK(clean_shutdown_status_ == CLEANLY_SHUTDOWN || | 1635 CHECK(clean_shutdown_status_ == CLEANLY_SHUTDOWN || |
1714 clean_shutdown_status_ == NEED_TO_SHUTDOWN); | 1636 clean_shutdown_status_ == NEED_TO_SHUTDOWN); |
1715 return clean_shutdown_status_ == CLEANLY_SHUTDOWN; | 1637 return clean_shutdown_status_ == CLEANLY_SHUTDOWN; |
1716 } | 1638 } |
1717 | 1639 |
1718 void MetricsService::RegisterSyntheticFieldTrial( | 1640 void MetricsService::RegisterSyntheticFieldTrial( |
1719 const SyntheticTrialGroup& trial) { | 1641 const SyntheticTrialGroup& trial) { |
1720 for (size_t i = 0; i < synthetic_trial_groups_.size(); ++i) { | 1642 for (size_t i = 0; i < synthetic_trial_groups_.size(); ++i) { |
1721 if (synthetic_trial_groups_[i].id.name == trial.id.name) { | 1643 if (synthetic_trial_groups_[i].id.name == trial.id.name) { |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1972 if (metrics_service) | 1894 if (metrics_service) |
1973 metrics_service->AddObserver(observer); | 1895 metrics_service->AddObserver(observer); |
1974 } | 1896 } |
1975 | 1897 |
1976 void MetricsServiceHelper::RemoveMetricsServiceObserver( | 1898 void MetricsServiceHelper::RemoveMetricsServiceObserver( |
1977 MetricsServiceObserver* observer) { | 1899 MetricsServiceObserver* observer) { |
1978 MetricsService* metrics_service = g_browser_process->metrics_service(); | 1900 MetricsService* metrics_service = g_browser_process->metrics_service(); |
1979 if (metrics_service) | 1901 if (metrics_service) |
1980 metrics_service->RemoveObserver(observer); | 1902 metrics_service->RemoveObserver(observer); |
1981 } | 1903 } |
OLD | NEW |