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

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

Issue 2608833002: Move logic for uploading logs into a ReportingService object. (Closed)
Patch Set: Fix iOS/Android typo Created 3 years, 9 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 //------------------------------------------------------------------------------ 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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 124
125 #include "components/metrics/metrics_service.h" 125 #include "components/metrics/metrics_service.h"
126 126
127 #include <stddef.h> 127 #include <stddef.h>
128 128
129 #include <algorithm> 129 #include <algorithm>
130 #include <utility> 130 #include <utility>
131 131
132 #include "base/bind.h" 132 #include "base/bind.h"
133 #include "base/callback.h" 133 #include "base/callback.h"
134 #include "base/feature_list.h"
135 #include "base/location.h" 134 #include "base/location.h"
136 #include "base/memory/ptr_util.h" 135 #include "base/memory/ptr_util.h"
137 #include "base/metrics/histogram_base.h" 136 #include "base/metrics/histogram_base.h"
138 #include "base/metrics/histogram_macros.h" 137 #include "base/metrics/histogram_macros.h"
139 #include "base/metrics/histogram_samples.h" 138 #include "base/metrics/histogram_samples.h"
140 #include "base/metrics/persistent_histogram_allocator.h" 139 #include "base/metrics/persistent_histogram_allocator.h"
141 #include "base/metrics/sparse_histogram.h" 140 #include "base/metrics/sparse_histogram.h"
142 #include "base/metrics/statistics_recorder.h" 141 #include "base/metrics/statistics_recorder.h"
143 #include "base/single_thread_task_runner.h" 142 #include "base/single_thread_task_runner.h"
144 #include "base/strings/string_number_conversions.h"
145 #include "base/strings/utf_string_conversions.h"
146 #include "base/threading/thread_task_runner_handle.h" 143 #include "base/threading/thread_task_runner_handle.h"
147 #include "base/time/time.h" 144 #include "base/time/time.h"
148 #include "base/tracked_objects.h" 145 #include "base/tracked_objects.h"
149 #include "build/build_config.h" 146 #include "build/build_config.h"
150 #include "components/metrics/data_use_tracker.h"
151 #include "components/metrics/environment_recorder.h" 147 #include "components/metrics/environment_recorder.h"
152 #include "components/metrics/metrics_log.h" 148 #include "components/metrics/metrics_log.h"
153 #include "components/metrics/metrics_log_manager.h" 149 #include "components/metrics/metrics_log_manager.h"
154 #include "components/metrics/metrics_log_uploader.h" 150 #include "components/metrics/metrics_log_uploader.h"
155 #include "components/metrics/metrics_pref_names.h" 151 #include "components/metrics/metrics_pref_names.h"
156 #include "components/metrics/metrics_reporting_scheduler.h"
157 #include "components/metrics/metrics_rotation_scheduler.h" 152 #include "components/metrics/metrics_rotation_scheduler.h"
158 #include "components/metrics/metrics_service_client.h" 153 #include "components/metrics/metrics_service_client.h"
159 #include "components/metrics/metrics_state_manager.h" 154 #include "components/metrics/metrics_state_manager.h"
160 #include "components/metrics/metrics_upload_scheduler.h"
161 #include "components/metrics/stability_metrics_provider.h" 155 #include "components/metrics/stability_metrics_provider.h"
162 #include "components/metrics/url_constants.h" 156 #include "components/metrics/url_constants.h"
163 #include "components/prefs/pref_registry_simple.h" 157 #include "components/prefs/pref_registry_simple.h"
164 #include "components/prefs/pref_service.h" 158 #include "components/prefs/pref_service.h"
165 #include "components/variations/entropy_provider.h" 159 #include "components/variations/entropy_provider.h"
166 160
167 namespace metrics { 161 namespace metrics {
168 162
169 namespace { 163 namespace {
170 164
(...skipping 10 matching lines...) Expand all
181 // TODO(dfalcantara): To avoid delaying startup, tighten up initialization so 175 // TODO(dfalcantara): To avoid delaying startup, tighten up initialization so
182 // that it occurs after the user gets their initial page. 176 // that it occurs after the user gets their initial page.
183 const int kInitializationDelaySeconds = 5; 177 const int kInitializationDelaySeconds = 5;
184 #else 178 #else
185 const int kInitializationDelaySeconds = 30; 179 const int kInitializationDelaySeconds = 30;
186 #endif 180 #endif
187 181
188 // The maximum number of events in a log uploaded to the UMA server. 182 // The maximum number of events in a log uploaded to the UMA server.
189 const int kEventLimit = 2400; 183 const int kEventLimit = 2400;
190 184
191 // If an upload fails, and the transmission was over this byte count, then we
192 // will discard the log, and not try to retransmit it. We also don't persist
193 // the log to the prefs for transmission during the next chrome session if this
194 // limit is exceeded.
195 const size_t kUploadLogAvoidRetransmitSize = 100 * 1024;
196
197 enum ResponseStatus {
198 UNKNOWN_FAILURE,
199 SUCCESS,
200 BAD_REQUEST, // Invalid syntax or log too large.
201 NO_RESPONSE,
202 NUM_RESPONSE_STATUSES
203 };
204
205 ResponseStatus ResponseCodeToStatus(int response_code) {
206 switch (response_code) {
207 case -1:
208 return NO_RESPONSE;
209 case 200:
210 return SUCCESS;
211 case 400:
212 return BAD_REQUEST;
213 default:
214 return UNKNOWN_FAILURE;
215 }
216 }
217
218 #if defined(OS_ANDROID) || defined(OS_IOS) 185 #if defined(OS_ANDROID) || defined(OS_IOS)
219 void MarkAppCleanShutdownAndCommit(CleanExitBeacon* clean_exit_beacon, 186 void MarkAppCleanShutdownAndCommit(CleanExitBeacon* clean_exit_beacon,
220 PrefService* local_state) { 187 PrefService* local_state) {
221 clean_exit_beacon->WriteBeaconValue(true); 188 clean_exit_beacon->WriteBeaconValue(true);
222 ExecutionPhaseManager(local_state).OnAppEnterBackground(); 189 ExecutionPhaseManager(local_state).OnAppEnterBackground();
223 // Start writing right away (write happens on a different thread). 190 // Start writing right away (write happens on a different thread).
224 local_state->CommitPendingWrite(); 191 local_state->CommitPendingWrite();
225 } 192 }
226 #endif // defined(OS_ANDROID) || defined(OS_IOS) 193 #endif // defined(OS_ANDROID) || defined(OS_IOS)
227 194
(...skipping 19 matching lines...) Expand all
247 registry->RegisterListPref(prefs::kMetricsInitialLogs); 214 registry->RegisterListPref(prefs::kMetricsInitialLogs);
248 registry->RegisterListPref(prefs::kMetricsOngoingLogs); 215 registry->RegisterListPref(prefs::kMetricsOngoingLogs);
249 216
250 registry->RegisterInt64Pref(prefs::kUninstallLaunchCount, 0); 217 registry->RegisterInt64Pref(prefs::kUninstallLaunchCount, 0);
251 registry->RegisterInt64Pref(prefs::kUninstallMetricsUptimeSec, 0); 218 registry->RegisterInt64Pref(prefs::kUninstallMetricsUptimeSec, 0);
252 } 219 }
253 220
254 MetricsService::MetricsService(MetricsStateManager* state_manager, 221 MetricsService::MetricsService(MetricsStateManager* state_manager,
255 MetricsServiceClient* client, 222 MetricsServiceClient* client,
256 PrefService* local_state) 223 PrefService* local_state)
257 : log_store_(local_state, kUploadLogAvoidRetransmitSize), 224 : reporting_service_(client, local_state),
258 histogram_snapshot_manager_(this), 225 histogram_snapshot_manager_(this),
259 state_manager_(state_manager), 226 state_manager_(state_manager),
260 client_(client), 227 client_(client),
261 local_state_(local_state), 228 local_state_(local_state),
262 clean_exit_beacon_(client->GetRegistryBackupKey(), local_state), 229 clean_exit_beacon_(client->GetRegistryBackupKey(), local_state),
263 recording_state_(UNSET), 230 recording_state_(UNSET),
264 reporting_active_(false),
265 test_mode_active_(false), 231 test_mode_active_(false),
266 state_(INITIALIZED), 232 state_(INITIALIZED),
267 log_upload_in_progress_(false),
268 idle_since_last_transmission_(false), 233 idle_since_last_transmission_(false),
269 session_id_(-1), 234 session_id_(-1),
270 data_use_tracker_(DataUseTracker::Create(local_state_)),
271 self_ptr_factory_(this) { 235 self_ptr_factory_(this) {
272 DCHECK(thread_checker_.CalledOnValidThread()); 236 DCHECK(thread_checker_.CalledOnValidThread());
273 DCHECK(state_manager_); 237 DCHECK(state_manager_);
274 DCHECK(client_); 238 DCHECK(client_);
275 DCHECK(local_state_); 239 DCHECK(local_state_);
276 240
277 // Set the install date if this is our first run. 241 // Set the install date if this is our first run.
278 int64_t install_date = local_state_->GetInt64(prefs::kInstallDate); 242 int64_t install_date = local_state_->GetInt64(prefs::kInstallDate);
279 if (install_date == 0) 243 if (install_date == 0)
280 local_state_->SetInt64(prefs::kInstallDate, base::Time::Now().ToTimeT()); 244 local_state_->SetInt64(prefs::kInstallDate, base::Time::Now().ToTimeT());
281 245
282 RegisterMetricsProvider(std::unique_ptr<metrics::MetricsProvider>( 246 RegisterMetricsProvider(std::unique_ptr<metrics::MetricsProvider>(
283 new StabilityMetricsProvider(local_state_))); 247 new StabilityMetricsProvider(local_state_)));
284 } 248 }
285 249
286 MetricsService::~MetricsService() { 250 MetricsService::~MetricsService() {
287 DisableRecording(); 251 DisableRecording();
288 } 252 }
289 253
290 void MetricsService::InitializeMetricsRecordingState() { 254 void MetricsService::InitializeMetricsRecordingState() {
255 reporting_service_.Initialize();
291 InitializeMetricsState(); 256 InitializeMetricsState();
292 257
293 base::Closure upload_callback = 258 base::Closure upload_callback =
294 base::Bind(&MetricsService::StartScheduledUpload, 259 base::Bind(&MetricsService::StartScheduledUpload,
295 self_ptr_factory_.GetWeakPtr()); 260 self_ptr_factory_.GetWeakPtr());
296 261
297 rotation_scheduler_.reset(new MetricsRotationScheduler( 262 rotation_scheduler_.reset(new MetricsRotationScheduler(
298 upload_callback, 263 upload_callback,
299 // MetricsServiceClient outlives MetricsService, and 264 // MetricsServiceClient outlives MetricsService, and
300 // MetricsRotationScheduler is tied to the lifetime of |this|. 265 // MetricsRotationScheduler is tied to the lifetime of |this|.
301 base::Bind(&MetricsServiceClient::GetStandardUploadInterval, 266 base::Bind(&MetricsServiceClient::GetStandardUploadInterval,
302 base::Unretained(client_)))); 267 base::Unretained(client_))));
303 base::Closure send_next_log_callback =
304 base::Bind(&MetricsService::SendNextLog, self_ptr_factory_.GetWeakPtr());
305 upload_scheduler_.reset(new MetricsUploadScheduler(send_next_log_callback));
306 268
307 for (auto& provider : metrics_providers_) 269 for (auto& provider : metrics_providers_)
308 provider->Init(); 270 provider->Init();
309 } 271 }
310 272
311 void MetricsService::Start() { 273 void MetricsService::Start() {
312 HandleIdleSinceLastTransmission(false); 274 HandleIdleSinceLastTransmission(false);
313 EnableRecording(); 275 EnableRecording();
314 EnableReporting(); 276 EnableReporting();
315 } 277 }
316 278
317 void MetricsService::StartRecordingForTests() { 279 void MetricsService::StartRecordingForTests() {
318 test_mode_active_ = true; 280 test_mode_active_ = true;
319 EnableRecording(); 281 EnableRecording();
320 DisableReporting(); 282 DisableReporting();
321 } 283 }
322 284
323 void MetricsService::Stop() { 285 void MetricsService::Stop() {
324 HandleIdleSinceLastTransmission(false); 286 HandleIdleSinceLastTransmission(false);
325 DisableReporting(); 287 DisableReporting();
326 DisableRecording(); 288 DisableRecording();
327 } 289 }
328 290
329 void MetricsService::EnableReporting() { 291 void MetricsService::EnableReporting() {
330 if (reporting_active_) 292 if (reporting_service_.reporting_active())
331 return; 293 return;
332 reporting_active_ = true; 294 reporting_service_.EnableReporting();
333 StartSchedulerIfNecessary(); 295 StartSchedulerIfNecessary();
334 } 296 }
335 297
336 void MetricsService::DisableReporting() { 298 void MetricsService::DisableReporting() {
337 reporting_active_ = false; 299 reporting_service_.DisableReporting();
338 } 300 }
339 301
340 std::string MetricsService::GetClientId() { 302 std::string MetricsService::GetClientId() {
341 return state_manager_->client_id(); 303 return state_manager_->client_id();
342 } 304 }
343 305
344 int64_t MetricsService::GetInstallDate() { 306 int64_t MetricsService::GetInstallDate() {
345 return local_state_->GetInt64(prefs::kInstallDate); 307 return local_state_->GetInt64(prefs::kInstallDate);
346 } 308 }
347 309
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 PushPendingLogsToPersistentStorage(); 351 PushPendingLogsToPersistentStorage();
390 } 352 }
391 353
392 bool MetricsService::recording_active() const { 354 bool MetricsService::recording_active() const {
393 DCHECK(thread_checker_.CalledOnValidThread()); 355 DCHECK(thread_checker_.CalledOnValidThread());
394 return recording_state_ == ACTIVE; 356 return recording_state_ == ACTIVE;
395 } 357 }
396 358
397 bool MetricsService::reporting_active() const { 359 bool MetricsService::reporting_active() const {
398 DCHECK(thread_checker_.CalledOnValidThread()); 360 DCHECK(thread_checker_.CalledOnValidThread());
399 return reporting_active_; 361 return reporting_service_.reporting_active();
362 }
363
364 bool MetricsService::has_unsent_logs() const {
365 return reporting_service_.metrics_log_store()->has_unsent_logs();
Alexei Svitkine (slow) 2017/02/28 18:03:45 Nit: can you just use log_store().has_unsent_logs(
Steven Holte 2017/03/01 02:02:33 Not quite. I would need a const version of log_st
400 } 366 }
401 367
402 void MetricsService::RecordDelta(const base::HistogramBase& histogram, 368 void MetricsService::RecordDelta(const base::HistogramBase& histogram,
403 const base::HistogramSamples& snapshot) { 369 const base::HistogramSamples& snapshot) {
404 log_manager_.current_log()->RecordHistogramDelta(histogram.histogram_name(), 370 log_manager_.current_log()->RecordHistogramDelta(histogram.histogram_name(),
405 snapshot); 371 snapshot);
406 } 372 }
407 373
408 void MetricsService::InconsistencyDetected( 374 void MetricsService::InconsistencyDetected(
409 base::HistogramBase::Inconsistency problem) { 375 base::HistogramBase::Inconsistency problem) {
(...skipping 30 matching lines...) Expand all
440 LogCleanShutdown(false); 406 LogCleanShutdown(false);
441 } 407 }
442 408
443 void MetricsService::RecordCompletedSessionEnd() { 409 void MetricsService::RecordCompletedSessionEnd() {
444 LogCleanShutdown(true); 410 LogCleanShutdown(true);
445 } 411 }
446 412
447 #if defined(OS_ANDROID) || defined(OS_IOS) 413 #if defined(OS_ANDROID) || defined(OS_IOS)
448 void MetricsService::OnAppEnterBackground() { 414 void MetricsService::OnAppEnterBackground() {
449 rotation_scheduler_->Stop(); 415 rotation_scheduler_->Stop();
450 upload_scheduler_->Stop(); 416 reporting_service_.Stop();
451 417
452 MarkAppCleanShutdownAndCommit(&clean_exit_beacon_, local_state_); 418 MarkAppCleanShutdownAndCommit(&clean_exit_beacon_, local_state_);
453 419
454 // Give providers a chance to persist histograms as part of being 420 // Give providers a chance to persist histograms as part of being
455 // backgrounded. 421 // backgrounded.
456 for (auto& provider : metrics_providers_) 422 for (auto& provider : metrics_providers_)
457 provider->OnAppEnterBackground(); 423 provider->OnAppEnterBackground();
458 424
459 // At this point, there's no way of knowing when the process will be 425 // At this point, there's no way of knowing when the process will be
460 // killed, so this has to be treated similar to a shutdown, closing and 426 // killed, so this has to be treated similar to a shutdown, closing and
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 StabilityMetricsProvider(local_state_) 462 StabilityMetricsProvider(local_state_)
497 .RecordBreakpadHasDebugger(has_debugger); 463 .RecordBreakpadHasDebugger(has_debugger);
498 } 464 }
499 465
500 void MetricsService::ClearSavedStabilityMetrics() { 466 void MetricsService::ClearSavedStabilityMetrics() {
501 for (auto& provider : metrics_providers_) 467 for (auto& provider : metrics_providers_)
502 provider->ClearSavedStabilityMetrics(); 468 provider->ClearSavedStabilityMetrics();
503 } 469 }
504 470
505 void MetricsService::PushExternalLog(const std::string& log) { 471 void MetricsService::PushExternalLog(const std::string& log) {
506 log_store_.StoreLog(log, MetricsLog::ONGOING_LOG); 472 log_store()->StoreLog(log, MetricsLog::ONGOING_LOG);
507 } 473 }
508 474
509 void MetricsService::UpdateMetricsUsagePrefs(const std::string& service_name, 475 void MetricsService::UpdateMetricsUsagePrefs(const std::string& service_name,
510 int message_size, 476 int message_size,
511 bool is_cellular) { 477 bool is_cellular) {
512 DCHECK(thread_checker_.CalledOnValidThread()); 478 DCHECK(thread_checker_.CalledOnValidThread());
513 if (data_use_tracker_) { 479 reporting_service_.UpdateMetricsUsagePrefs(service_name, message_size,
514 data_use_tracker_->UpdateMetricsUsagePrefs(service_name, 480 is_cellular);
515 message_size,
516 is_cellular);
517 }
518 } 481 }
519 482
520 //------------------------------------------------------------------------------ 483 //------------------------------------------------------------------------------
521 // private methods 484 // private methods
522 //------------------------------------------------------------------------------ 485 //------------------------------------------------------------------------------
523 486
524 487
525 //------------------------------------------------------------------------------ 488 //------------------------------------------------------------------------------
526 // Initialization methods 489 // Initialization methods
527 490
528 void MetricsService::InitializeMetricsState() { 491 void MetricsService::InitializeMetricsState() {
529 const int64_t buildtime = MetricsLog::GetBuildTime(); 492 const int64_t buildtime = MetricsLog::GetBuildTime();
530 const std::string version = client_->GetVersionString(); 493 const std::string version = client_->GetVersionString();
531 494
532 bool version_changed = false; 495 bool version_changed = false;
533 EnvironmentRecorder recorder(local_state_); 496 EnvironmentRecorder recorder(local_state_);
534 int64_t previous_buildtime = recorder.GetLastBuildtime(); 497 int64_t previous_buildtime = recorder.GetLastBuildtime();
535 std::string previous_version = recorder.GetLastVersion(); 498 std::string previous_version = recorder.GetLastVersion();
536 if (previous_buildtime != buildtime || previous_version != version) { 499 if (previous_buildtime != buildtime || previous_version != version) {
537 recorder.SetBuildtimeAndVersion(buildtime, version); 500 recorder.SetBuildtimeAndVersion(buildtime, version);
538 version_changed = true; 501 version_changed = true;
539 } 502 }
540 503
541 log_store_.LoadPersistedUnsentLogs(); 504 reporting_service_.Initialize();
542 505
543 session_id_ = local_state_->GetInteger(prefs::kMetricsSessionID); 506 session_id_ = local_state_->GetInteger(prefs::kMetricsSessionID);
544 507
545 StabilityMetricsProvider provider(local_state_); 508 StabilityMetricsProvider provider(local_state_);
546 if (!clean_exit_beacon_.exited_cleanly()) { 509 if (!clean_exit_beacon_.exited_cleanly()) {
547 provider.LogCrash(); 510 provider.LogCrash();
548 // Reset flag, and wait until we call LogNeedForCleanShutdown() before 511 // Reset flag, and wait until we call LogNeedForCleanShutdown() before
549 // monitoring. 512 // monitoring.
550 clean_exit_beacon_.WriteBeaconValue(true); 513 clean_exit_beacon_.WriteBeaconValue(true);
551 ExecutionPhaseManager manager(local_state_); 514 ExecutionPhaseManager manager(local_state_);
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 RecordCurrentEnvironment(current_log); 677 RecordCurrentEnvironment(current_log);
715 base::TimeDelta incremental_uptime; 678 base::TimeDelta incremental_uptime;
716 base::TimeDelta uptime; 679 base::TimeDelta uptime;
717 GetUptimes(local_state_, &incremental_uptime, &uptime); 680 GetUptimes(local_state_, &incremental_uptime, &uptime);
718 current_log->RecordStabilityMetrics(metrics_providers_, incremental_uptime, 681 current_log->RecordStabilityMetrics(metrics_providers_, incremental_uptime,
719 uptime); 682 uptime);
720 683
721 current_log->RecordGeneralMetrics(metrics_providers_); 684 current_log->RecordGeneralMetrics(metrics_providers_);
722 RecordCurrentHistograms(); 685 RecordCurrentHistograms();
723 DVLOG(1) << "Generated an ongoing log."; 686 DVLOG(1) << "Generated an ongoing log.";
724 log_manager_.FinishCurrentLog(&log_store_); 687 log_manager_.FinishCurrentLog(log_store());
725 } 688 }
726 689
727 void MetricsService::PushPendingLogsToPersistentStorage() { 690 void MetricsService::PushPendingLogsToPersistentStorage() {
728 if (state_ < SENDING_LOGS) 691 if (state_ < SENDING_LOGS)
729 return; // We didn't and still don't have time to get plugin list etc. 692 return; // We didn't and still don't have time to get plugin list etc.
730 693
731 CloseCurrentLog(); 694 CloseCurrentLog();
732 log_store_.PersistUnsentLogs(); 695 log_store()->PersistUnsentLogs();
733 } 696 }
734 697
735 //------------------------------------------------------------------------------ 698 //------------------------------------------------------------------------------
736 // Transmission of logs methods 699 // Transmission of logs methods
737 700
738 void MetricsService::StartSchedulerIfNecessary() { 701 void MetricsService::StartSchedulerIfNecessary() {
739 // Never schedule cutting or uploading of logs in test mode. 702 // Never schedule cutting or uploading of logs in test mode.
740 if (test_mode_active_) 703 if (test_mode_active_)
741 return; 704 return;
742 705
743 // Even if reporting is disabled, the scheduler is needed to trigger the 706 // Even if reporting is disabled, the scheduler is needed to trigger the
744 // creation of the initial log, which must be done in order for any logs to be 707 // creation of the initial log, which must be done in order for any logs to be
745 // persisted on shutdown or backgrounding. 708 // persisted on shutdown or backgrounding.
746 if (recording_active() && 709 if (recording_active() &&
747 (reporting_active() || state_ < SENDING_LOGS)) { 710 (reporting_active() || state_ < SENDING_LOGS)) {
748 rotation_scheduler_->Start(); 711 rotation_scheduler_->Start();
749 upload_scheduler_->Start(); 712 reporting_service_.Start();
750 } 713 }
751 } 714 }
752 715
753 void MetricsService::StartScheduledUpload() { 716 void MetricsService::StartScheduledUpload() {
754 DVLOG(1) << "StartScheduledUpload"; 717 DVLOG(1) << "StartScheduledUpload";
755 DCHECK(state_ >= INIT_TASK_DONE); 718 DCHECK(state_ >= INIT_TASK_DONE);
756 // If we're getting no notifications, then the log won't have much in it, and 719 // If we're getting no notifications, then the log won't have much in it, and
757 // it's possible the computer is about to go to sleep, so don't upload and 720 // it's possible the computer is about to go to sleep, so don't upload and
758 // stop the scheduler. 721 // stop the scheduler.
759 // If recording has been turned off, the scheduler doesn't need to run. 722 // If recording has been turned off, the scheduler doesn't need to run.
760 // If reporting is off, proceed if the initial log hasn't been created, since 723 // If reporting is off, proceed if the initial log hasn't been created, since
761 // that has to happen in order for logs to be cut and stored when persisting. 724 // that has to happen in order for logs to be cut and stored when persisting.
762 // TODO(stuartmorgan): Call Stop() on the scheduler when reporting and/or 725 // TODO(stuartmorgan): Call Stop() on the scheduler when reporting and/or
763 // recording are turned off instead of letting it fire and then aborting. 726 // recording are turned off instead of letting it fire and then aborting.
764 if (idle_since_last_transmission_ || 727 if (idle_since_last_transmission_ ||
765 !recording_active() || 728 !recording_active() ||
766 (!reporting_active() && state_ >= SENDING_LOGS)) { 729 (!reporting_active() && state_ >= SENDING_LOGS)) {
767 rotation_scheduler_->Stop(); 730 rotation_scheduler_->Stop();
768 rotation_scheduler_->RotationFinished(); 731 rotation_scheduler_->RotationFinished();
769 return; 732 return;
770 } 733 }
771 734
772 // If there are unsent logs, send the next one. If not, start the asynchronous 735 // If there are unsent logs, send the next one. If not, start the asynchronous
773 // process of finalizing the current log for upload. 736 // process of finalizing the current log for upload.
774 if (state_ == SENDING_LOGS && log_store_.has_unsent_logs()) { 737 if (state_ == SENDING_LOGS && has_unsent_logs()) {
775 upload_scheduler_->Start(); 738 reporting_service_.Start();
776 rotation_scheduler_->RotationFinished(); 739 rotation_scheduler_->RotationFinished();
777 } else { 740 } else {
778 // There are no logs left to send, so start creating a new one. 741 // There are no logs left to send, so start creating a new one.
779 client_->CollectFinalMetricsForLog( 742 client_->CollectFinalMetricsForLog(
780 base::Bind(&MetricsService::OnFinalLogInfoCollectionDone, 743 base::Bind(&MetricsService::OnFinalLogInfoCollectionDone,
781 self_ptr_factory_.GetWeakPtr())); 744 self_ptr_factory_.GetWeakPtr()));
782 } 745 }
783 } 746 }
784 747
785 void MetricsService::OnFinalLogInfoCollectionDone() { 748 void MetricsService::OnFinalLogInfoCollectionDone() {
786 DVLOG(1) << "OnFinalLogInfoCollectionDone"; 749 DVLOG(1) << "OnFinalLogInfoCollectionDone";
787 // Abort if metrics were turned off during the final info gathering. 750 // Abort if metrics were turned off during the final info gathering.
788 if (!recording_active()) { 751 if (!recording_active()) {
789 rotation_scheduler_->Stop(); 752 rotation_scheduler_->Stop();
790 rotation_scheduler_->RotationFinished(); 753 rotation_scheduler_->RotationFinished();
791 return; 754 return;
792 } 755 }
793 756
794 if (state_ == INIT_TASK_DONE) { 757 if (state_ == INIT_TASK_DONE) {
795 PrepareInitialMetricsLog(); 758 PrepareInitialMetricsLog();
796 } else { 759 } else {
797 DCHECK_EQ(SENDING_LOGS, state_); 760 DCHECK_EQ(SENDING_LOGS, state_);
798 CloseCurrentLog(); 761 CloseCurrentLog();
799 OpenNewLog(); 762 OpenNewLog();
800 } 763 }
764 reporting_service_.Start();
765 rotation_scheduler_->RotationFinished();
801 HandleIdleSinceLastTransmission(true); 766 HandleIdleSinceLastTransmission(true);
802 upload_scheduler_->Start();
803 rotation_scheduler_->RotationFinished();
804 }
805
806 void MetricsService::SendNextLog() {
807 DVLOG(1) << "SendNextLog";
808 if (!reporting_active()) {
809 upload_scheduler_->StopAndUploadCancelled();
810 return;
811 }
812 if (!log_store_.has_unsent_logs()) {
813 // Should only get here if serializing the log failed somehow.
814 upload_scheduler_->Stop();
815 // Reset backoff interval
816 upload_scheduler_->UploadFinished(true);
817 return;
818 }
819 if (!log_store_.has_staged_log())
820 log_store_.StageNextLog();
821
822 // Proceed to stage the log for upload if log size satisfies cellular log
823 // upload constrains.
824 bool upload_canceled = false;
825 bool is_cellular_logic = client_->IsUMACellularUploadLogicEnabled();
826 if (is_cellular_logic && data_use_tracker_ &&
827 !data_use_tracker_->ShouldUploadLogOnCellular(
828 log_store_.staged_log_hash().size())) {
829 upload_scheduler_->UploadOverDataUsageCap();
830 upload_canceled = true;
831 } else {
832 SendStagedLog();
833 }
834 if (is_cellular_logic) {
835 UMA_HISTOGRAM_BOOLEAN("UMA.LogUpload.Canceled.CellularConstraint",
836 upload_canceled);
837 }
838 } 767 }
839 768
840 bool MetricsService::ProvidersHaveInitialStabilityMetrics() { 769 bool MetricsService::ProvidersHaveInitialStabilityMetrics() {
841 // Check whether any metrics provider has initial stability metrics. 770 // Check whether any metrics provider has initial stability metrics.
842 // All providers are queried (rather than stopping after the first "true" 771 // All providers are queried (rather than stopping after the first "true"
843 // response) in case they do any kind of setup work in preparation for 772 // response) in case they do any kind of setup work in preparation for
844 // the later call to RecordInitialHistogramSnapshots(). 773 // the later call to RecordInitialHistogramSnapshots().
845 bool has_stability_metrics = false; 774 bool has_stability_metrics = false;
846 for (auto& provider : metrics_providers_) 775 for (auto& provider : metrics_providers_)
847 has_stability_metrics |= provider->HasInitialStabilityMetrics(); 776 has_stability_metrics |= provider->HasInitialStabilityMetrics();
(...skipping 24 matching lines...) Expand all
872 // Note: Some stability providers may record stability stats via histograms, 801 // Note: Some stability providers may record stability stats via histograms,
873 // so this call has to be after BeginLoggingWithLog(). 802 // so this call has to be after BeginLoggingWithLog().
874 log_manager_.current_log()->RecordStabilityMetrics( 803 log_manager_.current_log()->RecordStabilityMetrics(
875 metrics_providers_, base::TimeDelta(), base::TimeDelta()); 804 metrics_providers_, base::TimeDelta(), base::TimeDelta());
876 RecordCurrentStabilityHistograms(); 805 RecordCurrentStabilityHistograms();
877 806
878 // Note: RecordGeneralMetrics() intentionally not called since this log is for 807 // Note: RecordGeneralMetrics() intentionally not called since this log is for
879 // stability stats from a previous session only. 808 // stability stats from a previous session only.
880 809
881 DVLOG(1) << "Generated an stability log."; 810 DVLOG(1) << "Generated an stability log.";
882 log_manager_.FinishCurrentLog(&log_store_); 811 log_manager_.FinishCurrentLog(log_store());
883 log_manager_.ResumePausedLog(); 812 log_manager_.ResumePausedLog();
884 813
885 // Store unsent logs, including the stability log that was just saved, so 814 // Store unsent logs, including the stability log that was just saved, so
886 // that they're not lost in case of a crash before upload time. 815 // that they're not lost in case of a crash before upload time.
887 log_store_.PersistUnsentLogs(); 816 log_store()->PersistUnsentLogs();
888 817
889 return true; 818 return true;
890 } 819 }
891 820
892 void MetricsService::PrepareInitialMetricsLog() { 821 void MetricsService::PrepareInitialMetricsLog() {
893 DCHECK_EQ(INIT_TASK_DONE, state_); 822 DCHECK_EQ(INIT_TASK_DONE, state_);
894 823
895 RecordCurrentEnvironment(initial_metrics_log_.get()); 824 RecordCurrentEnvironment(initial_metrics_log_.get());
896 base::TimeDelta incremental_uptime; 825 base::TimeDelta incremental_uptime;
897 base::TimeDelta uptime; 826 base::TimeDelta uptime;
898 GetUptimes(local_state_, &incremental_uptime, &uptime); 827 GetUptimes(local_state_, &incremental_uptime, &uptime);
899 828
900 // Histograms only get written to the current log, so make the new log current 829 // Histograms only get written to the current log, so make the new log current
901 // before writing them. 830 // before writing them.
902 log_manager_.PauseCurrentLog(); 831 log_manager_.PauseCurrentLog();
903 log_manager_.BeginLoggingWithLog(std::move(initial_metrics_log_)); 832 log_manager_.BeginLoggingWithLog(std::move(initial_metrics_log_));
904 833
905 // Note: Some stability providers may record stability stats via histograms, 834 // Note: Some stability providers may record stability stats via histograms,
906 // so this call has to be after BeginLoggingWithLog(). 835 // so this call has to be after BeginLoggingWithLog().
907 MetricsLog* current_log = log_manager_.current_log(); 836 MetricsLog* current_log = log_manager_.current_log();
908 current_log->RecordStabilityMetrics(metrics_providers_, base::TimeDelta(), 837 current_log->RecordStabilityMetrics(metrics_providers_, base::TimeDelta(),
909 base::TimeDelta()); 838 base::TimeDelta());
910 current_log->RecordGeneralMetrics(metrics_providers_); 839 current_log->RecordGeneralMetrics(metrics_providers_);
911 RecordCurrentHistograms(); 840 RecordCurrentHistograms();
912 841
913 DVLOG(1) << "Generated an initial log."; 842 DVLOG(1) << "Generated an initial log.";
914 log_manager_.FinishCurrentLog(&log_store_); 843 log_manager_.FinishCurrentLog(log_store());
915 log_manager_.ResumePausedLog(); 844 log_manager_.ResumePausedLog();
916 845
917 // Store unsent logs, including the initial log that was just saved, so 846 // Store unsent logs, including the initial log that was just saved, so
918 // that they're not lost in case of a crash before upload time. 847 // that they're not lost in case of a crash before upload time.
919 log_store_.PersistUnsentLogs(); 848 log_store()->PersistUnsentLogs();
920 849
921 state_ = SENDING_LOGS; 850 state_ = SENDING_LOGS;
922 } 851 }
923 852
924 void MetricsService::SendStagedLog() {
925 DCHECK(log_store_.has_staged_log());
926 if (!log_store_.has_staged_log())
927 return;
928
929 DCHECK(!log_upload_in_progress_);
930 log_upload_in_progress_ = true;
931
932 if (!log_uploader_) {
933 log_uploader_ = client_->CreateUploader(
934 client_->GetMetricsServerUrl(), metrics::kDefaultMetricsMimeType,
935 metrics::MetricsLogUploader::UMA,
936 base::Bind(&MetricsService::OnLogUploadComplete,
937 self_ptr_factory_.GetWeakPtr()));
938 }
939 const std::string hash = base::HexEncode(log_store_.staged_log_hash().data(),
940 log_store_.staged_log_hash().size());
941 log_uploader_->UploadLog(log_store_.staged_log(), hash);
942 }
943
944
945 void MetricsService::OnLogUploadComplete(int response_code) {
946 DVLOG(1) << "OnLogUploadComplete:" << response_code;
947 DCHECK(log_upload_in_progress_);
948 log_upload_in_progress_ = false;
949
950 // Log a histogram to track response success vs. failure rates.
951 UMA_HISTOGRAM_ENUMERATION("UMA.UploadResponseStatus.Protobuf",
952 ResponseCodeToStatus(response_code),
953 NUM_RESPONSE_STATUSES);
954
955 bool upload_succeeded = response_code == 200;
956
957 // Provide boolean for error recovery (allow us to ignore response_code).
958 bool discard_log = false;
959 const size_t log_size = log_store_.staged_log().length();
960 if (upload_succeeded) {
961 UMA_HISTOGRAM_COUNTS_10000("UMA.LogSize.OnSuccess", log_size / 1024);
962 } else if (log_size > kUploadLogAvoidRetransmitSize) {
963 UMA_HISTOGRAM_COUNTS("UMA.Large Rejected Log was Discarded",
964 static_cast<int>(log_size));
965 discard_log = true;
966 } else if (response_code == 400) {
967 // Bad syntax. Retransmission won't work.
968 discard_log = true;
969 }
970
971 if (upload_succeeded || discard_log) {
972 log_store_.DiscardStagedLog();
973 // Store the updated list to disk now that the removed log is uploaded.
974 log_store_.PersistUnsentLogs();
975 }
976
977 // Error 400 indicates a problem with the log, not with the server, so
978 // don't consider that a sign that the server is in trouble.
979 bool server_is_healthy = upload_succeeded || response_code == 400;
980 if (!log_store_.has_unsent_logs()) {
981 DVLOG(1) << "Stopping upload_scheduler_";
982 upload_scheduler_->Stop();
983 }
984 upload_scheduler_->UploadFinished(server_is_healthy);
985 }
986
987 void MetricsService::IncrementLongPrefsValue(const char* path) { 853 void MetricsService::IncrementLongPrefsValue(const char* path) {
988 int64_t value = local_state_->GetInt64(path); 854 int64_t value = local_state_->GetInt64(path);
989 local_state_->SetInt64(path, value + 1); 855 local_state_->SetInt64(path, value + 1);
990 } 856 }
991 857
992 bool MetricsService::UmaMetricsProperlyShutdown() { 858 bool MetricsService::UmaMetricsProperlyShutdown() {
993 CHECK(clean_shutdown_status_ == CLEANLY_SHUTDOWN || 859 CHECK(clean_shutdown_status_ == CLEANLY_SHUTDOWN ||
994 clean_shutdown_status_ == NEED_TO_SHUTDOWN); 860 clean_shutdown_status_ == NEED_TO_SHUTDOWN);
995 return clean_shutdown_status_ == CLEANLY_SHUTDOWN; 861 return clean_shutdown_status_ == CLEANLY_SHUTDOWN;
996 } 862 }
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 // Redundant setting to assure that we always reset this value at shutdown 998 // Redundant setting to assure that we always reset this value at shutdown
1133 // (and that we don't use some alternate path, and not call LogCleanShutdown). 999 // (and that we don't use some alternate path, and not call LogCleanShutdown).
1134 clean_shutdown_status_ = CLEANLY_SHUTDOWN; 1000 clean_shutdown_status_ = CLEANLY_SHUTDOWN;
1135 client_->OnLogCleanShutdown(); 1001 client_->OnLogCleanShutdown();
1136 clean_exit_beacon_.WriteBeaconValue(true); 1002 clean_exit_beacon_.WriteBeaconValue(true);
1137 SetExecutionPhase(ExecutionPhase::SHUTDOWN_COMPLETE, local_state_); 1003 SetExecutionPhase(ExecutionPhase::SHUTDOWN_COMPLETE, local_state_);
1138 StabilityMetricsProvider(local_state_).MarkSessionEndCompleted(end_completed); 1004 StabilityMetricsProvider(local_state_).MarkSessionEndCompleted(end_completed);
1139 } 1005 }
1140 1006
1141 } // namespace metrics 1007 } // namespace metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698