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 |