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

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

Issue 2608833002: Move logic for uploading logs into a ReportingService object. (Closed)
Patch Set: Rebase again 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
« no previous file with comments | « components/metrics/reporting_service.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // ReportingService handles uploading serialized logs to a server.
6
7 #include "components/metrics/reporting_service.h"
8
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/memory/ptr_util.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "components/metrics/data_use_tracker.h"
14 #include "components/metrics/log_store.h"
15 #include "components/metrics/metrics_log_uploader.h"
16 #include "components/metrics/metrics_service_client.h"
17 #include "components/metrics/metrics_upload_scheduler.h"
18
19 namespace metrics {
20
21 // static
22 void ReportingService::RegisterPrefs(PrefRegistrySimple* registry) {
23 DataUseTracker::RegisterPrefs(registry);
24 }
25
26 ReportingService::ReportingService(MetricsServiceClient* client,
27 PrefService* local_state,
28 size_t max_retransmit_size)
29 : client_(client),
30 max_retransmit_size_(max_retransmit_size),
31 reporting_active_(false),
32 log_upload_in_progress_(false),
33 data_use_tracker_(DataUseTracker::Create(local_state)),
34 self_ptr_factory_(this) {
35 DCHECK(thread_checker_.CalledOnValidThread());
36 DCHECK(client_);
37 DCHECK(local_state);
38 }
39
40 ReportingService::~ReportingService() {
41 DisableReporting();
42 }
43
44 void ReportingService::Initialize() {
45 DCHECK(thread_checker_.CalledOnValidThread());
46 log_store()->LoadPersistedUnsentLogs();
47 base::Closure send_next_log_callback = base::Bind(
48 &ReportingService::SendNextLog, self_ptr_factory_.GetWeakPtr());
49 upload_scheduler_.reset(new MetricsUploadScheduler(send_next_log_callback));
50 }
51
52 void ReportingService::Start() {
53 DCHECK(thread_checker_.CalledOnValidThread());
54 if (reporting_active_)
55 upload_scheduler_->Start();
56 }
57
58 void ReportingService::Stop() {
59 DCHECK(thread_checker_.CalledOnValidThread());
60 if (upload_scheduler_)
61 upload_scheduler_->Stop();
62 }
63
64 void ReportingService::EnableReporting() {
65 DCHECK(thread_checker_.CalledOnValidThread());
66 if (reporting_active_)
67 return;
68 reporting_active_ = true;
69 Start();
70 }
71
72 void ReportingService::DisableReporting() {
73 DCHECK(thread_checker_.CalledOnValidThread());
74 reporting_active_ = false;
75 Stop();
76 }
77
78 bool ReportingService::reporting_active() const {
79 DCHECK(thread_checker_.CalledOnValidThread());
80 return reporting_active_;
81 }
82
83 void ReportingService::UpdateMetricsUsagePrefs(const std::string& service_name,
84 int message_size,
85 bool is_cellular) {
86 DCHECK(thread_checker_.CalledOnValidThread());
87 if (data_use_tracker_) {
88 data_use_tracker_->UpdateMetricsUsagePrefs(service_name, message_size,
89 is_cellular);
90 }
91 }
92
93 //------------------------------------------------------------------------------
94 // private methods
95 //------------------------------------------------------------------------------
96
97 void ReportingService::SendNextLog() {
98 DVLOG(1) << "SendNextLog";
99 DCHECK(thread_checker_.CalledOnValidThread());
100 if (!last_upload_finish_time_.is_null()) {
101 LogActualUploadInterval(base::TimeTicks::Now() - last_upload_finish_time_);
102 last_upload_finish_time_ = base::TimeTicks();
103 }
104 if (!reporting_active()) {
105 upload_scheduler_->StopAndUploadCancelled();
106 return;
107 }
108 if (!log_store()->has_unsent_logs()) {
109 // Should only get here if serializing the log failed somehow.
110 upload_scheduler_->Stop();
111 // Reset backoff interval
112 upload_scheduler_->UploadFinished(true);
113 return;
114 }
115 if (!log_store()->has_staged_log())
116 log_store()->StageNextLog();
117
118 // Proceed to stage the log for upload if log size satisfies cellular log
119 // upload constrains.
120 bool upload_canceled = false;
121 bool is_cellular_logic = client_->IsUMACellularUploadLogicEnabled();
122 if (is_cellular_logic && data_use_tracker_ &&
123 !data_use_tracker_->ShouldUploadLogOnCellular(
124 log_store()->staged_log_hash().size())) {
125 upload_scheduler_->UploadOverDataUsageCap();
126 upload_canceled = true;
127 } else {
128 SendStagedLog();
129 }
130 if (is_cellular_logic) {
131 LogCellularConstraint(upload_canceled);
132 }
133 }
134
135 void ReportingService::SendStagedLog() {
136 DCHECK(thread_checker_.CalledOnValidThread());
137 DCHECK(log_store()->has_staged_log());
138 if (!log_store()->has_staged_log())
139 return;
140
141 DCHECK(!log_upload_in_progress_);
142 log_upload_in_progress_ = true;
143
144 if (!log_uploader_) {
145 log_uploader_ = client_->CreateUploader(
146 GetUploadUrl(), upload_mime_type(), service_type(),
147 base::Bind(&ReportingService::OnLogUploadComplete,
148 self_ptr_factory_.GetWeakPtr()));
149 }
150
151 const std::string hash =
152 base::HexEncode(log_store()->staged_log_hash().data(),
153 log_store()->staged_log_hash().size());
154 log_uploader_->UploadLog(log_store()->staged_log(), hash);
155 }
156
157 void ReportingService::OnLogUploadComplete(int response_code) {
158 DVLOG(1) << "OnLogUploadComplete:" << response_code;
159 DCHECK(thread_checker_.CalledOnValidThread());
160 DCHECK(log_upload_in_progress_);
161 log_upload_in_progress_ = false;
162
163 // Log a histogram to track response success vs. failure rates.
164 LogResponseCode(response_code);
165
166 bool upload_succeeded = response_code == 200;
167
168 // Provide boolean for error recovery (allow us to ignore response_code).
169 bool discard_log = false;
170 const size_t log_size = log_store()->staged_log().length();
171 if (upload_succeeded) {
172 LogSuccess(log_size);
173 } else if (log_size > max_retransmit_size_) {
174 LogLargeRejection(log_size);
175 discard_log = true;
176 } else if (response_code == 400) {
177 // Bad syntax. Retransmission won't work.
178 discard_log = true;
179 }
180
181 if (upload_succeeded || discard_log) {
182 log_store()->DiscardStagedLog();
183 // Store the updated list to disk now that the removed log is uploaded.
184 log_store()->PersistUnsentLogs();
185 }
186
187 // Error 400 indicates a problem with the log, not with the server, so
188 // don't consider that a sign that the server is in trouble.
189 bool server_is_healthy = upload_succeeded || response_code == 400;
190 if (!log_store()->has_unsent_logs()) {
191 DVLOG(1) << "Stopping upload_scheduler_.";
192 upload_scheduler_->Stop();
193 }
194 upload_scheduler_->UploadFinished(server_is_healthy);
195 }
196
197 } // namespace metrics
OLDNEW
« no previous file with comments | « components/metrics/reporting_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698