diff options
author | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-28 05:43:37 +0000 |
---|---|---|
committer | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-28 05:43:37 +0000 |
commit | e324f6b9b93237c1488694b2a94cff0f8ec85460 (patch) | |
tree | 6b7ec91ccdf30bc794d8f837fcaac335f8a43afa /chrome/browser/metrics | |
parent | cce1cd0b2c227ab0c94276fbd1cc5155fc7b9943 (diff) | |
download | chromium_src-e324f6b9b93237c1488694b2a94cff0f8ec85460.zip chromium_src-e324f6b9b93237c1488694b2a94cff0f8ec85460.tar.gz chromium_src-e324f6b9b93237c1488694b2a94cff0f8ec85460.tar.bz2 |
Revert 123901 - Upload UMA data using protocol buffers.
For now, we will also preserve the existing XML upload system, so that there is no risk of data loss.
BUG=109817
TEST=unit tested
Review URL: http://codereview.chromium.org/9232071
TBR=isherman@chromium.org
Review URL: https://chromiumcodereview.appspot.com/9478031
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@123908 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/metrics')
-rw-r--r-- | chrome/browser/metrics/metrics_log.cc | 394 | ||||
-rw-r--r-- | chrome/browser/metrics/metrics_log.h | 15 | ||||
-rw-r--r-- | chrome/browser/metrics/metrics_log_serializer.cc | 145 | ||||
-rw-r--r-- | chrome/browser/metrics/metrics_log_serializer.h | 32 | ||||
-rw-r--r-- | chrome/browser/metrics/metrics_log_serializer_unittest.cc | 118 | ||||
-rw-r--r-- | chrome/browser/metrics/metrics_log_unittest.cc | 184 | ||||
-rw-r--r-- | chrome/browser/metrics/metrics_service.cc | 190 | ||||
-rw-r--r-- | chrome/browser/metrics/metrics_service.h | 16 |
8 files changed, 416 insertions, 678 deletions
diff --git a/chrome/browser/metrics/metrics_log.cc b/chrome/browser/metrics/metrics_log.cc index 1ba69ab..7170b03 100644 --- a/chrome/browser/metrics/metrics_log.cc +++ b/chrome/browser/metrics/metrics_log.cc @@ -12,7 +12,6 @@ #include "base/lazy_instance.h" #include "base/memory/scoped_ptr.h" #include "base/perftimer.h" -#include "base/string_number_conversions.h" #include "base/string_util.h" #include "base/sys_info.h" #include "base/third_party/nspr/prtime.h" @@ -21,19 +20,14 @@ #include "chrome/browser/autocomplete/autocomplete.h" #include "chrome/browser/autocomplete/autocomplete_match.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/gpu_performance_stats.h" #include "chrome/browser/plugin_prefs.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/common/chrome_version_info.h" #include "chrome/common/logging_chrome.h" -#include "chrome/common/metrics/proto/omnibox_event.pb.h" -#include "chrome/common/metrics/proto/system_profile.pb.h" #include "chrome/common/pref_names.h" -#include "content/public/browser/content_browser_client.h" #include "content/public/browser/gpu_data_manager.h" #include "content/public/common/gpu_info.h" -#include "content/public/common/content_client.h" #include "googleurl/src/gurl.h" #include "ui/gfx/screen.h" #include "webkit/plugins/webplugininfo.h" @@ -46,8 +40,6 @@ extern "C" IMAGE_DOS_HEADER __ImageBase; #endif using content::GpuDataManager; -using metrics::OmniboxEventProto; -using metrics::SystemProfileProto; namespace { @@ -63,85 +55,6 @@ std::string GetInstallDate() { } } -OmniboxEventProto::InputType AsOmniboxEventInputType( - AutocompleteInput::Type type) { - switch (type) { - case AutocompleteInput::INVALID: - return OmniboxEventProto::INVALID; - case AutocompleteInput::UNKNOWN: - return OmniboxEventProto::UNKNOWN; - case AutocompleteInput::REQUESTED_URL: - return OmniboxEventProto::REQUESTED_URL; - case AutocompleteInput::URL: - return OmniboxEventProto::URL; - case AutocompleteInput::QUERY: - return OmniboxEventProto::QUERY; - case AutocompleteInput::FORCED_QUERY: - return OmniboxEventProto::FORCED_QUERY; - default: - NOTREACHED(); - return OmniboxEventProto::INVALID; - } -} - -OmniboxEventProto::Suggestion::ProviderType AsOmniboxEventProviderType( - const AutocompleteProvider* provider) { - if (!provider) - return OmniboxEventProto::Suggestion::UNKNOWN_PROVIDER; - - const std::string& name = provider->name(); - if (name == "HistoryURL") - return OmniboxEventProto::Suggestion::URL; - if (name == "HistoryContents") - return OmniboxEventProto::Suggestion::HISTORY_CONTENTS; - if (name == "HistoryQuickProvider") - return OmniboxEventProto::Suggestion::HISTORY_QUICK; - if (name == "Search") - return OmniboxEventProto::Suggestion::SEARCH; - if (name == "Keyword") - return OmniboxEventProto::Suggestion::KEYWORD; - if (name == "Builtin") - return OmniboxEventProto::Suggestion::BUILTIN; - if (name == "ShortcutsProvider") - return OmniboxEventProto::Suggestion::SHORTCUTS; - if (name == "ExtensionApps") - return OmniboxEventProto::Suggestion::EXTENSION_APPS; - - NOTREACHED(); - return OmniboxEventProto::Suggestion::UNKNOWN_PROVIDER; -} - -OmniboxEventProto::Suggestion::ResultType AsOmniboxEventResultType( - AutocompleteMatch::Type type) { - switch (type) { - case AutocompleteMatch::URL_WHAT_YOU_TYPED: - return OmniboxEventProto::Suggestion::URL_WHAT_YOU_TYPED; - case AutocompleteMatch::HISTORY_URL: - return OmniboxEventProto::Suggestion::HISTORY_URL; - case AutocompleteMatch::HISTORY_TITLE: - return OmniboxEventProto::Suggestion::HISTORY_TITLE; - case AutocompleteMatch::HISTORY_BODY: - return OmniboxEventProto::Suggestion::HISTORY_BODY; - case AutocompleteMatch::HISTORY_KEYWORD: - return OmniboxEventProto::Suggestion::HISTORY_KEYWORD; - case AutocompleteMatch::NAVSUGGEST: - return OmniboxEventProto::Suggestion::NAVSUGGEST; - case AutocompleteMatch::SEARCH_WHAT_YOU_TYPED: - return OmniboxEventProto::Suggestion::SEARCH_WHAT_YOU_TYPED; - case AutocompleteMatch::SEARCH_HISTORY: - return OmniboxEventProto::Suggestion::SEARCH_HISTORY; - case AutocompleteMatch::SEARCH_SUGGEST: - return OmniboxEventProto::Suggestion::SEARCH_SUGGEST; - case AutocompleteMatch::SEARCH_OTHER_ENGINE: - return OmniboxEventProto::Suggestion::SEARCH_OTHER_ENGINE; - case AutocompleteMatch::EXTENSION_APP: - return OmniboxEventProto::Suggestion::EXTENSION_APP; - default: - NOTREACHED(); - return OmniboxEventProto::Suggestion::UNKNOWN_RESULT_TYPE; - } -} - // Returns the plugin preferences corresponding for this user, if available. // If multiple user profiles are loaded, returns the preferences corresponding // to an arbitrary one of the profiles. @@ -154,17 +67,6 @@ PluginPrefs* GetPluginPrefs() { return PluginPrefs::GetForProfile(profiles.front()); } -// Fills |plugin| with the info contained in |plugin_info| and |plugin_prefs|. -void SetPluginInfo(const webkit::WebPluginInfo& plugin_info, - const PluginPrefs* plugin_prefs, - SystemProfileProto::Plugin* plugin) { - plugin->set_name(UTF16ToUTF8(plugin_info.name)); - plugin->set_filename(plugin_info.path.BaseName().AsUTF8Unsafe()); - plugin->set_version(UTF16ToUTF8(plugin_info.version)); - if (plugin_prefs) - plugin->set_is_disabled(!plugin_prefs->IsPluginEnabled(plugin_info)); -} - } // namespace static base::LazyInstance<std::string>::Leaky @@ -222,8 +124,7 @@ const std::string& MetricsLog::version_extension() { return g_version_extension.Get(); } -void MetricsLog::RecordIncrementalStabilityElements( - const std::vector<webkit::WebPluginInfo>& plugin_list) { +void MetricsLog::RecordIncrementalStabilityElements() { DCHECK(!locked_); PrefService* pref = g_browser_process->local_state(); @@ -239,15 +140,15 @@ void MetricsLog::RecordIncrementalStabilityElements( WriteRequiredStabilityAttributes(pref); WriteRealtimeStabilityAttributes(pref); - WritePluginStabilityElements(plugin_list, pref); + WritePluginStabilityElements(pref); } } -void MetricsLog::WriteStabilityElement( - const std::vector<webkit::WebPluginInfo>& plugin_list, - PrefService* pref) { +void MetricsLog::WriteStabilityElement(PrefService* pref) { DCHECK(!locked_); + DCHECK(pref); + // Get stability attributes out of Local State, zeroing out stored values. // NOTE: This could lead to some data loss if this report isn't successfully // sent, but that's true for all the metrics. @@ -256,51 +157,31 @@ void MetricsLog::WriteStabilityElement( WriteRequiredStabilityAttributes(pref); WriteRealtimeStabilityAttributes(pref); - int incomplete_shutdown_count = - pref->GetInteger(prefs::kStabilityIncompleteSessionEndCount); + // TODO(jar): The following are all optional, so we *could* optimize them for + // values of zero (and not include them). + WriteIntAttribute("incompleteshutdowncount", + pref->GetInteger( + prefs::kStabilityIncompleteSessionEndCount)); pref->SetInteger(prefs::kStabilityIncompleteSessionEndCount, 0); - int breakpad_registration_success_count = - pref->GetInteger(prefs::kStabilityBreakpadRegistrationSuccess); + + + WriteIntAttribute("breakpadregistrationok", + pref->GetInteger(prefs::kStabilityBreakpadRegistrationSuccess)); pref->SetInteger(prefs::kStabilityBreakpadRegistrationSuccess, 0); - int breakpad_registration_failure_count = - pref->GetInteger(prefs::kStabilityBreakpadRegistrationFail); + WriteIntAttribute("breakpadregistrationfail", + pref->GetInteger(prefs::kStabilityBreakpadRegistrationFail)); pref->SetInteger(prefs::kStabilityBreakpadRegistrationFail, 0); - int debugger_present_count = - pref->GetInteger(prefs::kStabilityDebuggerPresent); + WriteIntAttribute("debuggerpresent", + pref->GetInteger(prefs::kStabilityDebuggerPresent)); pref->SetInteger(prefs::kStabilityDebuggerPresent, 0); - int debugger_not_present_count = - pref->GetInteger(prefs::kStabilityDebuggerNotPresent); + WriteIntAttribute("debuggernotpresent", + pref->GetInteger(prefs::kStabilityDebuggerNotPresent)); pref->SetInteger(prefs::kStabilityDebuggerNotPresent, 0); - // TODO(jar): The following are all optional, so we *could* optimize them for - // values of zero (and not include them). - - // Write the XML version. - WriteIntAttribute("incompleteshutdowncount", incomplete_shutdown_count); - WriteIntAttribute("breakpadregistrationok", - breakpad_registration_success_count); - WriteIntAttribute("breakpadregistrationfail", - breakpad_registration_failure_count); - WriteIntAttribute("debuggerpresent", debugger_present_count); - WriteIntAttribute("debuggernotpresent", debugger_not_present_count); - - // Write the protobuf version. - 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); - stability->set_breakpad_registration_failure_count( - breakpad_registration_failure_count); - stability->set_debugger_present_count(debugger_present_count); - stability->set_debugger_not_present_count(debugger_not_present_count); - - WritePluginStabilityElements(plugin_list, pref); + WritePluginStabilityElements(pref); } -void MetricsLog::WritePluginStabilityElements( - const std::vector<webkit::WebPluginInfo>& plugin_list, - PrefService* pref) { +void MetricsLog::WritePluginStabilityElements(PrefService* pref) { // Now log plugin stability info. const ListValue* plugin_stats_list = pref->GetList( prefs::kStabilityPluginStats); @@ -308,9 +189,6 @@ void MetricsLog::WritePluginStabilityElements( return; OPEN_ELEMENT_FOR_SCOPE("plugins"); - SystemProfileProto::Stability* stability = - uma_proto_.mutable_system_profile()->mutable_stability(); - PluginPrefs* plugin_prefs = GetPluginPrefs(); for (ListValue::const_iterator iter = plugin_stats_list->begin(); iter != plugin_stats_list->end(); ++iter) { if (!(*iter)->IsType(Value::TYPE_DICTIONARY)) { @@ -322,15 +200,10 @@ void MetricsLog::WritePluginStabilityElements( std::string plugin_name; plugin_dict->GetString(prefs::kStabilityPluginName, &plugin_name); - std::string base64_name_hash; - uint64 numeric_name_hash_ignored; - CreateHashes(plugin_name, &base64_name_hash, &numeric_name_hash_ignored); - - // Write the XML verison. OPEN_ELEMENT_FOR_SCOPE("pluginstability"); // Use "filename" instead of "name", otherwise we need to update the // UMA servers. - WriteAttribute("filename", base64_name_hash); + WriteAttribute("filename", CreateBase64Hash(plugin_name)); int launches = 0; plugin_dict->GetInteger(prefs::kStabilityPluginLaunches, &launches); @@ -343,60 +216,20 @@ void MetricsLog::WritePluginStabilityElements( int crashes = 0; plugin_dict->GetInteger(prefs::kStabilityPluginCrashes, &crashes); WriteIntAttribute("crashcount", crashes); - - // Write the protobuf version. - // Note that this search is potentially a quadratic operation, but given the - // low number of plugins installed on a "reasonable" setup, this should be - // fine. - // TODO(isherman): Verify that this does not show up as a hotspot in - // profiler runs. - const webkit::WebPluginInfo* plugin_info = NULL; - const string16 plugin_name_utf16 = UTF8ToUTF16(plugin_name); - for (std::vector<webkit::WebPluginInfo>::const_iterator iter = - plugin_list.begin(); - iter != plugin_list.end(); ++iter) { - if (iter->name == plugin_name_utf16) { - plugin_info = &(*iter); - break; - } - } - - if (!plugin_info) { - NOTREACHED(); - continue; - } - - SystemProfileProto::Stability::PluginStability* plugin_stability = - stability->add_plugin_stability(); - SetPluginInfo(*plugin_info, plugin_prefs, - plugin_stability->mutable_plugin()); - plugin_stability->set_launch_count(launches); - plugin_stability->set_instance_count(instances); - plugin_stability->set_crash_count(crashes); } pref->ClearPref(prefs::kStabilityPluginStats); } -// The server refuses data that doesn't have certain values. crashcount and -// launchcount are currently "required" in the "stability" group. -// TODO(isherman): Stop writing these attributes specially once the migration to -// protobufs is complete. void MetricsLog::WriteRequiredStabilityAttributes(PrefService* pref) { - int launch_count = pref->GetInteger(prefs::kStabilityLaunchCount); + // The server refuses data that doesn't have certain values. crashcount and + // launchcount are currently "required" in the "stability" group. + WriteIntAttribute("launchcount", + pref->GetInteger(prefs::kStabilityLaunchCount)); pref->SetInteger(prefs::kStabilityLaunchCount, 0); - int crash_count = pref->GetInteger(prefs::kStabilityCrashCount); + WriteIntAttribute("crashcount", + pref->GetInteger(prefs::kStabilityCrashCount)); pref->SetInteger(prefs::kStabilityCrashCount, 0); - - // Write the XML version. - WriteIntAttribute("launchcount", launch_count); - WriteIntAttribute("crashcount", crash_count); - - // Write the protobuf version. - SystemProfileProto::Stability* stability = - uma_proto_.mutable_system_profile()->mutable_stability(); - stability->set_launch_count(launch_count); - stability->set_crash_count(crash_count); } void MetricsLog::WriteRealtimeStabilityAttributes(PrefService* pref) { @@ -404,68 +237,71 @@ void MetricsLog::WriteRealtimeStabilityAttributes(PrefService* pref) { // Since these are "optional," only list ones that are non-zero, as the counts // are aggergated (summed) server side. - SystemProfileProto::Stability* stability = - uma_proto_.mutable_system_profile()->mutable_stability(); int count = pref->GetInteger(prefs::kStabilityPageLoadCount); if (count) { WriteIntAttribute("pageloadcount", count); - stability->set_page_load_count(count); pref->SetInteger(prefs::kStabilityPageLoadCount, 0); } count = pref->GetInteger(prefs::kStabilityRendererCrashCount); if (count) { WriteIntAttribute("renderercrashcount", count); - stability->set_renderer_crash_count(count); pref->SetInteger(prefs::kStabilityRendererCrashCount, 0); } count = pref->GetInteger(prefs::kStabilityExtensionRendererCrashCount); if (count) { WriteIntAttribute("extensionrenderercrashcount", count); - stability->set_extension_renderer_crash_count(count); pref->SetInteger(prefs::kStabilityExtensionRendererCrashCount, 0); } count = pref->GetInteger(prefs::kStabilityRendererHangCount); if (count) { WriteIntAttribute("rendererhangcount", count); - stability->set_renderer_hang_count(count); pref->SetInteger(prefs::kStabilityRendererHangCount, 0); } count = pref->GetInteger(prefs::kStabilityChildProcessCrashCount); if (count) { WriteIntAttribute("childprocesscrashcount", count); - stability->set_child_process_crash_count(count); pref->SetInteger(prefs::kStabilityChildProcessCrashCount, 0); } #if defined(OS_CHROMEOS) count = pref->GetInteger(prefs::kStabilityOtherUserCrashCount); if (count) { - stability->set_other_user_crash_count(count); + // TODO(kmixter): Write attribute once log server supports it + // and remove warning log. + // WriteIntAttribute("otherusercrashcount", count); + LOG(WARNING) << "Not yet able to send otherusercrashcount=" + << count; pref->SetInteger(prefs::kStabilityOtherUserCrashCount, 0); } count = pref->GetInteger(prefs::kStabilityKernelCrashCount); if (count) { - stability->set_kernel_crash_count(count); + // TODO(kmixter): Write attribute once log server supports it + // and remove warning log. + // WriteIntAttribute("kernelcrashcount", count); + LOG(WARNING) << "Not yet able to send kernelcrashcount=" + << count; pref->SetInteger(prefs::kStabilityKernelCrashCount, 0); } count = pref->GetInteger(prefs::kStabilitySystemUncleanShutdownCount); if (count) { - stability->set_unclean_system_shutdown_count(count); + // TODO(kmixter): Write attribute once log server supports it + // and remove warning log. + // WriteIntAttribute("systemuncleanshutdowns", count); + LOG(WARNING) << "Not yet able to send systemuncleanshutdowns=" + << count; pref->SetInteger(prefs::kStabilitySystemUncleanShutdownCount, 0); } #endif // OS_CHROMEOS int64 recent_duration = GetIncrementalUptime(pref); - if (recent_duration) { + if (recent_duration) WriteInt64Attribute("uptimesec", recent_duration); - stability->set_uptime_sec(recent_duration); - } } void MetricsLog::WritePluginList( @@ -475,53 +311,32 @@ void MetricsLog::WritePluginList( PluginPrefs* plugin_prefs = GetPluginPrefs(); OPEN_ELEMENT_FOR_SCOPE("plugins"); - SystemProfileProto* system_profile = uma_proto_.mutable_system_profile(); + for (std::vector<webkit::WebPluginInfo>::const_iterator iter = plugin_list.begin(); iter != plugin_list.end(); ++iter) { - std::string base64_name_hash; - uint64 numeric_name_hash_ignored; - CreateHashes(UTF16ToUTF8(iter->name), - &base64_name_hash, - &numeric_name_hash_ignored); - - std::string filename_bytes = iter->path.BaseName().AsUTF8Unsafe(); - std::string base64_filename_hash; - uint64 numeric_filename_hash; - CreateHashes(filename_bytes, - &base64_filename_hash, - &numeric_filename_hash); - - // Write the XML version. OPEN_ELEMENT_FOR_SCOPE("plugin"); // Plugin name and filename are hashed for the privacy of those // testing unreleased new extensions. - WriteAttribute("name", base64_name_hash); - WriteAttribute("filename", base64_filename_hash); + WriteAttribute("name", CreateBase64Hash(UTF16ToUTF8(iter->name))); + std::string filename_bytes = +#if defined(OS_WIN) + UTF16ToUTF8(iter->path.BaseName().value()); +#else + iter->path.BaseName().value(); +#endif + WriteAttribute("filename", CreateBase64Hash(filename_bytes)); WriteAttribute("version", UTF16ToUTF8(iter->version)); if (plugin_prefs) WriteIntAttribute("disabled", !plugin_prefs->IsPluginEnabled(*iter)); - - // Write the protobuf version. - SystemProfileProto::Plugin* plugin = system_profile->add_plugin(); - SetPluginInfo(*iter, plugin_prefs, plugin); } } void MetricsLog::WriteInstallElement() { - std::string install_date = GetInstallDate(); - - // Write the XML version. OPEN_ELEMENT_FOR_SCOPE("install"); - WriteAttribute("installdate", install_date); + WriteAttribute("installdate", GetInstallDate()); WriteIntAttribute("buildid", 0); // We're using appversion instead. - - // Write the protobuf version. - int numeric_install_date; - bool success = base::StringToInt(install_date, &numeric_install_date); - DCHECK(success); - uma_proto_.mutable_system_profile()->set_install_date(numeric_install_date); } void MetricsLog::RecordEnvironment( @@ -538,96 +353,42 @@ void MetricsLog::RecordEnvironment( WritePluginList(plugin_list); - WriteStabilityElement(plugin_list, pref); - - SystemProfileProto* system_profile = uma_proto_.mutable_system_profile(); - system_profile->set_application_locale( - content::GetContentClient()->browser()->GetApplicationLocale()); + WriteStabilityElement(pref); - SystemProfileProto::Hardware* hardware = system_profile->mutable_hardware(); { - std::string cpu_architecture = base::SysInfo::CPUArchitecture(); - - // Write the XML version. OPEN_ELEMENT_FOR_SCOPE("cpu"); - WriteAttribute("arch", cpu_architecture); - - // Write the protobuf version. - hardware->set_cpu_architecture(cpu_architecture); + WriteAttribute("arch", base::SysInfo::CPUArchitecture()); } { - int system_memory_mb = base::SysInfo::AmountOfPhysicalMemoryMB(); - - // Write the XML version. OPEN_ELEMENT_FOR_SCOPE("memory"); - WriteIntAttribute("mb", system_memory_mb); + WriteIntAttribute("mb", base::SysInfo::AmountOfPhysicalMemoryMB()); #if defined(OS_WIN) WriteIntAttribute("dllbase", reinterpret_cast<int>(&__ImageBase)); #endif - - // Write the protobuf version. - hardware->set_system_ram_mb(system_memory_mb); -#if defined(OS_WIN) - hardware->set_dll_base(reinterpret_cast<uint64>(&__ImageBase)); -#endif } { - std::string os_name = base::SysInfo::OperatingSystemName(); - std::string os_version = base::SysInfo::OperatingSystemVersion(); - - // Write the XML version. OPEN_ELEMENT_FOR_SCOPE("os"); - WriteAttribute("name", os_name); - WriteAttribute("version", os_version); - - // Write the protobuf version. - SystemProfileProto::OS* os = system_profile->mutable_os(); - os->set_name(os_name); - os->set_version(os_version); + WriteAttribute("name", + base::SysInfo::OperatingSystemName()); + WriteAttribute("version", + base::SysInfo::OperatingSystemVersion()); } { OPEN_ELEMENT_FOR_SCOPE("gpu"); - const content::GPUInfo& gpu_info = - GpuDataManager::GetInstance()->GetGPUInfo(); - GpuPerformanceStats gpu_performance_stats = - GpuPerformanceStats::RetrieveGpuPerformanceStats(); - - // Write the XML version. + content::GPUInfo gpu_info = GpuDataManager::GetInstance()->GetGPUInfo(); WriteIntAttribute("vendorid", gpu_info.vendor_id); WriteIntAttribute("deviceid", gpu_info.device_id); - - // Write the protobuf version. - SystemProfileProto::Hardware::Graphics* gpu = hardware->mutable_gpu(); - gpu->set_vendor_id(gpu_info.vendor_id); - gpu->set_device_id(gpu_info.device_id); - gpu->set_driver_version(gpu_info.driver_version); - gpu->set_driver_date(gpu_info.driver_date); - SystemProfileProto::Hardware::Graphics::PerformanceStatistics* - gpu_performance = gpu->mutable_performance_statistics(); - gpu_performance->set_graphics_score(gpu_performance_stats.graphics); - gpu_performance->set_gaming_score(gpu_performance_stats.gaming); - gpu_performance->set_overall_score(gpu_performance_stats.overall); } { - const gfx::Size display_size = gfx::Screen::GetPrimaryMonitorSize(); - int display_width = display_size.width(); - int display_height = display_size.height(); - int screen_count = gfx::Screen::GetNumMonitors(); - - // Write the XML version. OPEN_ELEMENT_FOR_SCOPE("display"); - WriteIntAttribute("xsize", display_width); - WriteIntAttribute("ysize", display_height); - WriteIntAttribute("screens", screen_count); - - // Write the protobuf version. - hardware->set_primary_screen_width(display_width); - hardware->set_primary_screen_height(display_height); - hardware->set_screen_count(screen_count); + const gfx::Size display_size = gfx::Screen::GetPrimaryMonitorSize(); + WriteIntAttribute("xsize", display_size.width()); + WriteIntAttribute("ysize", display_size.height()); + WriteIntAttribute("screens", gfx::Screen::GetNumMonitors()); } { @@ -732,7 +493,6 @@ void MetricsLog::WriteProfileMetrics(const std::string& profileidhash, void MetricsLog::RecordOmniboxOpenedURL(const AutocompleteLog& log) { DCHECK(!locked_); - // Write the XML version. OPEN_ELEMENT_FOR_SCOPE("uielement"); WriteAttribute("action", "autocomplete"); WriteAttribute("targetidhash", ""); @@ -778,25 +538,5 @@ void MetricsLog::RecordOmniboxOpenedURL(const AutocompleteLog& log) { } } - // Write the protobuf version. - OmniboxEventProto* omnibox_event = uma_proto_.add_omnibox_event(); - omnibox_event->set_time(MetricsLogBase::GetCurrentTime()); - if (log.tab_id != -1) { - // If we know what tab the autocomplete URL was opened in, log it. - omnibox_event->set_tab_id(log.tab_id); - } - omnibox_event->set_typed_length(log.text.length()); - omnibox_event->set_selected_index(log.selected_index); - omnibox_event->set_completed_length(log.inline_autocompleted_length); - omnibox_event->set_input_type(AsOmniboxEventInputType(log.input_type)); - for (AutocompleteResult::const_iterator i(log.result.begin()); - i != log.result.end(); ++i) { - OmniboxEventProto::Suggestion* suggestion = omnibox_event->add_suggestion(); - suggestion->set_provider(AsOmniboxEventProviderType(i->provider)); - suggestion->set_result_type(AsOmniboxEventResultType(i->type)); - suggestion->set_relevance(i->relevance); - suggestion->set_is_starred(i->starred); - } - ++num_events_; } diff --git a/chrome/browser/metrics/metrics_log.h b/chrome/browser/metrics/metrics_log.h index 5935139..a5a3504 100644 --- a/chrome/browser/metrics/metrics_log.h +++ b/chrome/browser/metrics/metrics_log.h @@ -65,25 +65,18 @@ class MetricsLog : public MetricsLogBase { // Record recent delta for critical stability metrics. We can't wait for a // restart to gather these, as that delay biases our observation away from // users that run happily for a looooong time. We send increments with each - // uma log upload, just as we send histogram data. Takes the list of - // installed plugins as a parameter because that can't be obtained - // synchronously from the UI thread. - void RecordIncrementalStabilityElements( - const std::vector<webkit::WebPluginInfo>& plugin_list); + // uma log upload, just as we send histogram data. + void RecordIncrementalStabilityElements(); private: FRIEND_TEST_ALL_PREFIXES(MetricsLogTest, ChromeOSStabilityData); // Writes application stability metrics (as part of the profile log). // NOTE: Has the side-effect of clearing those counts. - void WriteStabilityElement( - const std::vector<webkit::WebPluginInfo>& plugin_list, - PrefService* pref); + void WriteStabilityElement(PrefService* pref); // Within stability group, write plugin crash stats. - void WritePluginStabilityElements( - const std::vector<webkit::WebPluginInfo>& plugin_list, - PrefService* pref); + void WritePluginStabilityElements(PrefService* pref); // Within the stability group, write required attributes. void WriteRequiredStabilityAttributes(PrefService* pref); diff --git a/chrome/browser/metrics/metrics_log_serializer.cc b/chrome/browser/metrics/metrics_log_serializer.cc index b9ed48c..bbddf60 100644 --- a/chrome/browser/metrics/metrics_log_serializer.cc +++ b/chrome/browser/metrics/metrics_log_serializer.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -12,12 +12,10 @@ #include "chrome/browser/prefs/scoped_user_pref_update.h" #include "chrome/common/pref_names.h" -namespace { - // The number of "initial" logs we're willing to save, and hope to send during // a future Chrome session. Initial logs contain crash stats, and are pretty // small. -const size_t kMaxInitialLogsPersisted = 20; +static const size_t kMaxInitialLogsPersisted = 20; // The number of ongoing logs we're willing to save persistently, and hope to // send during a this or future sessions. Note that each log may be pretty @@ -28,14 +26,15 @@ const size_t kMaxInitialLogsPersisted = 20; // A "standard shutdown" will create a small log, including just the data that // was not yet been transmitted, and that is normal (to have exactly one // ongoing_log_ at startup). -const size_t kMaxOngoingLogsPersisted = 8; +static const size_t kMaxOngoingLogsPersisted = 8; // We append (2) more elements to persisted lists: the size of the list and a // checksum of the elements. -const size_t kChecksumEntryCount = 2; +static const size_t kChecksumEntryCount = 2; -// TODO(isherman): Remove this histogram once it's confirmed that there are no -// encoding failures for protobuf logs. +namespace { +// TODO(ziadh): This is here temporarily for a side experiment. Remove later +// on. enum LogStoreStatus { STORE_SUCCESS, // Successfully presisted log. ENCODE_FAIL, // Failed to encode log. @@ -44,23 +43,17 @@ enum LogStoreStatus { }; MetricsLogSerializer::LogReadStatus MakeRecallStatusHistogram( - MetricsLogSerializer::LogReadStatus status, - bool is_xml) { - if (is_xml) { - UMA_HISTOGRAM_ENUMERATION("PrefService.PersistentLogRecall", - status, MetricsLogSerializer::END_RECALL_STATUS); - } else { - UMA_HISTOGRAM_ENUMERATION("PrefService.PersistentLogRecallProtobufs", - status, MetricsLogSerializer::END_RECALL_STATUS); - } + MetricsLogSerializer::LogReadStatus status) { + UMA_HISTOGRAM_ENUMERATION("PrefService.PersistentLogRecall", status, + MetricsLogSerializer::END_RECALL_STATUS); return status; } +// TODO(ziadh): Remove this when done with experiment. void MakeStoreStatusHistogram(LogStoreStatus status) { UMA_HISTOGRAM_ENUMERATION("PrefService.PersistentLogStore2", status, END_STORE_STATUS); } - } // namespace @@ -68,76 +61,52 @@ MetricsLogSerializer::MetricsLogSerializer() {} MetricsLogSerializer::~MetricsLogSerializer() {} -void MetricsLogSerializer::SerializeLogs( - const std::vector<MetricsLogManager::SerializedLog>& logs, - MetricsLogManager::LogType log_type) { +void MetricsLogSerializer::SerializeLogs(const std::vector<std::string>& logs, + MetricsLogManager::LogType log_type) { PrefService* local_state = g_browser_process->local_state(); DCHECK(local_state); - const char* pref_xml = NULL; - const char* pref_proto = NULL; + const char* pref = NULL; size_t max_store_count = 0; switch (log_type) { case MetricsLogManager::INITIAL_LOG: - pref_xml = prefs::kMetricsInitialLogsXml; - pref_proto = prefs::kMetricsInitialLogsProto; + pref = prefs::kMetricsInitialLogs; max_store_count = kMaxInitialLogsPersisted; break; case MetricsLogManager::ONGOING_LOG: - pref_xml = prefs::kMetricsOngoingLogsXml; - pref_proto = prefs::kMetricsOngoingLogsProto; + pref = prefs::kMetricsOngoingLogs; max_store_count = kMaxOngoingLogsPersisted; break; default: NOTREACHED(); return; }; - - // Write the XML version. - ListPrefUpdate update_xml(local_state, pref_xml); - WriteLogsToPrefList(logs, true, max_store_count, update_xml.Get()); - - // Write the protobuf version. - ListPrefUpdate update_proto(local_state, pref_proto); - WriteLogsToPrefList(logs, false, max_store_count, update_proto.Get()); + ListPrefUpdate update(local_state, pref); + ListValue* pref_list = update.Get(); + WriteLogsToPrefList(logs, max_store_count, pref_list); } -void MetricsLogSerializer::DeserializeLogs( - MetricsLogManager::LogType log_type, - std::vector<MetricsLogManager::SerializedLog>* logs) { +void MetricsLogSerializer::DeserializeLogs(MetricsLogManager::LogType log_type, + std::vector<std::string>* logs) { DCHECK(logs); PrefService* local_state = g_browser_process->local_state(); DCHECK(local_state); - const char* pref_xml; - const char* pref_proto; - if (log_type == MetricsLogManager::INITIAL_LOG) { - pref_xml = prefs::kMetricsInitialLogsXml; - pref_proto = prefs::kMetricsInitialLogsProto; - } else { - pref_xml = prefs::kMetricsOngoingLogsXml; - pref_proto = prefs::kMetricsOngoingLogsProto; - } - - const ListValue* unsent_logs_xml = local_state->GetList(pref_xml); - const ListValue* unsent_logs_proto = local_state->GetList(pref_proto); - if (ReadLogsFromPrefList(*unsent_logs_xml, true, logs) == RECALL_SUCCESS) { - // In order to try to keep the data sent to both servers roughly in sync, - // only read the protobuf data if we read the XML data successfully. - ReadLogsFromPrefList(*unsent_logs_proto, false, logs); - } + const char* pref = (log_type == MetricsLogManager::INITIAL_LOG) ? + prefs::kMetricsInitialLogs : prefs::kMetricsOngoingLogs; + const ListValue* unsent_logs = local_state->GetList(pref); + ReadLogsFromPrefList(*unsent_logs, logs); } // static void MetricsLogSerializer::WriteLogsToPrefList( - const std::vector<MetricsLogManager::SerializedLog>& local_list, - bool is_xml, - size_t max_list_size, - base::ListValue* list) { + const std::vector<std::string>& local_list, + const size_t kMaxLocalListSize, + ListValue* list) { list->Clear(); size_t start = 0; - if (local_list.size() > max_list_size) - start = local_list.size() - max_list_size; - DCHECK_LE(start, local_list.size()); + if (local_list.size() > kMaxLocalListSize) + start = local_list.size() - kMaxLocalListSize; + DCHECK(start <= local_list.size()); if (local_list.size() <= start) return; @@ -147,13 +116,11 @@ void MetricsLogSerializer::WriteLogsToPrefList( base::MD5Context ctx; base::MD5Init(&ctx); std::string encoded_log; - for (std::vector<MetricsLogManager::SerializedLog>::const_iterator it = - local_list.begin() + start; + for (std::vector<std::string>::const_iterator it = local_list.begin() + start; it != local_list.end(); ++it) { - const std::string& value = is_xml ? it->xml : it->proto; // We encode the compressed log as Value::CreateStringValue() expects to // take a valid UTF8 string. - if (!base::Base64Encode(value, &encoded_log)) { + if (!base::Base64Encode(*it, &encoded_log)) { MakeStoreStatusHistogram(ENCODE_FAIL); list->Clear(); return; @@ -173,58 +140,44 @@ void MetricsLogSerializer::WriteLogsToPrefList( // static MetricsLogSerializer::LogReadStatus MetricsLogSerializer::ReadLogsFromPrefList( const ListValue& list, - bool is_xml, - std::vector<MetricsLogManager::SerializedLog>* local_list) { + std::vector<std::string>* local_list) { + DCHECK(local_list->empty()); if (list.GetSize() == 0) - return MakeRecallStatusHistogram(LIST_EMPTY, is_xml); + return MakeRecallStatusHistogram(LIST_EMPTY); if (list.GetSize() < 3) - return MakeRecallStatusHistogram(LIST_SIZE_TOO_SMALL, is_xml); + return MakeRecallStatusHistogram(LIST_SIZE_TOO_SMALL); // The size is stored at the beginning of the list. int size; bool valid = (*list.begin())->GetAsInteger(&size); if (!valid) - return MakeRecallStatusHistogram(LIST_SIZE_MISSING, is_xml); + return MakeRecallStatusHistogram(LIST_SIZE_MISSING); + // Account for checksum and size included in the list. if (static_cast<unsigned int>(size) != list.GetSize() - kChecksumEntryCount) { - return MakeRecallStatusHistogram(LIST_SIZE_CORRUPTION, is_xml); - } - - // Allocate strings for all of the logs we are going to read in. - // Do this ahead of time so that we can decode the string values directly into - // the elements of |local_list|, and thereby avoid making copies of the - // serialized logs, which can be fairly large. - if (is_xml) { - DCHECK(local_list->empty()); - local_list->resize(size); - } else if (local_list->size() != static_cast<size_t>(size)) { - return MakeRecallStatusHistogram(XML_PROTO_MISMATCH, false); + return MakeRecallStatusHistogram(LIST_SIZE_CORRUPTION); } base::MD5Context ctx; base::MD5Init(&ctx); std::string encoded_log; - size_t local_index = 0; + std::string decoded_log; for (ListValue::const_iterator it = list.begin() + 1; - it != list.end() - 1; // Last element is the checksum. - ++it, ++local_index) { - bool valid = (*it)->GetAsString(&encoded_log); + it != list.end() - 1; ++it) { // Last element is the checksum. + valid = (*it)->GetAsString(&encoded_log); if (!valid) { local_list->clear(); - return MakeRecallStatusHistogram(LOG_STRING_CORRUPTION, is_xml); + return MakeRecallStatusHistogram(LOG_STRING_CORRUPTION); } base::MD5Update(&ctx, encoded_log); - DCHECK_LT(local_index, local_list->size()); - std::string& decoded_log = is_xml ? - (*local_list)[local_index].xml : - (*local_list)[local_index].proto; if (!base::Base64Decode(encoded_log, &decoded_log)) { local_list->clear(); - return MakeRecallStatusHistogram(DECODE_FAIL, is_xml); + return MakeRecallStatusHistogram(DECODE_FAIL); } + local_list->push_back(decoded_log); } // Verify checksum. @@ -235,11 +188,11 @@ MetricsLogSerializer::LogReadStatus MetricsLogSerializer::ReadLogsFromPrefList( valid = (*(list.end() - 1))->GetAsString(&recovered_md5); if (!valid) { local_list->clear(); - return MakeRecallStatusHistogram(CHECKSUM_STRING_CORRUPTION, is_xml); + return MakeRecallStatusHistogram(CHECKSUM_STRING_CORRUPTION); } if (recovered_md5 != base::MD5DigestToBase16(digest)) { local_list->clear(); - return MakeRecallStatusHistogram(CHECKSUM_CORRUPTION, is_xml); + return MakeRecallStatusHistogram(CHECKSUM_CORRUPTION); } - return MakeRecallStatusHistogram(RECALL_SUCCESS, is_xml); + return MakeRecallStatusHistogram(RECALL_SUCCESS); } diff --git a/chrome/browser/metrics/metrics_log_serializer.h b/chrome/browser/metrics/metrics_log_serializer.h index 9a1e630..69986b6 100644 --- a/chrome/browser/metrics/metrics_log_serializer.h +++ b/chrome/browser/metrics/metrics_log_serializer.h @@ -17,7 +17,7 @@ class ListValue; // Serializer for persisting metrics logs to prefs. class MetricsLogSerializer : public MetricsLogManager::LogSerializer { public: - // Used to produce a histogram that keeps track of the status of recalling + // Used to produce a historgram that keeps track of the status of recalling // persisted per logs. enum LogReadStatus { RECALL_SUCCESS, // We were able to correctly recall a persisted log. @@ -28,9 +28,8 @@ class MetricsLogSerializer : public MetricsLogManager::LogSerializer { LOG_STRING_CORRUPTION, // Failed to recover log string using GetAsString(). CHECKSUM_CORRUPTION, // Failed to verify checksum. CHECKSUM_STRING_CORRUPTION, // Failed to recover checksum string using - // GetAsString(). + // GetAsString(). DECODE_FAIL, // Failed to decode log. - XML_PROTO_MISMATCH, // The XML and protobuf logs have inconsistent data. END_RECALL_STATUS // Number of bins to use to create the histogram. }; @@ -38,30 +37,23 @@ class MetricsLogSerializer : public MetricsLogManager::LogSerializer { virtual ~MetricsLogSerializer(); // Implementation of MetricsLogManager::LogSerializer - virtual void SerializeLogs( - const std::vector<MetricsLogManager::SerializedLog>& logs, - MetricsLogManager::LogType log_type) OVERRIDE; - virtual void DeserializeLogs( - MetricsLogManager::LogType log_type, - std::vector<MetricsLogManager::SerializedLog>* logs) OVERRIDE; + virtual void SerializeLogs(const std::vector<std::string>& logs, + MetricsLogManager::LogType log_type) OVERRIDE; + virtual void DeserializeLogs(MetricsLogManager::LogType log_type, + std::vector<std::string>* logs) OVERRIDE; private: // Encodes the textual log data from |local_list| and writes it to the given - // pref list, along with list size and checksum. If |is_xml| is true, writes - // the XML data from |local_list|; otherwise writes the protobuf data. - static void WriteLogsToPrefList( - const std::vector<MetricsLogManager::SerializedLog>& local_list, - bool is_xml, - size_t max_list_size, - base::ListValue* list); + // pref list, along with list size and checksum. + static void WriteLogsToPrefList(const std::vector<std::string>& local_list, + const size_t kMaxLocalListSize, + base::ListValue* list); // Decodes and verifies the textual log data from |list|, populating - // |local_list| and returning a status code. If |is_xml| is true, populates - // the XML data in |local_list|; otherwise populates the protobuf data. + // |local_list| and returning a status code. static LogReadStatus ReadLogsFromPrefList( const base::ListValue& list, - bool is_xml, - std::vector<MetricsLogManager::SerializedLog>* local_list); + std::vector<std::string>* local_list); FRIEND_TEST_ALL_PREFIXES(MetricsLogSerializerTest, EmptyLogList); FRIEND_TEST_ALL_PREFIXES(MetricsLogSerializerTest, SingleElementLogList); diff --git a/chrome/browser/metrics/metrics_log_serializer_unittest.cc b/chrome/browser/metrics/metrics_log_serializer_unittest.cc index f023a7c..59c257b 100644 --- a/chrome/browser/metrics/metrics_log_serializer_unittest.cc +++ b/chrome/browser/metrics/metrics_log_serializer_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -8,46 +8,42 @@ #include "chrome/browser/metrics/metrics_log_serializer.h" #include "testing/gtest/include/gtest/gtest.h" -typedef MetricsLogManager::SerializedLog SerializedLog; - namespace { + class MetricsLogSerializerTest : public ::testing::Test { + }; +} -const size_t kMaxLocalListSize = 3; - -} // namespace - -class MetricsLogSerializerTest : public ::testing::Test { -}; +static const size_t kMaxLocalListSize = 3; // Store and retrieve empty list. TEST(MetricsLogSerializerTest, EmptyLogList) { ListValue list; - std::vector<SerializedLog> local_list; + std::vector<std::string> local_list; - MetricsLogSerializer::WriteLogsToPrefList(local_list, true, kMaxLocalListSize, + MetricsLogSerializer::WriteLogsToPrefList(local_list, kMaxLocalListSize, &list); EXPECT_EQ(0U, list.GetSize()); local_list.clear(); // ReadLogsFromPrefList() expects empty |local_list|. - EXPECT_EQ( - MetricsLogSerializer::LIST_EMPTY, - MetricsLogSerializer::ReadLogsFromPrefList(list, true, &local_list)); + EXPECT_EQ(MetricsLogSerializer::LIST_EMPTY, + MetricsLogSerializer::ReadLogsFromPrefList(list, &local_list)); EXPECT_EQ(0U, local_list.size()); } // Store and retrieve a single log value. TEST(MetricsLogSerializerTest, SingleElementLogList) { ListValue list; + std::vector<std::string> local_list; - std::vector<SerializedLog> local_list(1); - local_list[0].xml = "Hello world!"; + local_list.push_back("Hello world!"); + EXPECT_EQ(1U, local_list.size()); - MetricsLogSerializer::WriteLogsToPrefList(local_list, true, kMaxLocalListSize, + MetricsLogSerializer::WriteLogsToPrefList(local_list, kMaxLocalListSize, &list); // |list| will now contain the following: // [1, Base64Encode("Hello world!"), MD5("Hello world!")]. - ASSERT_EQ(3U, list.GetSize()); + EXPECT_EQ(3U, list.GetSize()); // Examine each element. ListValue::const_iterator it = list.begin(); @@ -70,56 +66,55 @@ TEST(MetricsLogSerializerTest, SingleElementLogList) { EXPECT_TRUE(it == list.end()); // Reached end of list. local_list.clear(); - EXPECT_EQ( - MetricsLogSerializer::RECALL_SUCCESS, - MetricsLogSerializer::ReadLogsFromPrefList(list, true, &local_list)); + EXPECT_EQ(MetricsLogSerializer::RECALL_SUCCESS, + MetricsLogSerializer::ReadLogsFromPrefList(list, &local_list)); EXPECT_EQ(1U, local_list.size()); } // Store elements greater than the limit. TEST(MetricsLogSerializerTest, OverLimitLogList) { ListValue list; + std::vector<std::string> local_list; - std::vector<SerializedLog> local_list(4); - local_list[0].proto = "one"; - local_list[1].proto = "two"; - local_list[2].proto = "three"; - local_list[3].proto = "four"; + local_list.push_back("one"); + local_list.push_back("two"); + local_list.push_back("three"); + local_list.push_back("four"); + EXPECT_EQ(4U, local_list.size()); std::string expected_first; - base::Base64Encode(local_list[local_list.size() - kMaxLocalListSize].proto, + base::Base64Encode(local_list[local_list.size() - kMaxLocalListSize], &expected_first); std::string expected_last; - base::Base64Encode(local_list[local_list.size() - 1].proto, + base::Base64Encode(local_list[local_list.size() - 1], &expected_last); - MetricsLogSerializer::WriteLogsToPrefList(local_list, false, - kMaxLocalListSize, &list); + MetricsLogSerializer::WriteLogsToPrefList(local_list, kMaxLocalListSize, + &list); EXPECT_EQ(kMaxLocalListSize + 2, list.GetSize()); std::string actual_first; EXPECT_TRUE((*(list.begin() + 1))->GetAsString(&actual_first)); - EXPECT_EQ(expected_first, actual_first); + EXPECT_TRUE(expected_first == actual_first); std::string actual_last; EXPECT_TRUE((*(list.end() - 2))->GetAsString(&actual_last)); - EXPECT_EQ(expected_last, actual_last); + EXPECT_TRUE(expected_last == actual_last); local_list.clear(); - EXPECT_EQ( - MetricsLogSerializer::RECALL_SUCCESS, - MetricsLogSerializer::ReadLogsFromPrefList(list, true, &local_list)); + EXPECT_EQ(MetricsLogSerializer::RECALL_SUCCESS, + MetricsLogSerializer::ReadLogsFromPrefList(list, &local_list)); EXPECT_EQ(kMaxLocalListSize, local_list.size()); } // Induce LIST_SIZE_TOO_SMALL corruption TEST(MetricsLogSerializerTest, SmallRecoveredListSize) { ListValue list; + std::vector<std::string> local_list; - std::vector<SerializedLog> local_list(1); - local_list[0].xml = "Hello world!"; - - MetricsLogSerializer::WriteLogsToPrefList(local_list, true, kMaxLocalListSize, + local_list.push_back("Hello world!"); + EXPECT_EQ(1U, local_list.size()); + MetricsLogSerializer::WriteLogsToPrefList(local_list, kMaxLocalListSize, &list); EXPECT_EQ(3U, list.GetSize()); @@ -128,20 +123,19 @@ TEST(MetricsLogSerializerTest, SmallRecoveredListSize) { EXPECT_EQ(2U, list.GetSize()); local_list.clear(); - EXPECT_EQ( - MetricsLogSerializer::LIST_SIZE_TOO_SMALL, - MetricsLogSerializer::ReadLogsFromPrefList(list, true, &local_list)); + EXPECT_EQ(MetricsLogSerializer::LIST_SIZE_TOO_SMALL, + MetricsLogSerializer::ReadLogsFromPrefList(list, &local_list)); } // Remove size from the stored list. TEST(MetricsLogSerializerTest, RemoveSizeFromLogList) { ListValue list; + std::vector<std::string> local_list; - std::vector<SerializedLog> local_list(2); - local_list[0].xml = "one"; - local_list[1].xml = "two"; + local_list.push_back("one"); + local_list.push_back("two"); EXPECT_EQ(2U, local_list.size()); - MetricsLogSerializer::WriteLogsToPrefList(local_list, true, kMaxLocalListSize, + MetricsLogSerializer::WriteLogsToPrefList(local_list, kMaxLocalListSize, &list); EXPECT_EQ(4U, list.GetSize()); @@ -149,19 +143,18 @@ TEST(MetricsLogSerializerTest, RemoveSizeFromLogList) { EXPECT_EQ(3U, list.GetSize()); local_list.clear(); - EXPECT_EQ( - MetricsLogSerializer::LIST_SIZE_MISSING, - MetricsLogSerializer::ReadLogsFromPrefList(list, true, &local_list)); + EXPECT_EQ(MetricsLogSerializer::LIST_SIZE_MISSING, + MetricsLogSerializer::ReadLogsFromPrefList(list, &local_list)); } // Corrupt size of stored list. TEST(MetricsLogSerializerTest, CorruptSizeOfLogList) { ListValue list; + std::vector<std::string> local_list; - std::vector<SerializedLog> local_list(1); - local_list[0].xml = "Hello world!"; - - MetricsLogSerializer::WriteLogsToPrefList(local_list, true, kMaxLocalListSize, + local_list.push_back("Hello world!"); + EXPECT_EQ(1U, local_list.size()); + MetricsLogSerializer::WriteLogsToPrefList(local_list, kMaxLocalListSize, &list); EXPECT_EQ(3U, list.GetSize()); @@ -170,19 +163,19 @@ TEST(MetricsLogSerializerTest, CorruptSizeOfLogList) { EXPECT_EQ(3U, list.GetSize()); local_list.clear(); - EXPECT_EQ( - MetricsLogSerializer::LIST_SIZE_CORRUPTION, - MetricsLogSerializer::ReadLogsFromPrefList(list, true, &local_list)); + EXPECT_EQ(MetricsLogSerializer::LIST_SIZE_CORRUPTION, + MetricsLogSerializer::ReadLogsFromPrefList(list, &local_list)); } // Corrupt checksum of stored list. TEST(MetricsLogSerializerTest, CorruptChecksumOfLogList) { ListValue list; + std::vector<std::string> local_list; - std::vector<SerializedLog> local_list(1); - local_list[0].xml = "Hello world!"; - - MetricsLogSerializer::WriteLogsToPrefList(local_list, true, kMaxLocalListSize, + local_list.clear(); + local_list.push_back("Hello world!"); + EXPECT_EQ(1U, local_list.size()); + MetricsLogSerializer::WriteLogsToPrefList(local_list, kMaxLocalListSize, &list); EXPECT_EQ(3U, list.GetSize()); @@ -194,7 +187,6 @@ TEST(MetricsLogSerializerTest, CorruptChecksumOfLogList) { EXPECT_EQ(3U, list.GetSize()); local_list.clear(); - EXPECT_EQ( - MetricsLogSerializer::CHECKSUM_CORRUPTION, - MetricsLogSerializer::ReadLogsFromPrefList(list, true, &local_list)); + EXPECT_EQ(MetricsLogSerializer::CHECKSUM_CORRUPTION, + MetricsLogSerializer::ReadLogsFromPrefList(list, &local_list)); } diff --git a/chrome/browser/metrics/metrics_log_unittest.cc b/chrome/browser/metrics/metrics_log_unittest.cc index b3be903..edea42b 100644 --- a/chrome/browser/metrics/metrics_log_unittest.cc +++ b/chrome/browser/metrics/metrics_log_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -18,10 +18,14 @@ using base::TimeDelta; namespace { + class MetricsLogTest : public testing::Test { + }; +}; + // Since buildtime is highly variable, this function will scan an output log and // replace it with a consistent number. -void NormalizeBuildtime(std::string* xml_encoded) { +static void NormalizeBuildtime(std::string* xml_encoded) { std::string prefix = "buildtime=\""; const char postfix = '\"'; size_t offset = xml_encoded->find(prefix); @@ -39,6 +43,54 @@ void NormalizeBuildtime(std::string* xml_encoded) { xml_encoded->replace(offset, postfix_position - offset, "123246"); } +TEST(MetricsLogTest, EmptyRecord) { + std::string expected_output = base::StringPrintf( + "<log clientid=\"bogus client ID\" buildtime=\"123456789\" " + "appversion=\"%s\"/>", MetricsLog::GetVersionString().c_str()); + + MetricsLog log("bogus client ID", 0); + log.CloseLog(); + + int size = log.GetEncodedLogSize(); + ASSERT_GT(size, 0); + + std::string encoded; + // Leave room for the NUL terminator. + ASSERT_TRUE(log.GetEncodedLog(WriteInto(&encoded, size + 1), size)); + TrimWhitespaceASCII(encoded, TRIM_ALL, &encoded); + NormalizeBuildtime(&encoded); + NormalizeBuildtime(&expected_output); + + ASSERT_EQ(expected_output, encoded); +} + +#if defined(OS_CHROMEOS) +TEST(MetricsLogTest, ChromeOSEmptyRecord) { + std::string expected_output = base::StringPrintf( + "<log clientid=\"bogus client ID\" buildtime=\"123456789\" " + "appversion=\"%s\" hardwareclass=\"sample-class\"/>", + MetricsLog::GetVersionString().c_str()); + + MetricsLog log("bogus client ID", 0); + log.set_hardware_class("sample-class"); + log.CloseLog(); + + int size = log.GetEncodedLogSize(); + ASSERT_GT(size, 0); + + std::string encoded; + // Leave room for the NUL terminator. + ASSERT_TRUE(log.GetEncodedLog(WriteInto(&encoded, size + 1), size)); + TrimWhitespaceASCII(encoded, TRIM_ALL, &encoded); + NormalizeBuildtime(&encoded); + NormalizeBuildtime(&expected_output); + + ASSERT_EQ(expected_output, encoded); +} +#endif // OS_CHROMEOS + +namespace { + class NoTimeMetricsLog : public MetricsLog { public: NoTimeMetricsLog(std::string client_id, int session_id): @@ -51,12 +103,103 @@ class NoTimeMetricsLog : public MetricsLog { } }; -} // namespace +}; // namespace -class MetricsLogTest : public testing::Test { -}; +TEST(MetricsLogTest, WindowEvent) { + std::string expected_output = base::StringPrintf( + "<log clientid=\"bogus client ID\" buildtime=\"123456789\" " + "appversion=\"%s\">\n" + " <window action=\"create\" windowid=\"0\" session=\"0\" time=\"\"/>\n" + " <window action=\"open\" windowid=\"1\" parent=\"0\" " + "session=\"0\" time=\"\"/>\n" + " <window action=\"close\" windowid=\"1\" parent=\"0\" " + "session=\"0\" time=\"\"/>\n" + " <window action=\"destroy\" windowid=\"0\" session=\"0\" time=\"\"/>\n" + "</log>", MetricsLog::GetVersionString().c_str()); + + NoTimeMetricsLog log("bogus client ID", 0); + log.RecordWindowEvent(MetricsLog::WINDOW_CREATE, 0, -1); + log.RecordWindowEvent(MetricsLog::WINDOW_OPEN, 1, 0); + log.RecordWindowEvent(MetricsLog::WINDOW_CLOSE, 1, 0); + log.RecordWindowEvent(MetricsLog::WINDOW_DESTROY, 0, -1); + log.CloseLog(); + + ASSERT_EQ(4, log.num_events()); + + int size = log.GetEncodedLogSize(); + ASSERT_GT(size, 0); + + std::string encoded; + // Leave room for the NUL terminator. + ASSERT_TRUE(log.GetEncodedLog(WriteInto(&encoded, size + 1), size)); + TrimWhitespaceASCII(encoded, TRIM_ALL, &encoded); + NormalizeBuildtime(&encoded); + NormalizeBuildtime(&expected_output); + + ASSERT_EQ(expected_output, encoded); +} + +TEST(MetricsLogTest, LoadEvent) { + std::string expected_output = base::StringPrintf( + "<log clientid=\"bogus client ID\" buildtime=\"123456789\" " + "appversion=\"%s\">\n" + " <document action=\"load\" docid=\"1\" window=\"3\" loadtime=\"7219\" " + "origin=\"link\" session=\"0\" time=\"\"/>\n" + "</log>", MetricsLog::GetVersionString().c_str()); + + NoTimeMetricsLog log("bogus client ID", 0); + log.RecordLoadEvent(3, GURL("http://google.com"), + content::PAGE_TRANSITION_LINK, 1, + TimeDelta::FromMilliseconds(7219)); + + log.CloseLog(); + + ASSERT_EQ(1, log.num_events()); + + int size = log.GetEncodedLogSize(); + ASSERT_GT(size, 0); + + std::string encoded; + // Leave room for the NUL terminator. + ASSERT_TRUE(log.GetEncodedLog(WriteInto(&encoded, size + 1), size)); + TrimWhitespaceASCII(encoded, TRIM_ALL, &encoded); + NormalizeBuildtime(&encoded); + NormalizeBuildtime(&expected_output); + + ASSERT_EQ(expected_output, encoded); +} #if defined(OS_CHROMEOS) +TEST(MetricsLogTest, ChromeOSLoadEvent) { + std::string expected_output = base::StringPrintf( + "<log clientid=\"bogus client ID\" buildtime=\"123456789\" " + "appversion=\"%s\" hardwareclass=\"sample-class\">\n" + " <document action=\"load\" docid=\"1\" window=\"3\" loadtime=\"7219\" " + "origin=\"link\" session=\"0\" time=\"\"/>\n" + "</log>", MetricsLog::GetVersionString().c_str()); + + NoTimeMetricsLog log("bogus client ID", 0); + log.RecordLoadEvent(3, GURL("http://google.com"), + content::PAGE_TRANSITION_LINK, 1, + TimeDelta::FromMilliseconds(7219)); + log.set_hardware_class("sample-class"); + log.CloseLog(); + + ASSERT_EQ(1, log.num_events()); + + int size = log.GetEncodedLogSize(); + ASSERT_GT(size, 0); + + std::string encoded; + // Leave room for the NUL terminator. + ASSERT_TRUE(log.GetEncodedLog(WriteInto(&encoded, size + 1), size)); + TrimWhitespaceASCII(encoded, TRIM_ALL, &encoded); + NormalizeBuildtime(&encoded); + NormalizeBuildtime(&expected_output); + + ASSERT_EQ(expected_output, encoded); +} + TEST(MetricsLogTest, ChromeOSStabilityData) { NoTimeMetricsLog log("bogus client ID", 0); TestingPrefService prefs; @@ -75,7 +218,7 @@ TEST(MetricsLogTest, ChromeOSStabilityData) { log.WriteStabilityElement(&prefs); log.CloseLog(); - int size = log.GetEncodedLogSizeXml(); + int size = log.GetEncodedLogSize(); ASSERT_GT(size, 0); EXPECT_EQ(0, prefs.GetInteger(prefs::kStabilityChildProcessCrashCount)); @@ -85,7 +228,7 @@ TEST(MetricsLogTest, ChromeOSStabilityData) { std::string encoded; // Leave room for the NUL terminator. - bool encoding_result = log.GetEncodedLogXml( + bool encoding_result = log.GetEncodedLog( WriteInto(&encoded, size + 1), size); ASSERT_TRUE(encoding_result); @@ -101,4 +244,31 @@ TEST(MetricsLogTest, ChromeOSStabilityData) { EXPECT_EQ(std::string::npos, encoded.find(" systemuncleanshutdowns=")); } + #endif // OS_CHROMEOS + +// Make sure our ID hashes are the same as what we see on the server side. +TEST(MetricsLogTest, CreateHash) { + static const struct { + std::string input; + std::string output; + } cases[] = { + {"Back", "0x0557fa923dcee4d0"}, + {"Forward", "0x67d2f6740a8eaebf"}, + {"NewTab", "0x290eb683f96572f1"}, + }; + + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) { + std::string hash_string = MetricsLog::CreateHash(cases[i].input); + + // Convert to hex string + // We're only checking the first 8 bytes, because that's what + // the metrics server uses. + std::string hash_hex = "0x"; + for (size_t j = 0; j < 8; j++) { + base::StringAppendF(&hash_hex, "%02x", + static_cast<uint8>(hash_string.data()[j])); + } + EXPECT_EQ(cases[i].output, hash_hex); + } +}; diff --git a/chrome/browser/metrics/metrics_service.cc b/chrome/browser/metrics/metrics_service.cc index 1c53155..634ef6a 100644 --- a/chrome/browser/metrics/metrics_service.cc +++ b/chrome/browser/metrics/metrics_service.cc @@ -182,7 +182,6 @@ #include "content/public/browser/plugin_service.h" #include "content/public/browser/render_process_host.h" #include "content/public/common/url_fetcher.h" -#include "net/base/load_flags.h" #include "webkit/plugins/webplugininfo.h" // TODO(port): port browser_distribution.h. @@ -201,44 +200,30 @@ using content::BrowserThread; using content::ChildProcessData; using content::PluginService; -namespace { - // Check to see that we're being called on only one thread. -bool IsSingleThreaded() { - static base::PlatformThreadId thread_id = 0; - if (!thread_id) - thread_id = base::PlatformThread::CurrentId(); - return base::PlatformThread::CurrentId() == thread_id; -} - -const char kMetricsTypeXml[] = "application/vnd.mozilla.metrics.bz2"; -const char kMetricsTypeProto[] = "application/vnd.chrome.uma"; +static bool IsSingleThreaded(); -const char kServerUrlXml[] = - "https://clients4.google.com/firefox/metrics/collect"; -const char kServerUrlProto[] = "https://clients4.google.com/uma/v2"; +static const char kMetricsType[] = "application/vnd.mozilla.metrics.bz2"; // The delay, in seconds, after starting recording before doing expensive // initialization work. -const int kInitializationDelaySeconds = 30; +static const int kInitializationDelaySeconds = 30; // This specifies the amount of time to wait for all renderers to send their // data. -const int kMaxHistogramGatheringWaitDuration = 60000; // 60 seconds. +static const int kMaxHistogramGatheringWaitDuration = 60000; // 60 seconds. // The maximum number of events in a log uploaded to the UMA server. -const int kEventLimit = 2400; +static const int kEventLimit = 2400; // If an upload fails, and the transmission was over this byte count, then we // will discard the log, and not try to retransmit it. We also don't persist // the log to the prefs for transmission during the next chrome session if this // limit is exceeded. -const size_t kUploadLogAvoidRetransmitSize = 50000; +static const int kUploadLogAvoidRetransmitSize = 50000; // Interval, in minutes, between state saves. -const int kSaveStateIntervalMinutes = 5; - -} +static const int kSaveStateIntervalMinutes = 5; // static MetricsService::ShutdownCleanliness MetricsService::clean_shutdown_status_ = @@ -338,10 +323,8 @@ void MetricsService::RegisterPrefs(PrefService* local_state) { 0); local_state->RegisterIntegerPref(prefs::kNumFoldersInOtherBookmarkFolder, 0); local_state->RegisterIntegerPref(prefs::kNumKeywords, 0); - local_state->RegisterListPref(prefs::kMetricsInitialLogsXml); - local_state->RegisterListPref(prefs::kMetricsOngoingLogsXml); - local_state->RegisterListPref(prefs::kMetricsInitialLogsProto); - local_state->RegisterListPref(prefs::kMetricsOngoingLogsProto); + local_state->RegisterListPref(prefs::kMetricsInitialLogs); + local_state->RegisterListPref(prefs::kMetricsOngoingLogs); local_state->RegisterInt64Pref(prefs::kUninstallMetricsPageLoadCount, 0); local_state->RegisterInt64Pref(prefs::kUninstallLaunchCount, 0); @@ -374,16 +357,15 @@ void MetricsService::DiscardOldStabilityStats(PrefService* local_state) { local_state->ClearPref(prefs::kStabilityPluginStats); - local_state->ClearPref(prefs::kMetricsInitialLogsXml); - local_state->ClearPref(prefs::kMetricsOngoingLogsXml); - local_state->ClearPref(prefs::kMetricsInitialLogsProto); - local_state->ClearPref(prefs::kMetricsOngoingLogsProto); + local_state->ClearPref(prefs::kMetricsInitialLogs); + local_state->ClearPref(prefs::kMetricsOngoingLogs); } MetricsService::MetricsService() : recording_active_(false), reporting_active_(false), state_(INITIALIZED), + current_fetch_(NULL), io_thread_(NULL), idle_since_last_transmission_(false), next_window_id_(0), @@ -646,13 +628,11 @@ void MetricsService::RecordBreakpadHasDebugger(bool has_debugger) { void MetricsService::InitializeMetricsState() { #if defined(OS_POSIX) - server_url_xml_ = ASCIIToUTF16(kServerUrlXml); - server_url_proto_ = ASCIIToUTF16(kServerUrlProto); + server_url_ = L"https://clients4.google.com/firefox/metrics/collect"; network_stats_server_ = "chrome.googleechotest.com"; #else BrowserDistribution* dist = BrowserDistribution::GetDistribution(); - server_url_xml_ = dist->GetStatsServerURL(); - server_url_proto_ = ASCIIToUTF16(kServerUrlProto); + server_url_ = dist->GetStatsServerURL(); network_stats_server_ = dist->GetNetworkStatsServer(); #endif @@ -859,7 +839,7 @@ void MetricsService::StopRecording() { MetricsLog* current_log = static_cast<MetricsLog*>(log_manager_.current_log()); DCHECK(current_log); - current_log->RecordIncrementalStabilityElements(plugins_); + current_log->RecordIncrementalStabilityElements(); RecordCurrentHistograms(); log_manager_.StageCurrentLogForUpload(); @@ -954,9 +934,8 @@ void MetricsService::OnHistogramSynchronizationDone() { // If somehow there is a fetch in progress, we return and hope things work // out. The scheduler isn't informed since if this happens, the scheduler // will get a response from the upload. - DCHECK(!current_fetch_xml_.get()); - DCHECK(!current_fetch_proto_.get()); - if (current_fetch_xml_.get() || current_fetch_proto_.get()) + DCHECK(!current_fetch_.get()); + if (current_fetch_.get()) return; // This function should only be called as the callback from an ansynchronous @@ -986,8 +965,7 @@ void MetricsService::OnHistogramSynchronizationDone() { PrepareFetchWithStagedLog(); - if (!current_fetch_xml_.get()) { - DCHECK(!current_fetch_proto_.get()); + if (!current_fetch_.get()) { // Compression failed, and log discarded :-/. log_manager_.DiscardStagedLog(); scheduler_->UploadCancelled(); @@ -995,19 +973,11 @@ void MetricsService::OnHistogramSynchronizationDone() { // compressed that, so that we can signal that we're losing logs. return; } - // Currently, the staged log for the protobuf version of the data is discarded - // after we create the URL request, so that there is no chance for - // re-transmission in case the corresponding XML request fails. We will - // handle protobuf failures more carefully once that becomes the main - // pipeline, i.e. once we switch away from the XML pipeline. - DCHECK(current_fetch_proto_.get() || !log_manager_.has_staged_log_proto()); DCHECK(!waiting_for_asynchronus_reporting_step_); waiting_for_asynchronus_reporting_step_ = true; - current_fetch_xml_->Start(); - if (current_fetch_proto_.get()) - current_fetch_proto_->Start(); + current_fetch_->Start(); HandleIdleSinceLastTransmission(true); } @@ -1081,40 +1051,13 @@ void MetricsService::StoreUnsentLogs() { void MetricsService::PrepareFetchWithStagedLog() { DCHECK(!log_manager_.staged_log_text().empty()); + DCHECK(!current_fetch_.get()); - // Prepare the XML version. - DCHECK(!current_fetch_xml_.get()); - current_fetch_xml_.reset(content::URLFetcher::Create( - GURL(server_url_xml_), content::URLFetcher::POST, this)); - current_fetch_xml_->SetRequestContext( + current_fetch_.reset(content::URLFetcher::Create( + GURL(WideToUTF16(server_url_)), content::URLFetcher::POST, this)); + current_fetch_->SetRequestContext( g_browser_process->system_request_context()); - current_fetch_xml_->SetUploadData(kMetricsTypeXml, - log_manager_.staged_log_text().xml); - // We already drop cookies server-side, but we might as well strip them out - // client-side as well. - current_fetch_xml_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | - net::LOAD_DO_NOT_SEND_COOKIES); - - // Prepare the protobuf version. - DCHECK(!current_fetch_proto_.get()); - if (log_manager_.has_staged_log_proto()) { - current_fetch_proto_.reset(content::URLFetcher::Create( - GURL(server_url_proto_), content::URLFetcher::POST, this)); - current_fetch_proto_->SetRequestContext( - g_browser_process->system_request_context()); - current_fetch_proto_->SetUploadData(kMetricsTypeProto, - log_manager_.staged_log_text().proto); - // We already drop cookies server-side, but we might as well strip them out - // client-side as well. - current_fetch_proto_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | - net::LOAD_DO_NOT_SEND_COOKIES); - - // Discard the protobuf version of the staged log, so that we will avoid - // re-uploading it even if we need to re-upload the XML version. - // TODO(isherman): Handle protobuf upload failures more gracefully once we - // transition away from the XML-based pipeline. - log_manager_.DiscardStagedLogProto(); - } + current_fetch_->SetUploadData(kMetricsType, log_manager_.staged_log_text()); } static const char* StatusToString(const net::URLRequestStatus& status) { @@ -1140,71 +1083,30 @@ static const char* StatusToString(const net::URLRequestStatus& status) { } } -// We need to wait for two responses: the response to the XML upload, and the -// response to the protobuf upload. For now, only the XML upload's response -// affects decisions like whether to retry the upload, whether to abandon the -// upload because it is too large, etc. However, we still need to wait for the -// protobuf upload, as we cannot reset |current_fetch_proto_| until we have -// confirmation that the network request was sent; and the easiest way to do -// that is to wait for the response. In case the XML upload's response arrives -// first, we cache that response until the protobuf upload's response also -// arrives. -// -// Note that if the XML upload succeeds but the protobuf upload fails, we will -// not retry the protobuf upload. If the XML upload fails while the protobuf -// upload succeeds, we will still avoid re-uploading the protobuf data because -// we "zap" the data after the first upload attempt. This means that we might -// lose protobuf uploads when XML ones succeed; but we will never duplicate any -// protobuf uploads. Protobuf failures should be rare enough to where this -// should be ok while we have the two pipelines running in parallel. void MetricsService::OnURLFetchComplete(const content::URLFetcher* source) { DCHECK(waiting_for_asynchronus_reporting_step_); - - // We're not allowed to re-use the existing |URLFetcher|s, so free them here. - scoped_ptr<content::URLFetcher> s; - if (source == current_fetch_xml_.get()) { - s.reset(current_fetch_xml_.release()); - - // Cache the XML responses, in case we still need to wait for the protobuf - // response. - response_code_ = source->GetResponseCode(); - response_status_ = StatusToString(source->GetStatus()); - source->GetResponseAsString(&response_data_); - } else if (source == current_fetch_proto_.get()) { - s.reset(current_fetch_proto_.release()); - } else { - NOTREACHED(); - return; - } - - // If we're still waiting for one of the responses, keep waiting... - if (current_fetch_xml_.get() || current_fetch_proto_.get()) - return; - - // We should only be able to reach here once we've received responses to both - // the XML and the protobuf requests. We should always have the response code - // available. - DCHECK_NE(response_code_, content::URLFetcher::RESPONSE_CODE_INVALID); waiting_for_asynchronus_reporting_step_ = false; - + DCHECK(current_fetch_.get()); + // We're not allowed to re-use it. Delete it on function exit since we use it. + scoped_ptr<content::URLFetcher> s(current_fetch_.release()); // Confirm send so that we can move on. - VLOG(1) << "METRICS RESPONSE CODE: " << response_code_ - << " status=" << response_status_; + VLOG(1) << "METRICS RESPONSE CODE: " << source->GetResponseCode() + << " status=" << StatusToString(source->GetStatus()); - bool upload_succeeded = response_code_ == 200; + bool upload_succeeded = source->GetResponseCode() == 200; // Provide boolean for error recovery (allow us to ignore response_code). bool discard_log = false; if (!upload_succeeded && - log_manager_.staged_log_text().xml.length() > - kUploadLogAvoidRetransmitSize) { + (log_manager_.staged_log_text().length() > + static_cast<size_t>(kUploadLogAvoidRetransmitSize))) { UMA_HISTOGRAM_COUNTS( "UMA.Large Rejected Log was Discarded", - static_cast<int>(log_manager_.staged_log_text().xml.length())); + static_cast<int>(log_manager_.staged_log_text().length())); discard_log = true; - } else if (response_code_ == 400) { + } else if (source->GetResponseCode() == 400) { // Bad syntax. Retransmission won't work. UMA_HISTOGRAM_COUNTS("UMA.Unacceptable_Log_Discarded", state_); discard_log = true; @@ -1212,10 +1114,12 @@ void MetricsService::OnURLFetchComplete(const content::URLFetcher* source) { if (!upload_succeeded && !discard_log) { VLOG(1) << "METRICS: transmission attempt returned a failure code: " - << response_code_ << ". Verify network connectivity"; + << source->GetResponseCode() << ". Verify network connectivity"; LogBadResponseCode(); } else { // Successful receipt (or we are discarding log). - VLOG(1) << "METRICS RESPONSE DATA: " << response_data_; + std::string data; + source->GetResponseAsString(&data); + VLOG(1) << "METRICS RESPONSE DATA: " << data; switch (state_) { case INITIAL_LOG_READY: state_ = SENDING_OLD_LOGS; @@ -1242,7 +1146,7 @@ void MetricsService::OnURLFetchComplete(const content::URLFetcher* source) { // Error 400 indicates a problem with the log, not with the server, so // don't consider that a sign that the server is in trouble. - bool server_is_healthy = upload_succeeded || response_code_ == 400; + bool server_is_healthy = upload_succeeded || source->GetResponseCode() == 400; scheduler_->UploadFinished(server_is_healthy, log_manager_.has_unsent_logs()); @@ -1250,21 +1154,16 @@ void MetricsService::OnURLFetchComplete(const content::URLFetcher* source) { // Collect network stats if UMA upload succeeded. if (server_is_healthy && io_thread_) chrome_browser_net::CollectNetworkStats(network_stats_server_, io_thread_); - - // Reset the cached response data. - response_code_ = content::URLFetcher::RESPONSE_CODE_INVALID; - response_data_ = std::string(); - response_status_ = std::string(); } void MetricsService::LogBadResponseCode() { VLOG(1) << "Verify your metrics logs are formatted correctly. Verify server " - "is active at " << server_url_xml_; + "is active at " << server_url_; if (!log_manager_.has_staged_log()) { VLOG(1) << "METRICS: Recorder shutdown during log transmission."; } else { VLOG(1) << "METRICS: transmission retry being scheduled for " - << log_manager_.staged_log_text().xml; + << log_manager_.staged_log_text(); } } @@ -1636,6 +1535,13 @@ bool MetricsService::IsPluginProcess(content::ProcessType type) { type == content::PROCESS_TYPE_PPAPI_PLUGIN); } +static bool IsSingleThreaded() { + static base::PlatformThreadId thread_id = 0; + if (!thread_id) + thread_id = base::PlatformThread::CurrentId(); + return base::PlatformThread::CurrentId() == thread_id; +} + #if defined(OS_CHROMEOS) void MetricsService::StartExternalMetrics() { external_metrics_ = new chromeos::ExternalMetrics; diff --git a/chrome/browser/metrics/metrics_service.h b/chrome/browser/metrics/metrics_service.h index 9c22683..4280b44 100644 --- a/chrome/browser/metrics/metrics_service.h +++ b/chrome/browser/metrics/metrics_service.h @@ -339,18 +339,10 @@ class MetricsService : public content::NotificationObserver, std::vector<webkit::WebPluginInfo> plugins_; // The outstanding transmission appears as a URL Fetch operation. - scoped_ptr<content::URLFetcher> current_fetch_xml_; - scoped_ptr<content::URLFetcher> current_fetch_proto_; - - // Cached responses from the XML request while we wait for a response to the - // protubuf request. - int response_code_; - std::string response_status_; - std::string response_data_; - - // The URLs for the XML and protobuf metrics servers. - string16 server_url_xml_; - string16 server_url_proto_; + scoped_ptr<content::URLFetcher> current_fetch_; + + // The URL for the metrics server. + std::wstring server_url_; // The TCP/UDP echo server to collect network connectivity stats. std::string network_stats_server_; |