Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(390)

Side by Side Diff: components/metrics/metrics_log.cc

Issue 2687393004: Gather stability prefs into managing objects. (Closed)
Patch Set: Incorporate Feedback Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/metrics/metrics_log.h ('k') | components/metrics/metrics_log_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <string> 10 #include <string>
11 11
12 #include "base/base64.h"
13 #include "base/build_time.h" 12 #include "base/build_time.h"
14 #include "base/cpu.h" 13 #include "base/cpu.h"
15 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
16 #include "base/metrics/histogram_samples.h" 15 #include "base/metrics/histogram_samples.h"
17 #include "base/metrics/metrics_hashes.h" 16 #include "base/metrics/metrics_hashes.h"
18 #include "base/sha1.h"
19 #include "base/strings/string_number_conversions.h"
20 #include "base/strings/string_util.h"
21 #include "base/strings/utf_string_conversions.h"
22 #include "base/sys_info.h" 17 #include "base/sys_info.h"
23 #include "base/time/time.h" 18 #include "base/time/time.h"
24 #include "build/build_config.h" 19 #include "build/build_config.h"
20 #include "components/metrics/environment_recorder.h"
25 #include "components/metrics/histogram_encoder.h" 21 #include "components/metrics/histogram_encoder.h"
26 #include "components/metrics/metrics_pref_names.h" 22 #include "components/metrics/metrics_pref_names.h"
27 #include "components/metrics/metrics_provider.h" 23 #include "components/metrics/metrics_provider.h"
28 #include "components/metrics/metrics_service_client.h" 24 #include "components/metrics/metrics_service_client.h"
29 #include "components/metrics/proto/histogram_event.pb.h" 25 #include "components/metrics/proto/histogram_event.pb.h"
30 #include "components/metrics/proto/system_profile.pb.h" 26 #include "components/metrics/proto/system_profile.pb.h"
31 #include "components/metrics/proto/user_action_event.pb.h" 27 #include "components/metrics/proto/user_action_event.pb.h"
32 #include "components/prefs/pref_registry_simple.h" 28 #include "components/prefs/pref_registry_simple.h"
33 #include "components/prefs/pref_service.h" 29 #include "components/prefs/pref_service.h"
34 #include "components/variations/active_field_trials.h" 30 #include "components/variations/active_field_trials.h"
(...skipping 11 matching lines...) Expand all
46 42
47 namespace metrics { 43 namespace metrics {
48 44
49 namespace { 45 namespace {
50 46
51 // Any id less than 16 bytes is considered to be a testing id. 47 // Any id less than 16 bytes is considered to be a testing id.
52 bool IsTestingID(const std::string& id) { 48 bool IsTestingID(const std::string& id) {
53 return id.size() < 16; 49 return id.size() < 16;
54 } 50 }
55 51
56 // Computes a SHA-1 hash of |data| and returns it as a hex string.
57 std::string ComputeSHA1(const std::string& data) {
58 const std::string sha1 = base::SHA1HashString(data);
59 return base::HexEncode(sha1.data(), sha1.size());
60 }
61
62 void WriteFieldTrials(const std::vector<ActiveGroupId>& field_trial_ids, 52 void WriteFieldTrials(const std::vector<ActiveGroupId>& field_trial_ids,
63 SystemProfileProto* system_profile) { 53 SystemProfileProto* system_profile) {
64 for (std::vector<ActiveGroupId>::const_iterator it = 54 for (std::vector<ActiveGroupId>::const_iterator it =
65 field_trial_ids.begin(); it != field_trial_ids.end(); ++it) { 55 field_trial_ids.begin(); it != field_trial_ids.end(); ++it) {
66 SystemProfileProto::FieldTrial* field_trial = 56 SystemProfileProto::FieldTrial* field_trial =
67 system_profile->add_field_trial(); 57 system_profile->add_field_trial();
68 field_trial->set_name_id(it->name); 58 field_trial->set_name_id(it->name);
69 field_trial->set_group_id(it->group); 59 field_trial->set_group_id(it->group);
70 } 60 }
71 } 61 }
(...skipping 30 matching lines...) Expand all
102 uma_proto_.set_product(product); 92 uma_proto_.set_product(product);
103 93
104 RecordCoreSystemProfile(client_, uma_proto_.mutable_system_profile()); 94 RecordCoreSystemProfile(client_, uma_proto_.mutable_system_profile());
105 } 95 }
106 96
107 MetricsLog::~MetricsLog() { 97 MetricsLog::~MetricsLog() {
108 } 98 }
109 99
110 // static 100 // static
111 void MetricsLog::RegisterPrefs(PrefRegistrySimple* registry) { 101 void MetricsLog::RegisterPrefs(PrefRegistrySimple* registry) {
112 registry->RegisterIntegerPref(prefs::kStabilityCrashCount, 0); 102 EnvironmentRecorder::RegisterPrefs(registry);
113 registry->RegisterIntegerPref(prefs::kStabilityIncompleteSessionEndCount, 0);
114 registry->RegisterIntegerPref(prefs::kStabilityLaunchCount, 0);
115 registry->RegisterIntegerPref(prefs::kStabilityBreakpadRegistrationFail, 0);
116 registry->RegisterIntegerPref(
117 prefs::kStabilityBreakpadRegistrationSuccess, 0);
118 registry->RegisterIntegerPref(prefs::kStabilityDebuggerPresent, 0);
119 registry->RegisterIntegerPref(prefs::kStabilityDebuggerNotPresent, 0);
120 registry->RegisterStringPref(prefs::kStabilitySavedSystemProfile,
121 std::string());
122 registry->RegisterStringPref(prefs::kStabilitySavedSystemProfileHash,
123 std::string());
124 registry->RegisterIntegerPref(prefs::kStabilityDeferredCount, 0);
125 registry->RegisterIntegerPref(prefs::kStabilityDiscardCount, 0);
126 registry->RegisterIntegerPref(prefs::kStabilityVersionMismatchCount, 0);
127 } 103 }
128 104
129 // static 105 // static
130 uint64_t MetricsLog::Hash(const std::string& value) { 106 uint64_t MetricsLog::Hash(const std::string& value) {
131 uint64_t hash = base::HashMetricName(value); 107 uint64_t hash = base::HashMetricName(value);
132 108
133 // The following log is VERY helpful when folks add some named histogram into 109 // The following log is VERY helpful when folks add some named histogram into
134 // the code, but forgot to update the descriptive list of histograms. When 110 // the code, but forgot to update the descriptive list of histograms. When
135 // that happens, all we get to see (server side) is a hash of the histogram 111 // that happens, all we get to see (server side) is a hash of the histogram
136 // name. We can then use this logging to find out what histogram name was 112 // name. We can then use this logging to find out what histogram name was
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 } 179 }
204 180
205 void MetricsLog::RecordStabilityMetrics( 181 void MetricsLog::RecordStabilityMetrics(
206 const std::vector<std::unique_ptr<MetricsProvider>>& metrics_providers, 182 const std::vector<std::unique_ptr<MetricsProvider>>& metrics_providers,
207 base::TimeDelta incremental_uptime, 183 base::TimeDelta incremental_uptime,
208 base::TimeDelta uptime) { 184 base::TimeDelta uptime) {
209 DCHECK(!closed_); 185 DCHECK(!closed_);
210 DCHECK(HasEnvironment()); 186 DCHECK(HasEnvironment());
211 DCHECK(!HasStabilityMetrics()); 187 DCHECK(!HasStabilityMetrics());
212 188
213 PrefService* pref = local_state_;
214 DCHECK(pref);
215
216 // Get stability attributes out of Local State, zeroing out stored values.
217 // NOTE: This could lead to some data loss if this report isn't successfully
218 // sent, but that's true for all the metrics.
219
220 WriteRequiredStabilityAttributes(pref);
221
222 // Record recent delta for critical stability metrics. We can't wait for a 189 // Record recent delta for critical stability metrics. We can't wait for a
223 // restart to gather these, as that delay biases our observation away from 190 // restart to gather these, as that delay biases our observation away from
224 // users that run happily for a looooong time. We send increments with each 191 // users that run happily for a looooong time. We send increments with each
225 // uma log upload, just as we send histogram data. 192 // uma log upload, just as we send histogram data.
226 WriteRealtimeStabilityAttributes(pref, incremental_uptime, uptime); 193 WriteRealtimeStabilityAttributes(incremental_uptime, uptime);
227 194
228 SystemProfileProto* system_profile = uma_proto()->mutable_system_profile(); 195 SystemProfileProto* system_profile = uma_proto()->mutable_system_profile();
229 for (size_t i = 0; i < metrics_providers.size(); ++i) { 196 for (size_t i = 0; i < metrics_providers.size(); ++i) {
230 if (log_type() == INITIAL_STABILITY_LOG) 197 if (log_type() == INITIAL_STABILITY_LOG)
231 metrics_providers[i]->ProvideInitialStabilityMetrics(system_profile); 198 metrics_providers[i]->ProvideInitialStabilityMetrics(system_profile);
232 metrics_providers[i]->ProvideStabilityMetrics(system_profile); 199 metrics_providers[i]->ProvideStabilityMetrics(system_profile);
233 } 200 }
234
235 SystemProfileProto::Stability* stability =
236 system_profile->mutable_stability();
237
238 int incomplete_shutdown_count =
239 pref->GetInteger(prefs::kStabilityIncompleteSessionEndCount);
240 if (incomplete_shutdown_count) {
241 pref->SetInteger(prefs::kStabilityIncompleteSessionEndCount, 0);
242 stability->set_incomplete_shutdown_count(incomplete_shutdown_count);
243 }
244
245 int breakpad_registration_success_count =
246 pref->GetInteger(prefs::kStabilityBreakpadRegistrationSuccess);
247 if (breakpad_registration_success_count) {
248 pref->SetInteger(prefs::kStabilityBreakpadRegistrationSuccess, 0);
249 stability->set_breakpad_registration_success_count(
250 breakpad_registration_success_count);
251 }
252
253 int breakpad_registration_failure_count =
254 pref->GetInteger(prefs::kStabilityBreakpadRegistrationFail);
255 if (breakpad_registration_failure_count) {
256 pref->SetInteger(prefs::kStabilityBreakpadRegistrationFail, 0);
257 stability->set_breakpad_registration_failure_count(
258 breakpad_registration_failure_count);
259 }
260
261 int debugger_present_count =
262 pref->GetInteger(prefs::kStabilityDebuggerPresent);
263 if (debugger_present_count) {
264 pref->SetInteger(prefs::kStabilityDebuggerPresent, 0);
265 stability->set_debugger_present_count(debugger_present_count);
266 }
267
268 int debugger_not_present_count =
269 pref->GetInteger(prefs::kStabilityDebuggerNotPresent);
270 if (debugger_not_present_count) {
271 pref->SetInteger(prefs::kStabilityDebuggerNotPresent, 0);
272 stability->set_debugger_not_present_count(debugger_not_present_count);
273 }
274
275 // Note: only logging the following histograms for non-zero values.
276
277 int deferred_count = pref->GetInteger(prefs::kStabilityDeferredCount);
278 if (deferred_count) {
279 local_state_->SetInteger(prefs::kStabilityDeferredCount, 0);
280 UMA_STABILITY_HISTOGRAM_COUNTS_100(
281 "Stability.Internals.InitialStabilityLogDeferredCount", deferred_count);
282 }
283
284 int discard_count = local_state_->GetInteger(prefs::kStabilityDiscardCount);
285 if (discard_count) {
286 local_state_->SetInteger(prefs::kStabilityDiscardCount, 0);
287 UMA_STABILITY_HISTOGRAM_COUNTS_100("Stability.Internals.DataDiscardCount",
288 discard_count);
289 }
290
291 int version_mismatch_count =
292 local_state_->GetInteger(prefs::kStabilityVersionMismatchCount);
293 if (version_mismatch_count) {
294 local_state_->SetInteger(prefs::kStabilityVersionMismatchCount, 0);
295 UMA_STABILITY_HISTOGRAM_COUNTS_100(
296 "Stability.Internals.VersionMismatchCount",
297 version_mismatch_count);
298 }
299 } 201 }
300 202
301 void MetricsLog::RecordGeneralMetrics( 203 void MetricsLog::RecordGeneralMetrics(
302 const std::vector<std::unique_ptr<MetricsProvider>>& metrics_providers) { 204 const std::vector<std::unique_ptr<MetricsProvider>>& metrics_providers) {
303 if (local_state_->GetBoolean(prefs::kMetricsResetIds)) 205 if (local_state_->GetBoolean(prefs::kMetricsResetIds))
304 UMA_HISTOGRAM_BOOLEAN("UMA.IsClonedInstall", true); 206 UMA_HISTOGRAM_BOOLEAN("UMA.IsClonedInstall", true);
305 207
306 for (size_t i = 0; i < metrics_providers.size(); ++i) 208 for (size_t i = 0; i < metrics_providers.size(); ++i)
307 metrics_providers[i]->ProvideGeneralMetrics(uma_proto()); 209 metrics_providers[i]->ProvideGeneralMetrics(uma_proto());
308 } 210 }
(...skipping 28 matching lines...) Expand all
337 case EnableMetricsDefault::OPT_OUT: 239 case EnableMetricsDefault::OPT_OUT:
338 system_profile->set_uma_default_state( 240 system_profile->set_uma_default_state(
339 SystemProfileProto_UmaDefaultState_OPT_OUT); 241 SystemProfileProto_UmaDefaultState_OPT_OUT);
340 } 242 }
341 } 243 }
342 244
343 bool MetricsLog::HasStabilityMetrics() const { 245 bool MetricsLog::HasStabilityMetrics() const {
344 return uma_proto()->system_profile().stability().has_launch_count(); 246 return uma_proto()->system_profile().stability().has_launch_count();
345 } 247 }
346 248
347 // The server refuses data that doesn't have certain values. crashcount and
348 // launchcount are currently "required" in the "stability" group.
349 // TODO(isherman): Stop writing these attributes specially once the migration to
350 // protobufs is complete.
351 void MetricsLog::WriteRequiredStabilityAttributes(PrefService* pref) {
352 int launch_count = pref->GetInteger(prefs::kStabilityLaunchCount);
353 if (launch_count)
354 pref->SetInteger(prefs::kStabilityLaunchCount, 0);
355 int crash_count = pref->GetInteger(prefs::kStabilityCrashCount);
356 if (crash_count)
357 pref->SetInteger(prefs::kStabilityCrashCount, 0);
358
359 SystemProfileProto::Stability* stability =
360 uma_proto()->mutable_system_profile()->mutable_stability();
361 stability->set_launch_count(launch_count);
362 stability->set_crash_count(crash_count);
363 }
364
365 void MetricsLog::WriteRealtimeStabilityAttributes( 249 void MetricsLog::WriteRealtimeStabilityAttributes(
366 PrefService* pref,
367 base::TimeDelta incremental_uptime, 250 base::TimeDelta incremental_uptime,
368 base::TimeDelta uptime) { 251 base::TimeDelta uptime) {
369 // Update the stats which are critical for real-time stability monitoring. 252 // Update the stats which are critical for real-time stability monitoring.
370 // Since these are "optional," only list ones that are non-zero, as the counts 253 // Since these are "optional," only list ones that are non-zero, as the counts
371 // are aggregated (summed) server side. 254 // are aggregated (summed) server side.
372 255
373 SystemProfileProto::Stability* stability = 256 SystemProfileProto::Stability* stability =
374 uma_proto()->mutable_system_profile()->mutable_stability(); 257 uma_proto()->mutable_system_profile()->mutable_stability();
375 258
376 const uint64_t incremental_uptime_sec = incremental_uptime.InSeconds(); 259 const uint64_t incremental_uptime_sec = incremental_uptime.InSeconds();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 cpu->set_num_cores(base::SysInfo::NumberOfProcessors()); 295 cpu->set_num_cores(base::SysInfo::NumberOfProcessors());
413 296
414 std::vector<ActiveGroupId> field_trial_ids; 297 std::vector<ActiveGroupId> field_trial_ids;
415 GetFieldTrialIds(&field_trial_ids); 298 GetFieldTrialIds(&field_trial_ids);
416 WriteFieldTrials(field_trial_ids, system_profile); 299 WriteFieldTrials(field_trial_ids, system_profile);
417 WriteFieldTrials(synthetic_trials, system_profile); 300 WriteFieldTrials(synthetic_trials, system_profile);
418 301
419 for (size_t i = 0; i < metrics_providers.size(); ++i) 302 for (size_t i = 0; i < metrics_providers.size(); ++i)
420 metrics_providers[i]->ProvideSystemProfileMetrics(system_profile); 303 metrics_providers[i]->ProvideSystemProfileMetrics(system_profile);
421 304
422 std::string serialized_system_profile; 305 EnvironmentRecorder recorder(local_state_);
423 std::string base64_system_profile; 306 return recorder.SerializeAndRecordEnvironmentToPrefs(*system_profile);
424 if (system_profile->SerializeToString(&serialized_system_profile)) {
425 // Persist the system profile to disk. In the event of an unclean shutdown,
426 // it will be used as part of the initial stability report.
427 base::Base64Encode(serialized_system_profile, &base64_system_profile);
428 PrefService* local_state = local_state_;
429 local_state->SetString(prefs::kStabilitySavedSystemProfile,
430 base64_system_profile);
431 local_state->SetString(prefs::kStabilitySavedSystemProfileHash,
432 ComputeSHA1(serialized_system_profile));
433 }
434
435 return serialized_system_profile;
436 } 307 }
437 308
438 bool MetricsLog::LoadSavedEnvironmentFromPrefs(std::string* app_version) { 309 bool MetricsLog::LoadSavedEnvironmentFromPrefs(std::string* app_version) {
439 DCHECK(app_version); 310 DCHECK(app_version);
440 app_version->clear(); 311 app_version->clear();
441 312
442 PrefService* local_state = local_state_;
443 const std::string base64_system_profile =
444 local_state->GetString(prefs::kStabilitySavedSystemProfile);
445 if (base64_system_profile.empty())
446 return false;
447 const std::string system_profile_hash =
448 local_state->GetString(prefs::kStabilitySavedSystemProfileHash);
449
450 SystemProfileProto* system_profile = uma_proto()->mutable_system_profile(); 313 SystemProfileProto* system_profile = uma_proto()->mutable_system_profile();
451 std::string serialized_system_profile; 314 EnvironmentRecorder recorder(local_state_);
452 315 bool success = recorder.LoadEnvironmentFromPrefs(system_profile);
453 bool success =
454 base::Base64Decode(base64_system_profile, &serialized_system_profile) &&
455 ComputeSHA1(serialized_system_profile) == system_profile_hash &&
456 system_profile->ParseFromString(serialized_system_profile);
457 if (success) 316 if (success)
458 *app_version = system_profile->app_version(); 317 *app_version = system_profile->app_version();
459 return success; 318 return success;
460 } 319 }
461 320
462 void MetricsLog::CloseLog() { 321 void MetricsLog::CloseLog() {
463 DCHECK(!closed_); 322 DCHECK(!closed_);
464 closed_ = true; 323 closed_ = true;
465 } 324 }
466 325
467 void MetricsLog::GetEncodedLog(std::string* encoded_log) { 326 void MetricsLog::GetEncodedLog(std::string* encoded_log) {
468 DCHECK(closed_); 327 DCHECK(closed_);
469 uma_proto_.SerializeToString(encoded_log); 328 uma_proto_.SerializeToString(encoded_log);
470 } 329 }
471 330
472 } // namespace metrics 331 } // namespace metrics
OLDNEW
« no previous file with comments | « components/metrics/metrics_log.h ('k') | components/metrics/metrics_log_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698