Chromium Code Reviews| 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_reporting_scheduler.h" | 5 #include "components/metrics/metrics_reporting_scheduler.h" |
| 6 | 6 |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "base/metrics/field_trial.h" | |
| 9 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
| 10 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 11 #include "components/variations/variations_associated_data.h" | 10 #include "components/variations/variations_associated_data.h" |
| 12 | 11 |
| 13 using base::TimeDelta; | 12 using base::TimeDelta; |
| 14 | 13 |
| 15 namespace metrics { | 14 namespace metrics { |
| 16 | 15 |
| 17 namespace { | 16 namespace { |
| 18 | 17 |
| 19 // The delay, in seconds, after startup before sending the first log message. | 18 // The delay, in seconds, after startup before sending the first log message. |
| 20 #if defined(OS_ANDROID) || defined(OS_IOS) | 19 #if defined(OS_ANDROID) || defined(OS_IOS) |
| 21 // Sessions are more likely to be short on a mobile device, so handle the | 20 // Sessions are more likely to be short on a mobile device, so handle the |
| 22 // initial log quickly. | 21 // initial log quickly. |
| 23 const int kInitialUploadIntervalSeconds = 15; | 22 const int kInitialUploadIntervalSeconds = 15; |
| 24 #else | 23 #else |
| 25 const int kInitialUploadIntervalSeconds = 60; | 24 const int kInitialUploadIntervalSeconds = 60; |
| 26 #endif | 25 #endif |
| 27 | 26 |
| 28 // The delay, in seconds, between uploading when there are queued logs from | 27 // The delay, in seconds, between uploading when there are queued logs from |
| 29 // previous sessions to send. | 28 // previous sessions to send. |
| 30 #if defined(OS_ANDROID) || defined(OS_IOS) | 29 #if defined(OS_ANDROID) || defined(OS_IOS) |
| 31 // Sending in a burst is better on a mobile device, since keeping the radio on | 30 // Sending in a burst is better on a mobile device, since keeping the radio on |
| 32 // is very expensive. | 31 // is very expensive. |
| 33 const int kUnsentLogsIntervalSeconds = 3; | 32 const int kUnsentLogsIntervalSeconds = 3; |
| 34 #else | 33 #else |
| 35 const int kUnsentLogsIntervalSeconds = 15; | 34 const int kUnsentLogsIntervalSeconds = 15; |
| 36 #endif | 35 #endif |
| 37 | 36 |
| 38 // Standard interval between log uploads, in seconds. | |
| 39 #if defined(OS_ANDROID) || defined(OS_IOS) | |
| 40 const int kStandardUploadIntervalSeconds = 5 * 60; // Five minutes. | |
| 41 const int kStandardUploadIntervalCellularSeconds = 15 * 60; // Fifteen minutes. | |
| 42 #else | |
| 43 const int kStandardUploadIntervalSeconds = 30 * 60; // Thirty minutes. | |
| 44 #endif | |
| 45 | |
| 46 // When uploading metrics to the server fails, we progressively wait longer and | 37 // When uploading metrics to the server fails, we progressively wait longer and |
| 47 // longer before sending the next log. This backoff process helps reduce load | 38 // longer before sending the next log. This backoff process helps reduce load |
| 48 // on a server that is having issues. | 39 // on a server that is having issues. |
| 49 // The following is the multiplier we use to expand that inter-log duration. | 40 // The following is the multiplier we use to expand that inter-log duration. |
| 50 const double kBackoffMultiplier = 1.1; | 41 const double kBackoffMultiplier = 1.1; |
| 51 | 42 |
| 52 // The maximum backoff multiplier. | 43 // The maximum backoff multiplier. |
| 53 const int kMaxBackoffMultiplier = 10; | 44 const int kMaxBackoffMultiplier = 10; |
| 54 | 45 |
| 55 enum InitSequence { | 46 enum InitSequence { |
| 56 TIMER_FIRED_FIRST, | 47 TIMER_FIRED_FIRST, |
| 57 INIT_TASK_COMPLETED_FIRST, | 48 INIT_TASK_COMPLETED_FIRST, |
| 58 INIT_SEQUENCE_ENUM_SIZE, | 49 INIT_SEQUENCE_ENUM_SIZE, |
| 59 }; | 50 }; |
| 60 | 51 |
| 61 void LogMetricsInitSequence(InitSequence sequence) { | 52 void LogMetricsInitSequence(InitSequence sequence) { |
| 62 UMA_HISTOGRAM_ENUMERATION("UMA.InitSequence", sequence, | 53 UMA_HISTOGRAM_ENUMERATION("UMA.InitSequence", sequence, |
| 63 INIT_SEQUENCE_ENUM_SIZE); | 54 INIT_SEQUENCE_ENUM_SIZE); |
| 64 } | 55 } |
| 65 | 56 |
| 66 void LogActualUploadInterval(TimeDelta interval) { | 57 void LogActualUploadInterval(TimeDelta interval) { |
| 67 UMA_HISTOGRAM_CUSTOM_COUNTS("UMA.ActualLogUploadInterval", | 58 UMA_HISTOGRAM_CUSTOM_COUNTS("UMA.ActualLogUploadInterval", |
| 68 interval.InMinutes(), | 59 interval.InMinutes(), |
| 69 1, | 60 1, |
| 70 base::TimeDelta::FromHours(12).InMinutes(), | 61 base::TimeDelta::FromHours(12).InMinutes(), |
| 71 50); | 62 50); |
| 72 } | 63 } |
| 73 | 64 |
| 74 // Returns upload interval specified for the current experiment running. | |
| 75 // TODO(gayane): Only for experimenting with upload interval for Android | |
| 76 // (bug: 17391128). Should be removed once the experiments are done. | |
| 77 base::TimeDelta GetUploadIntervalFromExperiment() { | |
| 78 std::string interval_str = variations::GetVariationParamValue( | |
| 79 "UMALogUploadInterval", "interval"); | |
| 80 int interval; | |
| 81 if (interval_str.empty() || !base::StringToInt(interval_str, &interval)) | |
| 82 return TimeDelta::FromSeconds(kStandardUploadIntervalSeconds); | |
| 83 | |
| 84 return TimeDelta::FromMinutes(interval); | |
| 85 } | |
| 86 | |
| 87 #if defined(OS_ANDROID) || defined(OS_IOS) | |
| 88 // Returns true if the user is assigned to the experiment group for enabled | |
| 89 // cellular uploads. | |
| 90 bool IsCellularEnabledByExperiment() { | |
| 91 const std::string group_name = | |
| 92 base::FieldTrialList::FindFullName("UMA_EnableCellularLogUpload"); | |
| 93 return group_name == "Enabled"; | |
| 94 } | |
| 95 #endif | |
| 96 | |
| 97 } // anonymous namespace | 65 } // anonymous namespace |
| 98 | 66 |
| 99 MetricsReportingScheduler::MetricsReportingScheduler( | 67 MetricsReportingScheduler::MetricsReportingScheduler( |
| 100 const base::Closure& upload_callback, | 68 const base::Closure& upload_callback, |
| 101 const base::Callback<void(bool*)>& cellular_callback) | 69 const base::Callback<base::TimeDelta(void)>& upload_interval_callback) |
| 102 : upload_callback_(upload_callback), | 70 : upload_callback_(upload_callback), |
| 103 upload_interval_(TimeDelta::FromSeconds(kInitialUploadIntervalSeconds)), | 71 upload_interval_(TimeDelta::FromSeconds(kInitialUploadIntervalSeconds)), |
| 104 running_(false), | 72 running_(false), |
| 105 callback_pending_(false), | 73 callback_pending_(false), |
| 106 init_task_complete_(false), | 74 init_task_complete_(false), |
| 107 waiting_for_init_task_complete_(false), | 75 waiting_for_init_task_complete_(false), |
| 108 cellular_callback_(cellular_callback) { | 76 upload_interval_callback_(upload_interval_callback) { |
| 109 } | 77 } |
| 110 | 78 |
| 111 MetricsReportingScheduler::~MetricsReportingScheduler() {} | 79 MetricsReportingScheduler::~MetricsReportingScheduler() {} |
| 112 | 80 |
| 113 void MetricsReportingScheduler::Start() { | 81 void MetricsReportingScheduler::Start() { |
| 114 GetUploadIntervalFromExperiment(); | 82 GetUploadIntervalFromExperiment(); |
| 115 running_ = true; | 83 running_ = true; |
| 116 ScheduleNextUpload(); | 84 ScheduleNextUpload(); |
| 117 } | 85 } |
| 118 | 86 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 199 static_cast<int64>(kBackoffMultiplier * | 167 static_cast<int64>(kBackoffMultiplier * |
| 200 upload_interval_.InMicroseconds())); | 168 upload_interval_.InMicroseconds())); |
| 201 | 169 |
| 202 TimeDelta max_interval = kMaxBackoffMultiplier * GetStandardUploadInterval(); | 170 TimeDelta max_interval = kMaxBackoffMultiplier * GetStandardUploadInterval(); |
| 203 if (upload_interval_ > max_interval || upload_interval_.InSeconds() < 0) { | 171 if (upload_interval_ > max_interval || upload_interval_.InSeconds() < 0) { |
| 204 upload_interval_ = max_interval; | 172 upload_interval_ = max_interval; |
| 205 } | 173 } |
| 206 } | 174 } |
| 207 | 175 |
| 208 base::TimeDelta MetricsReportingScheduler::GetStandardUploadInterval() { | 176 base::TimeDelta MetricsReportingScheduler::GetStandardUploadInterval() { |
| 209 #if defined(OS_ANDROID) || defined(OS_IOS) | 177 return upload_interval_callback_.Run(); |
| 210 bool is_cellular = false; | 178 } |
| 211 if (!cellular_callback_.is_null()) | |
| 212 cellular_callback_.Run(&is_cellular); | |
| 213 | 179 |
| 214 if (is_cellular && IsCellularEnabledByExperiment()) | 180 base::TimeDelta MetricsReportingScheduler::GetUploadIntervalFromExperiment() { |
|
Alexei Svitkine (slow)
2015/03/09 17:26:17
Hmm, I don't think we need this here anymore. Look
gayane -on leave until 09-2017
2015/03/09 18:18:36
Right, we don't need that anymore. The experiment
Alexei Svitkine (slow)
2015/03/09 18:20:42
Got it - I think given that this CL is already cha
gunsch
2015/03/13 00:48:25
Done.
| |
| 215 return TimeDelta::FromSeconds(kStandardUploadIntervalCellularSeconds); | 181 std::string interval_str = variations::GetVariationParamValue( |
| 216 #endif | 182 "UMALogUploadInterval", "interval"); |
| 217 return TimeDelta::FromSeconds(kStandardUploadIntervalSeconds); | 183 int interval; |
| 184 if (interval_str.empty() || !base::StringToInt(interval_str, &interval)) | |
| 185 return GetStandardUploadInterval(); | |
| 186 | |
| 187 return TimeDelta::FromMinutes(interval); | |
| 218 } | 188 } |
| 219 | 189 |
| 220 } // namespace metrics | 190 } // namespace metrics |
| OLD | NEW |