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

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

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

Powered by Google App Engine
This is Rietveld 408576698