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 |