Introduce a MetricsProvider interface.

Also, introduces a way to register MetricsProviders
on MetricsService.

BUG=374229
R=isherman@chromium.org

Review URL: https://codereview.chromium.org/296483004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@271652 0039d316-1c4b-4281-b951-d872f2087c98
parent 6db80a63
......@@ -38,6 +38,7 @@
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/pref_names.h"
#include "chrome/installer/util/google_update_settings.h"
#include "components/metrics/metrics_provider.h"
#include "components/metrics/proto/omnibox_event.pb.h"
#include "components/metrics/proto/profiler_event.pb.h"
#include "components/metrics/proto/system_profile.pb.h"
......@@ -448,7 +449,9 @@ const std::string& MetricsLog::version_extension() {
return g_version_extension.Get();
}
void MetricsLog::RecordStabilityMetrics(base::TimeDelta incremental_uptime,
void MetricsLog::RecordStabilityMetrics(
const std::vector<metrics::MetricsProvider*>& metrics_providers,
base::TimeDelta incremental_uptime,
base::TimeDelta uptime) {
DCHECK(!locked());
DCHECK(HasEnvironment());
......@@ -470,6 +473,11 @@ void MetricsLog::RecordStabilityMetrics(base::TimeDelta incremental_uptime,
// uma log upload, just as we send histogram data.
WriteRealtimeStabilityAttributes(pref, incremental_uptime, uptime);
SystemProfileProto::Stability* stability =
uma_proto()->mutable_system_profile()->mutable_stability();
for (size_t i = 0; i < metrics_providers.size(); ++i)
metrics_providers[i]->ProvideStabilityMetrics(stability);
// Omit some stats unless this is the initial stability log.
if (log_type() != INITIAL_STABILITY_LOG)
return;
......@@ -492,8 +500,6 @@ void MetricsLog::RecordStabilityMetrics(base::TimeDelta incremental_uptime,
// TODO(jar): The following are all optional, so we *could* optimize them for
// values of zero (and not include them).
SystemProfileProto::Stability* stability =
uma_proto()->mutable_system_profile()->mutable_stability();
stability->set_incomplete_shutdown_count(incomplete_shutdown_count);
stability->set_breakpad_registration_success_count(
breakpad_registration_success_count);
......@@ -503,6 +509,12 @@ void MetricsLog::RecordStabilityMetrics(base::TimeDelta incremental_uptime,
stability->set_debugger_not_present_count(debugger_not_present_count);
}
void MetricsLog::RecordGeneralMetrics(
const std::vector<metrics::MetricsProvider*>& metrics_providers) {
for (size_t i = 0; i < metrics_providers.size(); ++i)
metrics_providers[i]->ProvideGeneralMetrics(uma_proto());
}
PrefService* MetricsLog::GetPrefService() {
return g_browser_process->local_state();
}
......@@ -689,6 +701,7 @@ void MetricsLog::WritePluginList(
}
void MetricsLog::RecordEnvironment(
const std::vector<metrics::MetricsProvider*>& metrics_providers,
const std::vector<content::WebPluginInfo>& plugin_list,
const GoogleUpdateMetrics& google_update_metrics,
const std::vector<variations::ActiveGroupId>& synthetic_trials) {
......@@ -795,6 +808,9 @@ void MetricsLog::RecordEnvironment(
metrics_log_chromeos_->LogChromeOSMetrics();
#endif // OS_CHROMEOS
for (size_t i = 0; i < metrics_providers.size(); ++i)
metrics_providers[i]->ProvideSystemProfileMetrics(system_profile);
std::string serialied_system_profile;
std::string base64_system_profile;
if (system_profile->SerializeToString(&serialied_system_profile)) {
......
......@@ -37,6 +37,10 @@ namespace content {
struct WebPluginInfo;
}
namespace metrics {
class MetricsProvider;
}
namespace tracked_objects {
struct ProcessDataSnapshot;
}
......@@ -82,13 +86,15 @@ class MetricsLog : public metrics::MetricsLogBase {
static void set_version_extension(const std::string& extension);
static const std::string& version_extension();
// Records the current operating environment. Takes the list of installed
// Records the current operating environment, including metrics provided by
// the specified set of |metrics_providers|. Takes the list of installed
// plugins, Google Update statistics, and synthetic trial IDs as parameters
// because those can't be obtained synchronously from the UI thread.
// A synthetic trial is one that is set up dynamically by code in Chrome. For
// example, a pref may be mapped to a synthetic trial such that the group
// is determined by the pref value.
void RecordEnvironment(
const std::vector<metrics::MetricsProvider*>& metrics_providers,
const std::vector<content::WebPluginInfo>& plugin_list,
const GoogleUpdateMetrics& google_update_metrics,
const std::vector<variations::ActiveGroupId>& synthetic_trials);
......@@ -108,17 +114,24 @@ class MetricsLog : public metrics::MetricsLogBase {
const tracked_objects::ProcessDataSnapshot& process_data,
int process_type);
// Writes application stability metrics (as part of the profile log). The
// system profile portion of the log must have already been filled in by a
// call to RecordEnvironment() or LoadSavedEnvironmentFromPrefs().
// Writes application stability metrics, including stability metrics provided
// by the specified set of |metrics_providers|. The system profile portion of
// the log must have already been filled in by a call to RecordEnvironment()
// or LoadSavedEnvironmentFromPrefs().
// NOTE: Has the side-effect of clearing the stability prefs..
//
// If this log is of type INITIAL_STABILITY_LOG, records additional info such
// as number of incomplete shutdowns as well as extra breakpad and debugger
// stats.
void RecordStabilityMetrics(base::TimeDelta incremental_uptime,
void RecordStabilityMetrics(
const std::vector<metrics::MetricsProvider*>& metrics_providers,
base::TimeDelta incremental_uptime,
base::TimeDelta uptime);
// Records general metrics based on the specified |metrics_providers|.
void RecordGeneralMetrics(
const std::vector<metrics::MetricsProvider*>& metrics_providers);
const base::TimeTicks& creation_time() const {
return creation_time_;
}
......
......@@ -27,6 +27,7 @@
#include "chrome/common/pref_names.h"
#include "chrome/installer/util/google_update_settings.h"
#include "components/metrics/metrics_hashes.h"
#include "components/metrics/metrics_provider.h"
#include "components/metrics/proto/profiler_event.pb.h"
#include "components/metrics/proto/system_profile.pb.h"
#include "components/variations/active_field_trials.h"
......@@ -324,7 +325,8 @@ TEST_F(MetricsLogTest, RecordEnvironment) {
synthetic_trials.push_back(kSyntheticTrials[0]);
synthetic_trials.push_back(kSyntheticTrials[1]);
log.RecordEnvironment(plugins, google_update_metrics, synthetic_trials);
log.RecordEnvironment(std::vector<metrics::MetricsProvider*>(),
plugins, google_update_metrics, synthetic_trials);
// Check that the system profile on the log has the correct values set.
CheckSystemProfile(log.system_profile());
......@@ -357,7 +359,8 @@ TEST_F(MetricsLogTest, LoadSavedEnvironmentFromPrefs) {
// Do a RecordEnvironment() call and check whether the pref is recorded.
{
TestMetricsLog log(kClientId, kSessionId, MetricsLog::ONGOING_LOG, &prefs);
log.RecordEnvironment(std::vector<content::WebPluginInfo>(),
log.RecordEnvironment(std::vector<metrics::MetricsProvider*>(),
std::vector<content::WebPluginInfo>(),
GoogleUpdateMetrics(),
std::vector<variations::ActiveGroupId>());
EXPECT_FALSE(prefs.GetString(kSystemProfilePref).empty());
......@@ -379,7 +382,8 @@ TEST_F(MetricsLogTest, LoadSavedEnvironmentFromPrefs) {
{
TestMetricsLog log(kClientId, kSessionId, MetricsLog::ONGOING_LOG, &prefs);
// Call RecordEnvironment() to record the pref again.
log.RecordEnvironment(std::vector<content::WebPluginInfo>(),
log.RecordEnvironment(std::vector<metrics::MetricsProvider*>(),
std::vector<content::WebPluginInfo>(),
GoogleUpdateMetrics(),
std::vector<variations::ActiveGroupId>());
}
......@@ -397,10 +401,13 @@ TEST_F(MetricsLogTest, LoadSavedEnvironmentFromPrefs) {
TEST_F(MetricsLogTest, InitialLogStabilityMetrics) {
TestMetricsLog log(kClientId, kSessionId, MetricsLog::INITIAL_STABILITY_LOG);
log.RecordEnvironment(std::vector<content::WebPluginInfo>(),
std::vector<metrics::MetricsProvider*> metrics_providers;
log.RecordEnvironment(metrics_providers,
std::vector<content::WebPluginInfo>(),
GoogleUpdateMetrics(),
std::vector<variations::ActiveGroupId>());
log.RecordStabilityMetrics(base::TimeDelta(), base::TimeDelta());
log.RecordStabilityMetrics(metrics_providers, base::TimeDelta(),
base::TimeDelta());
const metrics::SystemProfileProto_Stability& stability =
log.system_profile().stability();
// Required metrics:
......@@ -416,10 +423,13 @@ TEST_F(MetricsLogTest, InitialLogStabilityMetrics) {
TEST_F(MetricsLogTest, OngoingLogStabilityMetrics) {
TestMetricsLog log(kClientId, kSessionId, MetricsLog::ONGOING_LOG);
log.RecordEnvironment(std::vector<content::WebPluginInfo>(),
std::vector<metrics::MetricsProvider*> metrics_providers;
log.RecordEnvironment(metrics_providers,
std::vector<content::WebPluginInfo>(),
GoogleUpdateMetrics(),
std::vector<variations::ActiveGroupId>());
log.RecordStabilityMetrics(base::TimeDelta(), base::TimeDelta());
log.RecordStabilityMetrics(metrics_providers, base::TimeDelta(),
base::TimeDelta());
const metrics::SystemProfileProto_Stability& stability =
log.system_profile().stability();
// Required metrics:
......@@ -436,13 +446,14 @@ TEST_F(MetricsLogTest, OngoingLogStabilityMetrics) {
#if defined(ENABLE_PLUGINS)
TEST_F(MetricsLogTest, Plugins) {
TestMetricsLog log(kClientId, kSessionId, MetricsLog::ONGOING_LOG);
std::vector<metrics::MetricsProvider*> metrics_providers;
std::vector<content::WebPluginInfo> plugins;
plugins.push_back(CreateFakePluginInfo("p1", FILE_PATH_LITERAL("p1.plugin"),
"1.5", true));
plugins.push_back(CreateFakePluginInfo("p2", FILE_PATH_LITERAL("p2.plugin"),
"2.0", false));
log.RecordEnvironment(plugins, GoogleUpdateMetrics(),
log.RecordEnvironment(metrics_providers, plugins, GoogleUpdateMetrics(),
std::vector<variations::ActiveGroupId>());
const metrics::SystemProfileProto& system_profile = log.system_profile();
......@@ -468,7 +479,8 @@ TEST_F(MetricsLogTest, Plugins) {
update.Get()->Append(plugin_dict.release());
}
log.RecordStabilityMetrics(base::TimeDelta(), base::TimeDelta());
log.RecordStabilityMetrics(metrics_providers, base::TimeDelta(),
base::TimeDelta());
const metrics::SystemProfileProto_Stability& stability =
log.system_profile().stability();
ASSERT_EQ(1, stability.plugin_stability_size());
......@@ -673,10 +685,12 @@ TEST_F(MetricsLogTest, MultiProfileUserCount) {
user_manager->LoginUser(user3);
TestMetricsLog log(kClientId, kSessionId, MetricsLog::ONGOING_LOG);
std::vector<metrics::MetricsProvider*> metrics_providers;
std::vector<content::WebPluginInfo> plugins;
GoogleUpdateMetrics google_update_metrics;
std::vector<variations::ActiveGroupId> synthetic_trials;
log.RecordEnvironment(plugins, google_update_metrics, synthetic_trials);
log.RecordEnvironment(metrics_providers, plugins, google_update_metrics,
synthetic_trials);
EXPECT_EQ(2u, log.system_profile().multi_profile_user_count());
}
......@@ -698,15 +712,18 @@ TEST_F(MetricsLogTest, MultiProfileCountInvalidated) {
EXPECT_EQ(1u, log.system_profile().multi_profile_user_count());
user_manager->LoginUser(user2);
std::vector<metrics::MetricsProvider*> metrics_providers;
std::vector<variations::ActiveGroupId> synthetic_trials;
log.RecordEnvironment(std::vector<content::WebPluginInfo>(),
log.RecordEnvironment(metrics_providers,
std::vector<content::WebPluginInfo>(),
GoogleUpdateMetrics(), synthetic_trials);
EXPECT_EQ(0u, log.system_profile().multi_profile_user_count());
}
TEST_F(MetricsLogTest, BluetoothHardwareDisabled) {
TestMetricsLog log(kClientId, kSessionId, MetricsLog::ONGOING_LOG);
log.RecordEnvironment(std::vector<content::WebPluginInfo>(),
log.RecordEnvironment(std::vector<metrics::MetricsProvider*>(),
std::vector<content::WebPluginInfo>(),
GoogleUpdateMetrics(),
std::vector<variations::ActiveGroupId>());
......@@ -724,7 +741,8 @@ TEST_F(MetricsLogTest, BluetoothHardwareEnabled) {
properties->powered.ReplaceValue(true);
TestMetricsLog log(kClientId, kSessionId, MetricsLog::ONGOING_LOG);
log.RecordEnvironment(std::vector<content::WebPluginInfo>(),
log.RecordEnvironment(std::vector<metrics::MetricsProvider*>(),
std::vector<content::WebPluginInfo>(),
GoogleUpdateMetrics(),
std::vector<variations::ActiveGroupId>());
......@@ -754,7 +772,8 @@ TEST_F(MetricsLogTest, BluetoothPairedDevices) {
properties->paired.ReplaceValue(true);
TestMetricsLog log(kClientId, kSessionId, MetricsLog::ONGOING_LOG);
log.RecordEnvironment(std::vector<content::WebPluginInfo>(),
log.RecordEnvironment(std::vector<metrics::MetricsProvider*>(),
std::vector<content::WebPluginInfo>(),
GoogleUpdateMetrics(),
std::vector<variations::ActiveGroupId>());
......
......@@ -553,6 +553,9 @@ void MetricsService::EnableRecording() {
if (!log_manager_.current_log())
OpenNewLog();
for (size_t i = 0; i < metrics_providers_.size(); ++i)
metrics_providers_[i]->OnRecordingEnabled();
SetUpNotifications(&registrar_, this);
base::RemoveActionCallback(action_callback_);
action_callback_ = base::Bind(&MetricsService::OnUserAction,
......@@ -569,6 +572,10 @@ void MetricsService::DisableRecording() {
base::RemoveActionCallback(action_callback_);
registrar_.RemoveAll();
for (size_t i = 0; i < metrics_providers_.size(); ++i)
metrics_providers_[i]->OnRecordingDisabled();
PushPendingLogsToPersistentStorage();
DCHECK(!log_manager_.has_staged_log());
}
......@@ -1167,15 +1174,17 @@ void MetricsService::CloseCurrentLog() {
DCHECK(current_log);
std::vector<variations::ActiveGroupId> synthetic_trials;
GetCurrentSyntheticFieldTrials(&synthetic_trials);
current_log->RecordEnvironment(plugins_, google_update_metrics_,
synthetic_trials);
current_log->RecordEnvironment(metrics_providers_.get(), plugins_,
google_update_metrics_, synthetic_trials);
PrefService* pref = g_browser_process->local_state();
base::TimeDelta incremental_uptime;
base::TimeDelta uptime;
GetUptimes(pref, &incremental_uptime, &uptime);
current_log->RecordStabilityMetrics(incremental_uptime, uptime);
current_log->RecordStabilityMetrics(metrics_providers_.get(),
incremental_uptime, uptime);
RecordCurrentHistograms();
current_log->RecordGeneralMetrics(metrics_providers_.get());
log_manager_.FinishCurrentLog();
}
......@@ -1427,16 +1436,27 @@ void MetricsService::PrepareInitialStabilityLog() {
if (!initial_stability_log->LoadSavedEnvironmentFromPrefs())
return;
initial_stability_log->RecordStabilityMetrics(base::TimeDelta(),
base::TimeDelta());
log_manager_.LoadPersistedUnsentLogs();
log_manager_.PauseCurrentLog();
log_manager_.BeginLoggingWithLog(initial_stability_log.release());
// Note: Some stability providers may record stability stats via histograms,
// so this call has to be after BeginLoggingWithLog().
MetricsLog* current_log =
static_cast<MetricsLog*>(log_manager_.current_log());
current_log->RecordStabilityMetrics(metrics_providers_.get(),
base::TimeDelta(), base::TimeDelta());
#if defined(OS_ANDROID)
ConvertAndroidStabilityPrefsToHistograms(pref);
RecordCurrentStabilityHistograms();
#endif // defined(OS_ANDROID)
// Note: RecordGeneralMetrics() intentionally not called since this log is for
// stability stats from a previous session only.
log_manager_.FinishCurrentLog();
log_manager_.ResumePausedLog();
......@@ -1453,22 +1473,33 @@ void MetricsService::PrepareInitialMetricsLog() {
std::vector<variations::ActiveGroupId> synthetic_trials;
GetCurrentSyntheticFieldTrials(&synthetic_trials);
initial_metrics_log_->RecordEnvironment(plugins_, google_update_metrics_,
initial_metrics_log_->RecordEnvironment(metrics_providers_.get(), plugins_,
google_update_metrics_,
synthetic_trials);
PrefService* pref = g_browser_process->local_state();
base::TimeDelta incremental_uptime;
base::TimeDelta uptime;
GetUptimes(pref, &incremental_uptime, &uptime);
initial_metrics_log_->RecordStabilityMetrics(incremental_uptime, uptime);
// Histograms only get written to the current log, so make the new log current
// before writing them.
log_manager_.PauseCurrentLog();
log_manager_.BeginLoggingWithLog(initial_metrics_log_.release());
// Note: Some stability providers may record stability stats via histograms,
// so this call has to be after BeginLoggingWithLog().
MetricsLog* current_log =
static_cast<MetricsLog*>(log_manager_.current_log());
current_log->RecordStabilityMetrics(metrics_providers_.get(),
base::TimeDelta(), base::TimeDelta());
#if defined(OS_ANDROID)
ConvertAndroidStabilityPrefsToHistograms(pref);
#endif // defined(OS_ANDROID)
RecordCurrentHistograms();
current_log->RecordGeneralMetrics(metrics_providers_.get());
log_manager_.FinishCurrentLog();
log_manager_.ResumePausedLog();
......@@ -1721,6 +1752,12 @@ void MetricsService::RegisterSyntheticFieldTrial(
synthetic_trial_groups_.push_back(trial_group);
}
void MetricsService::RegisterMetricsProvider(
scoped_ptr<metrics::MetricsProvider> provider) {
DCHECK_EQ(INITIALIZED, state_);
metrics_providers_.push_back(provider.release());
}
void MetricsService::CheckForClonedInstall(
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
state_manager_->CheckForClonedInstall(task_runner);
......
......@@ -15,6 +15,7 @@
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/user_metrics.h"
......@@ -26,6 +27,7 @@
#include "chrome/browser/metrics/tracking_synchronizer_observer.h"
#include "chrome/common/metrics/metrics_service_base.h"
#include "chrome/installer/util/google_update_settings.h"
#include "components/metrics/metrics_provider.h"
#include "components/metrics/metrics_service_observer.h"
#include "components/variations/active_field_trials.h"
#include "content/public/browser/browser_child_process_observer.h"
......@@ -277,6 +279,10 @@ class MetricsService
// To use this method, SyntheticTrialGroup should friend your class.
void RegisterSyntheticFieldTrial(const SyntheticTrialGroup& trial_group);
// Register the specified |provider| to provide additional metrics into the
// UMA log. Should be called during MetricsService initialization only.
void RegisterMetricsProvider(scoped_ptr<metrics::MetricsProvider> provider);
// Check if this install was cloned or imaged from another machine. If a
// clone is detected, reset the client id and low entropy source. This
// should not be called more than once.
......@@ -483,6 +489,9 @@ class MetricsService
// low entropy source and whether metrics reporting is enabled. Weak pointer.
metrics::MetricsStateManager* state_manager_;
// Registered metrics providers.
ScopedVector<metrics::MetricsProvider> metrics_providers_;
base::ActionCallback action_callback_;
content::NotificationRegistrar registrar_;
......
......@@ -193,7 +193,8 @@ TEST_F(MetricsServiceTest, InitialStabilityLogAfterCrash) {
// Save an existing system profile to prefs, to correspond to what would be
// saved from a previous session.
TestMetricsLog log("client", 1);
log.RecordEnvironment(std::vector<content::WebPluginInfo>(),
log.RecordEnvironment(std::vector<metrics::MetricsProvider*>(),
std::vector<content::WebPluginInfo>(),
GoogleUpdateMetrics(),
std::vector<variations::ActiveGroupId>());
......
......@@ -15,6 +15,7 @@
'component_metrics_proto',
],
'sources': [
'metrics/metrics_provider.h',
'metrics/metrics_hashes.cc',
'metrics/metrics_hashes.h',
'metrics/metrics_log_base.cc',
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_METRICS_METRICS_PROVIDER_H_
#define COMPONENTS_METRICS_METRICS_PROVIDER_H_
#include "base/basictypes.h"
namespace metrics {
class ChromeUserMetricsExtension;
class SystemProfileProto;
class SystemProfileProto_Stability;
// MetricsProvider is an interface allowing different parts of the UMA protos to
// be filled out by different classes.
class MetricsProvider {
public:
MetricsProvider() {}
virtual ~MetricsProvider() {}
// Called when metrics recording has been enabled.
virtual void OnRecordingEnabled() {}
// Called when metrics recording has been disabled.
virtual void OnRecordingDisabled() {}
// Provides additional metrics into the system profile.
virtual void ProvideSystemProfileMetrics(
SystemProfileProto* system_profile_proto) {}
// Provides additional stability metrics. Stability metrics can be provided
// directly into |stability_proto| fields or by logging stability histograms
// via the UMA_STABILITY_HISTOGRAM_ENUMERATION() macro.
virtual void ProvideStabilityMetrics(
SystemProfileProto_Stability* stability_proto) {}
// Provides general metrics that are neither system profile nor stability
// metrics.
virtual void ProvideGeneralMetrics(
ChromeUserMetricsExtension* uma_proto) {}
private:
DISALLOW_COPY_AND_ASSIGN(MetricsProvider);
};
} // namespace metrics
#endif // COMPONENTS_METRICS_METRICS_PROVIDER_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment