| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/metrics/metrics_log.h" | 5 #include "components/metrics/metrics_log.h" |
| 6 | 6 |
| 7 #include <stddef.h> |
| 8 |
| 7 #include <algorithm> | 9 #include <algorithm> |
| 8 #include <string> | 10 #include <string> |
| 9 #include <vector> | 11 #include <vector> |
| 10 | 12 |
| 11 #include "base/base64.h" | 13 #include "base/base64.h" |
| 12 #include "base/basictypes.h" | |
| 13 #include "base/build_time.h" | 14 #include "base/build_time.h" |
| 14 #include "base/cpu.h" | 15 #include "base/cpu.h" |
| 15 #include "base/memory/scoped_ptr.h" | 16 #include "base/memory/scoped_ptr.h" |
| 16 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
| 17 #include "base/metrics/histogram_samples.h" | 18 #include "base/metrics/histogram_samples.h" |
| 18 #include "base/metrics/metrics_hashes.h" | 19 #include "base/metrics/metrics_hashes.h" |
| 19 #include "base/prefs/pref_registry_simple.h" | 20 #include "base/prefs/pref_registry_simple.h" |
| 20 #include "base/prefs/pref_service.h" | 21 #include "base/prefs/pref_service.h" |
| 21 #include "base/sha1.h" | 22 #include "base/sha1.h" |
| 22 #include "base/strings/string_number_conversions.h" | 23 #include "base/strings/string_number_conversions.h" |
| 23 #include "base/strings/string_util.h" | 24 #include "base/strings/string_util.h" |
| 24 #include "base/strings/utf_string_conversions.h" | 25 #include "base/strings/utf_string_conversions.h" |
| 25 #include "base/sys_info.h" | 26 #include "base/sys_info.h" |
| 26 #include "base/time/time.h" | 27 #include "base/time/time.h" |
| 28 #include "build/build_config.h" |
| 27 #include "components/metrics/histogram_encoder.h" | 29 #include "components/metrics/histogram_encoder.h" |
| 28 #include "components/metrics/metrics_pref_names.h" | 30 #include "components/metrics/metrics_pref_names.h" |
| 29 #include "components/metrics/metrics_provider.h" | 31 #include "components/metrics/metrics_provider.h" |
| 30 #include "components/metrics/metrics_service_client.h" | 32 #include "components/metrics/metrics_service_client.h" |
| 31 #include "components/metrics/proto/histogram_event.pb.h" | 33 #include "components/metrics/proto/histogram_event.pb.h" |
| 32 #include "components/metrics/proto/system_profile.pb.h" | 34 #include "components/metrics/proto/system_profile.pb.h" |
| 33 #include "components/metrics/proto/user_action_event.pb.h" | 35 #include "components/metrics/proto/user_action_event.pb.h" |
| 34 #include "components/variations/active_field_trials.h" | 36 #include "components/variations/active_field_trials.h" |
| 35 | 37 |
| 36 #if defined(OS_ANDROID) | 38 #if defined(OS_ANDROID) |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 SystemProfileProto::FieldTrial* field_trial = | 71 SystemProfileProto::FieldTrial* field_trial = |
| 70 system_profile->add_field_trial(); | 72 system_profile->add_field_trial(); |
| 71 field_trial->set_name_id(it->name); | 73 field_trial->set_name_id(it->name); |
| 72 field_trial->set_group_id(it->group); | 74 field_trial->set_group_id(it->group); |
| 73 } | 75 } |
| 74 } | 76 } |
| 75 | 77 |
| 76 // Round a timestamp measured in seconds since epoch to one with a granularity | 78 // Round a timestamp measured in seconds since epoch to one with a granularity |
| 77 // of an hour. This can be used before uploaded potentially sensitive | 79 // of an hour. This can be used before uploaded potentially sensitive |
| 78 // timestamps. | 80 // timestamps. |
| 79 int64 RoundSecondsToHour(int64 time_in_seconds) { | 81 int64_t RoundSecondsToHour(int64_t time_in_seconds) { |
| 80 return 3600 * (time_in_seconds / 3600); | 82 return 3600 * (time_in_seconds / 3600); |
| 81 } | 83 } |
| 82 | 84 |
| 83 } // namespace | 85 } // namespace |
| 84 | 86 |
| 85 MetricsLog::MetricsLog(const std::string& client_id, | 87 MetricsLog::MetricsLog(const std::string& client_id, |
| 86 int session_id, | 88 int session_id, |
| 87 LogType log_type, | 89 LogType log_type, |
| 88 MetricsServiceClient* client, | 90 MetricsServiceClient* client, |
| 89 PrefService* local_state) | 91 PrefService* local_state) |
| 90 : closed_(false), | 92 : closed_(false), |
| 91 log_type_(log_type), | 93 log_type_(log_type), |
| 92 client_(client), | 94 client_(client), |
| 93 creation_time_(base::TimeTicks::Now()), | 95 creation_time_(base::TimeTicks::Now()), |
| 94 local_state_(local_state) { | 96 local_state_(local_state) { |
| 95 if (IsTestingID(client_id)) | 97 if (IsTestingID(client_id)) |
| 96 uma_proto_.set_client_id(0); | 98 uma_proto_.set_client_id(0); |
| 97 else | 99 else |
| 98 uma_proto_.set_client_id(Hash(client_id)); | 100 uma_proto_.set_client_id(Hash(client_id)); |
| 99 | 101 |
| 100 uma_proto_.set_session_id(session_id); | 102 uma_proto_.set_session_id(session_id); |
| 101 | 103 |
| 102 const int32 product = client_->GetProduct(); | 104 const int32_t product = client_->GetProduct(); |
| 103 // Only set the product if it differs from the default value. | 105 // Only set the product if it differs from the default value. |
| 104 if (product != uma_proto_.product()) | 106 if (product != uma_proto_.product()) |
| 105 uma_proto_.set_product(product); | 107 uma_proto_.set_product(product); |
| 106 | 108 |
| 107 SystemProfileProto* system_profile = uma_proto_.mutable_system_profile(); | 109 SystemProfileProto* system_profile = uma_proto_.mutable_system_profile(); |
| 108 system_profile->set_build_timestamp(GetBuildTime()); | 110 system_profile->set_build_timestamp(GetBuildTime()); |
| 109 system_profile->set_app_version(client_->GetVersionString()); | 111 system_profile->set_app_version(client_->GetVersionString()); |
| 110 system_profile->set_channel(client_->GetChannel()); | 112 system_profile->set_channel(client_->GetChannel()); |
| 111 #if defined(SYZYASAN) | 113 #if defined(SYZYASAN) |
| 112 system_profile->set_is_asan_build(true); | 114 system_profile->set_is_asan_build(true); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 126 prefs::kStabilityBreakpadRegistrationSuccess, 0); | 128 prefs::kStabilityBreakpadRegistrationSuccess, 0); |
| 127 registry->RegisterIntegerPref(prefs::kStabilityDebuggerPresent, 0); | 129 registry->RegisterIntegerPref(prefs::kStabilityDebuggerPresent, 0); |
| 128 registry->RegisterIntegerPref(prefs::kStabilityDebuggerNotPresent, 0); | 130 registry->RegisterIntegerPref(prefs::kStabilityDebuggerNotPresent, 0); |
| 129 registry->RegisterStringPref(prefs::kStabilitySavedSystemProfile, | 131 registry->RegisterStringPref(prefs::kStabilitySavedSystemProfile, |
| 130 std::string()); | 132 std::string()); |
| 131 registry->RegisterStringPref(prefs::kStabilitySavedSystemProfileHash, | 133 registry->RegisterStringPref(prefs::kStabilitySavedSystemProfileHash, |
| 132 std::string()); | 134 std::string()); |
| 133 } | 135 } |
| 134 | 136 |
| 135 // static | 137 // static |
| 136 uint64 MetricsLog::Hash(const std::string& value) { | 138 uint64_t MetricsLog::Hash(const std::string& value) { |
| 137 uint64 hash = base::HashMetricName(value); | 139 uint64_t hash = base::HashMetricName(value); |
| 138 | 140 |
| 139 // The following log is VERY helpful when folks add some named histogram into | 141 // The following log is VERY helpful when folks add some named histogram into |
| 140 // the code, but forgot to update the descriptive list of histograms. When | 142 // the code, but forgot to update the descriptive list of histograms. When |
| 141 // that happens, all we get to see (server side) is a hash of the histogram | 143 // that happens, all we get to see (server side) is a hash of the histogram |
| 142 // name. We can then use this logging to find out what histogram name was | 144 // name. We can then use this logging to find out what histogram name was |
| 143 // being hashed to a given MD5 value by just running the version of Chromium | 145 // being hashed to a given MD5 value by just running the version of Chromium |
| 144 // in question with --enable-logging. | 146 // in question with --enable-logging. |
| 145 DVLOG(1) << "Metrics: Hash numeric [" << value << "]=[" << hash << "]"; | 147 DVLOG(1) << "Metrics: Hash numeric [" << value << "]=[" << hash << "]"; |
| 146 | 148 |
| 147 return hash; | 149 return hash; |
| 148 } | 150 } |
| 149 | 151 |
| 150 // static | 152 // static |
| 151 int64 MetricsLog::GetBuildTime() { | 153 int64_t MetricsLog::GetBuildTime() { |
| 152 static int64 integral_build_time = 0; | 154 static int64_t integral_build_time = 0; |
| 153 if (!integral_build_time) | 155 if (!integral_build_time) |
| 154 integral_build_time = static_cast<int64>(base::GetBuildTime().ToTimeT()); | 156 integral_build_time = static_cast<int64_t>(base::GetBuildTime().ToTimeT()); |
| 155 return integral_build_time; | 157 return integral_build_time; |
| 156 } | 158 } |
| 157 | 159 |
| 158 // static | 160 // static |
| 159 int64 MetricsLog::GetCurrentTime() { | 161 int64_t MetricsLog::GetCurrentTime() { |
| 160 return (base::TimeTicks::Now() - base::TimeTicks()).InSeconds(); | 162 return (base::TimeTicks::Now() - base::TimeTicks()).InSeconds(); |
| 161 } | 163 } |
| 162 | 164 |
| 163 void MetricsLog::RecordUserAction(const std::string& key) { | 165 void MetricsLog::RecordUserAction(const std::string& key) { |
| 164 DCHECK(!closed_); | 166 DCHECK(!closed_); |
| 165 | 167 |
| 166 UserActionEventProto* user_action = uma_proto_.add_user_action_event(); | 168 UserActionEventProto* user_action = uma_proto_.add_user_action_event(); |
| 167 user_action->set_name_hash(Hash(key)); | 169 user_action->set_name_hash(Hash(key)); |
| 168 user_action->set_time(GetCurrentTime()); | 170 user_action->set_time(GetCurrentTime()); |
| 169 } | 171 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 PrefService* pref, | 278 PrefService* pref, |
| 277 base::TimeDelta incremental_uptime, | 279 base::TimeDelta incremental_uptime, |
| 278 base::TimeDelta uptime) { | 280 base::TimeDelta uptime) { |
| 279 // Update the stats which are critical for real-time stability monitoring. | 281 // Update the stats which are critical for real-time stability monitoring. |
| 280 // Since these are "optional," only list ones that are non-zero, as the counts | 282 // Since these are "optional," only list ones that are non-zero, as the counts |
| 281 // are aggregated (summed) server side. | 283 // are aggregated (summed) server side. |
| 282 | 284 |
| 283 SystemProfileProto::Stability* stability = | 285 SystemProfileProto::Stability* stability = |
| 284 uma_proto()->mutable_system_profile()->mutable_stability(); | 286 uma_proto()->mutable_system_profile()->mutable_stability(); |
| 285 | 287 |
| 286 const uint64 incremental_uptime_sec = incremental_uptime.InSeconds(); | 288 const uint64_t incremental_uptime_sec = incremental_uptime.InSeconds(); |
| 287 if (incremental_uptime_sec) | 289 if (incremental_uptime_sec) |
| 288 stability->set_incremental_uptime_sec(incremental_uptime_sec); | 290 stability->set_incremental_uptime_sec(incremental_uptime_sec); |
| 289 const uint64 uptime_sec = uptime.InSeconds(); | 291 const uint64_t uptime_sec = uptime.InSeconds(); |
| 290 if (uptime_sec) | 292 if (uptime_sec) |
| 291 stability->set_uptime_sec(uptime_sec); | 293 stability->set_uptime_sec(uptime_sec); |
| 292 } | 294 } |
| 293 | 295 |
| 294 void MetricsLog::RecordEnvironment( | 296 void MetricsLog::RecordEnvironment( |
| 295 const std::vector<MetricsProvider*>& metrics_providers, | 297 const std::vector<MetricsProvider*>& metrics_providers, |
| 296 const std::vector<variations::ActiveGroupId>& synthetic_trials, | 298 const std::vector<variations::ActiveGroupId>& synthetic_trials, |
| 297 int64 install_date, | 299 int64_t install_date, |
| 298 int64 metrics_reporting_enabled_date) { | 300 int64_t metrics_reporting_enabled_date) { |
| 299 DCHECK(!HasEnvironment()); | 301 DCHECK(!HasEnvironment()); |
| 300 | 302 |
| 301 SystemProfileProto* system_profile = uma_proto()->mutable_system_profile(); | 303 SystemProfileProto* system_profile = uma_proto()->mutable_system_profile(); |
| 302 | 304 |
| 303 std::string brand_code; | 305 std::string brand_code; |
| 304 if (client_->GetBrand(&brand_code)) | 306 if (client_->GetBrand(&brand_code)) |
| 305 system_profile->set_brand_code(brand_code); | 307 system_profile->set_brand_code(brand_code); |
| 306 | 308 |
| 307 // Reduce granularity of the enabled_date field to nearest hour. | 309 // Reduce granularity of the enabled_date field to nearest hour. |
| 308 system_profile->set_uma_enabled_date( | 310 system_profile->set_uma_enabled_date( |
| 309 RoundSecondsToHour(metrics_reporting_enabled_date)); | 311 RoundSecondsToHour(metrics_reporting_enabled_date)); |
| 310 | 312 |
| 311 // Reduce granularity of the install_date field to nearest hour. | 313 // Reduce granularity of the install_date field to nearest hour. |
| 312 system_profile->set_install_date(RoundSecondsToHour(install_date)); | 314 system_profile->set_install_date(RoundSecondsToHour(install_date)); |
| 313 | 315 |
| 314 system_profile->set_application_locale(client_->GetApplicationLocale()); | 316 system_profile->set_application_locale(client_->GetApplicationLocale()); |
| 315 | 317 |
| 316 SystemProfileProto::Hardware* hardware = system_profile->mutable_hardware(); | 318 SystemProfileProto::Hardware* hardware = system_profile->mutable_hardware(); |
| 317 | 319 |
| 318 // HardwareModelName() will return an empty string on platforms where it's | 320 // HardwareModelName() will return an empty string on platforms where it's |
| 319 // not implemented or if an error occured. | 321 // not implemented or if an error occured. |
| 320 hardware->set_hardware_class(base::SysInfo::HardwareModelName()); | 322 hardware->set_hardware_class(base::SysInfo::HardwareModelName()); |
| 321 | 323 |
| 322 hardware->set_cpu_architecture(base::SysInfo::OperatingSystemArchitecture()); | 324 hardware->set_cpu_architecture(base::SysInfo::OperatingSystemArchitecture()); |
| 323 hardware->set_system_ram_mb(base::SysInfo::AmountOfPhysicalMemoryMB()); | 325 hardware->set_system_ram_mb(base::SysInfo::AmountOfPhysicalMemoryMB()); |
| 324 #if defined(OS_WIN) | 326 #if defined(OS_WIN) |
| 325 hardware->set_dll_base(reinterpret_cast<uint64>(&__ImageBase)); | 327 hardware->set_dll_base(reinterpret_cast<uint64_t>(&__ImageBase)); |
| 326 #endif | 328 #endif |
| 327 | 329 |
| 328 SystemProfileProto::OS* os = system_profile->mutable_os(); | 330 SystemProfileProto::OS* os = system_profile->mutable_os(); |
| 329 std::string os_name = base::SysInfo::OperatingSystemName(); | 331 std::string os_name = base::SysInfo::OperatingSystemName(); |
| 330 #if defined(OS_WIN) | 332 #if defined(OS_WIN) |
| 331 // TODO(mad): This only checks whether the main process is a Metro process at | 333 // TODO(mad): This only checks whether the main process is a Metro process at |
| 332 // upload time; not whether the collected metrics were all gathered from | 334 // upload time; not whether the collected metrics were all gathered from |
| 333 // Metro. This is ok as an approximation for now, since users will rarely be | 335 // Metro. This is ok as an approximation for now, since users will rarely be |
| 334 // switching from Metro to Desktop mode; but we should re-evaluate whether we | 336 // switching from Metro to Desktop mode; but we should re-evaluate whether we |
| 335 // can distinguish metrics more cleanly in the future: http://crbug.com/140568 | 337 // can distinguish metrics more cleanly in the future: http://crbug.com/140568 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 DCHECK(!closed_); | 394 DCHECK(!closed_); |
| 393 closed_ = true; | 395 closed_ = true; |
| 394 } | 396 } |
| 395 | 397 |
| 396 void MetricsLog::GetEncodedLog(std::string* encoded_log) { | 398 void MetricsLog::GetEncodedLog(std::string* encoded_log) { |
| 397 DCHECK(closed_); | 399 DCHECK(closed_); |
| 398 uma_proto_.SerializeToString(encoded_log); | 400 uma_proto_.SerializeToString(encoded_log); |
| 399 } | 401 } |
| 400 | 402 |
| 401 } // namespace metrics | 403 } // namespace metrics |
| OLD | NEW |