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 //------------------------------------------------------------------------------ | 5 //------------------------------------------------------------------------------ |
6 // Description of the life cycle of a instance of MetricsService. | 6 // Description of the life cycle of a instance of MetricsService. |
7 // | 7 // |
8 // OVERVIEW | 8 // OVERVIEW |
9 // | 9 // |
10 // A MetricsService instance is typically created at application startup. It is | 10 // A MetricsService instance is typically created at application startup. It is |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 return NO_RESPONSE; | 247 return NO_RESPONSE; |
248 case 200: | 248 case 200: |
249 return SUCCESS; | 249 return SUCCESS; |
250 case 400: | 250 case 400: |
251 return BAD_REQUEST; | 251 return BAD_REQUEST; |
252 default: | 252 default: |
253 return UNKNOWN_FAILURE; | 253 return UNKNOWN_FAILURE; |
254 } | 254 } |
255 } | 255 } |
256 | 256 |
257 void MarkAppCleanShutdownAndCommit(PrefService* local_state) { | 257 void MarkAppCleanShutdownAndCommit(CleanExitBeacon* clean_exit_beacon, |
258 local_state->SetBoolean(metrics::prefs::kStabilityExitedCleanly, true); | 258 PrefService* local_state) { |
| 259 clean_exit_beacon->WriteBeaconValue(true); |
259 local_state->SetInteger(metrics::prefs::kStabilityExecutionPhase, | 260 local_state->SetInteger(metrics::prefs::kStabilityExecutionPhase, |
260 MetricsService::SHUTDOWN_COMPLETE); | 261 MetricsService::SHUTDOWN_COMPLETE); |
261 // Start writing right away (write happens on a different thread). | 262 // Start writing right away (write happens on a different thread). |
262 local_state->CommitPendingWrite(); | 263 local_state->CommitPendingWrite(); |
263 } | 264 } |
264 | 265 |
265 } // namespace | 266 } // namespace |
266 | 267 |
267 | 268 |
268 SyntheticTrialGroup::SyntheticTrialGroup(uint32 trial, uint32 group) { | 269 SyntheticTrialGroup::SyntheticTrialGroup(uint32 trial, uint32 group) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 } | 309 } |
309 | 310 |
310 MetricsService::MetricsService(metrics::MetricsStateManager* state_manager, | 311 MetricsService::MetricsService(metrics::MetricsStateManager* state_manager, |
311 metrics::MetricsServiceClient* client, | 312 metrics::MetricsServiceClient* client, |
312 PrefService* local_state) | 313 PrefService* local_state) |
313 : log_manager_(local_state, kUploadLogAvoidRetransmitSize), | 314 : log_manager_(local_state, kUploadLogAvoidRetransmitSize), |
314 histogram_snapshot_manager_(this), | 315 histogram_snapshot_manager_(this), |
315 state_manager_(state_manager), | 316 state_manager_(state_manager), |
316 client_(client), | 317 client_(client), |
317 local_state_(local_state), | 318 local_state_(local_state), |
| 319 clean_exit_beacon_(client->GetRegistryBackupKey(), local_state), |
318 recording_active_(false), | 320 recording_active_(false), |
319 reporting_active_(false), | 321 reporting_active_(false), |
320 test_mode_active_(false), | 322 test_mode_active_(false), |
321 state_(INITIALIZED), | 323 state_(INITIALIZED), |
322 has_initial_stability_log_(false), | 324 has_initial_stability_log_(false), |
323 log_upload_in_progress_(false), | 325 log_upload_in_progress_(false), |
324 idle_since_last_transmission_(false), | 326 idle_since_last_transmission_(false), |
325 session_id_(-1), | 327 session_id_(-1), |
326 self_ptr_factory_(this), | 328 self_ptr_factory_(this), |
327 state_saver_factory_(this) { | 329 state_saver_factory_(this) { |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 | 493 |
492 void MetricsService::RecordCompletedSessionEnd() { | 494 void MetricsService::RecordCompletedSessionEnd() { |
493 LogCleanShutdown(); | 495 LogCleanShutdown(); |
494 RecordBooleanPrefValue(metrics::prefs::kStabilitySessionEndCompleted, true); | 496 RecordBooleanPrefValue(metrics::prefs::kStabilitySessionEndCompleted, true); |
495 } | 497 } |
496 | 498 |
497 #if defined(OS_ANDROID) || defined(OS_IOS) | 499 #if defined(OS_ANDROID) || defined(OS_IOS) |
498 void MetricsService::OnAppEnterBackground() { | 500 void MetricsService::OnAppEnterBackground() { |
499 scheduler_->Stop(); | 501 scheduler_->Stop(); |
500 | 502 |
501 MarkAppCleanShutdownAndCommit(local_state_); | 503 MarkAppCleanShutdownAndCommit(&clean_exit_beacon_, local_state_); |
502 | 504 |
503 // At this point, there's no way of knowing when the process will be | 505 // At this point, there's no way of knowing when the process will be |
504 // killed, so this has to be treated similar to a shutdown, closing and | 506 // killed, so this has to be treated similar to a shutdown, closing and |
505 // persisting all logs. Unlinke a shutdown, the state is primed to be ready | 507 // persisting all logs. Unlinke a shutdown, the state is primed to be ready |
506 // to continue logging and uploading if the process does return. | 508 // to continue logging and uploading if the process does return. |
507 if (recording_active() && state_ >= SENDING_INITIAL_STABILITY_LOG) { | 509 if (recording_active() && state_ >= SENDING_INITIAL_STABILITY_LOG) { |
508 PushPendingLogsToPersistentStorage(); | 510 PushPendingLogsToPersistentStorage(); |
509 // Persisting logs closes the current log, so start recording a new log | 511 // Persisting logs closes the current log, so start recording a new log |
510 // immediately to capture any background work that might be done before the | 512 // immediately to capture any background work that might be done before the |
511 // process is killed. | 513 // process is killed. |
512 OpenNewLog(); | 514 OpenNewLog(); |
513 } | 515 } |
514 } | 516 } |
515 | 517 |
516 void MetricsService::OnAppEnterForeground() { | 518 void MetricsService::OnAppEnterForeground() { |
517 local_state_->SetBoolean(metrics::prefs::kStabilityExitedCleanly, false); | 519 clean_exit_beacon_.WriteBeaconValue(false); |
518 StartSchedulerIfNecessary(); | 520 StartSchedulerIfNecessary(); |
519 } | 521 } |
520 #else | 522 #else |
521 void MetricsService::LogNeedForCleanShutdown() { | 523 void MetricsService::LogNeedForCleanShutdown() { |
522 local_state_->SetBoolean(metrics::prefs::kStabilityExitedCleanly, false); | 524 clean_exit_beacon_.WriteBeaconValue(false); |
523 // Redundant setting to be sure we call for a clean shutdown. | 525 // Redundant setting to be sure we call for a clean shutdown. |
524 clean_shutdown_status_ = NEED_TO_SHUTDOWN; | 526 clean_shutdown_status_ = NEED_TO_SHUTDOWN; |
525 } | 527 } |
526 #endif // defined(OS_ANDROID) || defined(OS_IOS) | 528 #endif // defined(OS_ANDROID) || defined(OS_IOS) |
527 | 529 |
528 // static | 530 // static |
529 void MetricsService::SetExecutionPhase(ExecutionPhase execution_phase, | 531 void MetricsService::SetExecutionPhase(ExecutionPhase execution_phase, |
530 PrefService* local_state) { | 532 PrefService* local_state) { |
531 execution_phase_ = execution_phase; | 533 execution_phase_ = execution_phase; |
532 local_state->SetInteger(metrics::prefs::kStabilityExecutionPhase, | 534 local_state->SetInteger(metrics::prefs::kStabilityExecutionPhase, |
(...skipping 24 matching lines...) Expand all Loading... |
557 | 559 |
558 void MetricsService::InitializeMetricsState() { | 560 void MetricsService::InitializeMetricsState() { |
559 local_state_->SetString(metrics::prefs::kStabilityStatsVersion, | 561 local_state_->SetString(metrics::prefs::kStabilityStatsVersion, |
560 client_->GetVersionString()); | 562 client_->GetVersionString()); |
561 local_state_->SetInt64(metrics::prefs::kStabilityStatsBuildTime, | 563 local_state_->SetInt64(metrics::prefs::kStabilityStatsBuildTime, |
562 MetricsLog::GetBuildTime()); | 564 MetricsLog::GetBuildTime()); |
563 | 565 |
564 log_manager_.LoadPersistedUnsentLogs(); | 566 log_manager_.LoadPersistedUnsentLogs(); |
565 | 567 |
566 session_id_ = local_state_->GetInteger(metrics::prefs::kMetricsSessionID); | 568 session_id_ = local_state_->GetInteger(metrics::prefs::kMetricsSessionID); |
567 bool exited_cleanly = true; | 569 |
568 if (!local_state_->GetBoolean(metrics::prefs::kStabilityExitedCleanly)) { | 570 if (!clean_exit_beacon_.exited_cleanly()) { |
569 IncrementPrefValue(metrics::prefs::kStabilityCrashCount); | 571 IncrementPrefValue(metrics::prefs::kStabilityCrashCount); |
570 // Reset flag, and wait until we call LogNeedForCleanShutdown() before | 572 // Reset flag, and wait until we call LogNeedForCleanShutdown() before |
571 // monitoring. | 573 // monitoring. |
572 local_state_->SetBoolean(metrics::prefs::kStabilityExitedCleanly, true); | 574 clean_exit_beacon_.WriteBeaconValue(true); |
573 exited_cleanly = false; | |
574 } | 575 } |
575 | 576 |
576 if (!exited_cleanly || ProvidersHaveStabilityMetrics()) { | 577 if (!clean_exit_beacon_.exited_cleanly() || ProvidersHaveStabilityMetrics()) { |
577 // TODO(rtenneti): On windows, consider saving/getting execution_phase from | 578 // TODO(rtenneti): On windows, consider saving/getting execution_phase from |
578 // the registry. | 579 // the registry. |
579 int execution_phase = | 580 int execution_phase = |
580 local_state_->GetInteger(metrics::prefs::kStabilityExecutionPhase); | 581 local_state_->GetInteger(metrics::prefs::kStabilityExecutionPhase); |
581 UMA_HISTOGRAM_SPARSE_SLOWLY("Chrome.Browser.CrashedExecutionPhase", | 582 UMA_HISTOGRAM_SPARSE_SLOWLY("Chrome.Browser.CrashedExecutionPhase", |
582 execution_phase); | 583 execution_phase); |
583 | 584 |
584 // If the previous session didn't exit cleanly, or if any provider | 585 // If the previous session didn't exit cleanly, or if any provider |
585 // explicitly requests it, prepare an initial stability log - | 586 // explicitly requests it, prepare an initial stability log - |
586 // provided UMA is enabled. | 587 // provided UMA is enabled. |
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1159 } | 1160 } |
1160 | 1161 |
1161 void MetricsService::RecordCurrentStabilityHistograms() { | 1162 void MetricsService::RecordCurrentStabilityHistograms() { |
1162 DCHECK(log_manager_.current_log()); | 1163 DCHECK(log_manager_.current_log()); |
1163 histogram_snapshot_manager_.PrepareDeltas( | 1164 histogram_snapshot_manager_.PrepareDeltas( |
1164 base::Histogram::kNoFlags, base::Histogram::kUmaStabilityHistogramFlag); | 1165 base::Histogram::kNoFlags, base::Histogram::kUmaStabilityHistogramFlag); |
1165 } | 1166 } |
1166 | 1167 |
1167 void MetricsService::LogCleanShutdown() { | 1168 void MetricsService::LogCleanShutdown() { |
1168 // Redundant hack to write pref ASAP. | 1169 // Redundant hack to write pref ASAP. |
1169 MarkAppCleanShutdownAndCommit(local_state_); | 1170 MarkAppCleanShutdownAndCommit(&clean_exit_beacon_, local_state_); |
1170 | 1171 |
1171 // Redundant setting to assure that we always reset this value at shutdown | 1172 // Redundant setting to assure that we always reset this value at shutdown |
1172 // (and that we don't use some alternate path, and not call LogCleanShutdown). | 1173 // (and that we don't use some alternate path, and not call LogCleanShutdown). |
1173 clean_shutdown_status_ = CLEANLY_SHUTDOWN; | 1174 clean_shutdown_status_ = CLEANLY_SHUTDOWN; |
1174 | 1175 |
1175 RecordBooleanPrefValue(metrics::prefs::kStabilityExitedCleanly, true); | 1176 clean_exit_beacon_.WriteBeaconValue(true); |
| 1177 RecordCurrentState(local_state_); |
1176 local_state_->SetInteger(metrics::prefs::kStabilityExecutionPhase, | 1178 local_state_->SetInteger(metrics::prefs::kStabilityExecutionPhase, |
1177 MetricsService::SHUTDOWN_COMPLETE); | 1179 MetricsService::SHUTDOWN_COMPLETE); |
1178 } | 1180 } |
1179 | 1181 |
1180 bool MetricsService::ShouldLogEvents() { | 1182 bool MetricsService::ShouldLogEvents() { |
1181 // We simply don't log events to UMA if there is a single incognito | 1183 // We simply don't log events to UMA if there is a single incognito |
1182 // session visible. The problem is that we always notify using the orginal | 1184 // session visible. The problem is that we always notify using the orginal |
1183 // profile in order to simplify notification processing. | 1185 // profile in order to simplify notification processing. |
1184 return !client_->IsOffTheRecordSessionActive(); | 1186 return !client_->IsOffTheRecordSessionActive(); |
1185 } | 1187 } |
1186 | 1188 |
1187 void MetricsService::RecordBooleanPrefValue(const char* path, bool value) { | 1189 void MetricsService::RecordBooleanPrefValue(const char* path, bool value) { |
1188 DCHECK(IsSingleThreaded()); | 1190 DCHECK(IsSingleThreaded()); |
1189 local_state_->SetBoolean(path, value); | 1191 local_state_->SetBoolean(path, value); |
1190 RecordCurrentState(local_state_); | 1192 RecordCurrentState(local_state_); |
1191 } | 1193 } |
1192 | 1194 |
1193 void MetricsService::RecordCurrentState(PrefService* pref) { | 1195 void MetricsService::RecordCurrentState(PrefService* pref) { |
1194 pref->SetInt64(metrics::prefs::kStabilityLastTimestampSec, | 1196 pref->SetInt64(metrics::prefs::kStabilityLastTimestampSec, |
1195 base::Time::Now().ToTimeT()); | 1197 base::Time::Now().ToTimeT()); |
1196 } | 1198 } |
1197 | 1199 |
1198 } // namespace metrics | 1200 } // namespace metrics |
OLD | NEW |