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

Side by Side Diff: components/metrics/reporting_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
(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 base::Closure send_next_log_callback = base::Bind(
47 &ReportingService::SendNextLog, self_ptr_factory_.GetWeakPtr());
48 upload_scheduler_.reset(new MetricsUploadScheduler(send_next_log_callback));
49 }
50
51 void ReportingService::Start() {
52 if (reporting_active_)
53 upload_scheduler_->Start();
54 }
55
56 void ReportingService::Stop() {
57 if (upload_scheduler_)
58 upload_scheduler_->Stop();
59 }
60
61 void ReportingService::EnableReporting() {
62 if (reporting_active_)
63 return;
64 reporting_active_ = true;
65 Start();
66 }
67
68 void ReportingService::DisableReporting() {
69 reporting_active_ = false;
70 Stop();
71 }
72
73 bool ReportingService::reporting_active() const {
74 DCHECK(thread_checker_.CalledOnValidThread());
75 return reporting_active_;
76 }
77
78 void ReportingService::UpdateMetricsUsagePrefs(const std::string& service_name,
79 int message_size,
80 bool is_cellular) {
81 DCHECK(thread_checker_.CalledOnValidThread());
82 if (data_use_tracker_) {
83 data_use_tracker_->UpdateMetricsUsagePrefs(service_name, message_size,
84 is_cellular);
85 }
86 }
87
88 //------------------------------------------------------------------------------
89 // private methods
90 //------------------------------------------------------------------------------
91
92 void ReportingService::SendNextLog() {
93 DVLOG(1) << "SendNextLog";
94 DCHECK(thread_checker_.CalledOnValidThread());
95 if (!last_upload_finish_time_.is_null()) {
96 LogActualUploadInterval(base::TimeTicks::Now() - last_upload_finish_time_);
97 last_upload_finish_time_ = base::TimeTicks();
98 }
99 if (!reporting_active()) {
100 upload_scheduler_->StopAndUploadCancelled();
101 return;
102 }
103 if (!log_store()->has_unsent_logs()) {
104 // Should only get here if serializing the log failed somehow.
105 upload_scheduler_->Stop();
106 // Reset backoff interval
107 upload_scheduler_->UploadFinished(true);
108 return;
109 }
110 if (!log_store()->has_staged_log())
111 log_store()->StageNextLog();
112
113 // Proceed to stage the log for upload if log size satisfies cellular log
114 // upload constrains.
115 bool upload_canceled = false;
116 bool is_cellular_logic = client_->IsUMACellularUploadLogicEnabled();
117 if (is_cellular_logic && data_use_tracker_ &&
118 !data_use_tracker_->ShouldUploadLogOnCellular(
119 log_store()->staged_log_hash().size())) {
120 upload_scheduler_->UploadOverDataUsageCap();
121 upload_canceled = true;
122 } else {
123 SendStagedLog();
124 }
125 if (is_cellular_logic) {
126 LogCellularConstraint(upload_canceled);
127 }
128 }
129
130 void ReportingService::SendStagedLog() {
131 DCHECK(thread_checker_.CalledOnValidThread());
132 DCHECK(log_store()->has_staged_log());
133 if (!log_store()->has_staged_log())
134 return;
135
136 DCHECK(!log_upload_in_progress_);
137 log_upload_in_progress_ = true;
138
139 if (!log_uploader_) {
140 log_uploader_ = client_->CreateUploader(
141 upload_url(), upload_mime_type(), service_type(),
142 base::Bind(&ReportingService::OnLogUploadComplete,
143 self_ptr_factory_.GetWeakPtr()));
144 }
145
146 const std::string hash =
147 base::HexEncode(log_store()->staged_log_hash().data(),
148 log_store()->staged_log_hash().size());
149 log_uploader_->UploadLog(log_store()->staged_log(), hash);
150 }
151
152 void ReportingService::OnLogUploadComplete(int response_code) {
153 DVLOG(1) << "OnLogUploadComplete:" << response_code;
154 DCHECK(thread_checker_.CalledOnValidThread());
155 DCHECK(log_upload_in_progress_);
156 log_upload_in_progress_ = false;
157
158 // Log a histogram to track response success vs. failure rates.
159 LogResponseCode(response_code);
160
161 bool upload_succeeded = response_code == 200;
162
163 // Provide boolean for error recovery (allow us to ignore response_code).
164 bool discard_log = false;
165 const size_t log_size = log_store()->staged_log().length();
166 if (upload_succeeded) {
167 LogSuccess(log_size);
168 } else if (log_size > max_retransmit_size_) {
169 LogLargeRejection(log_size);
170 discard_log = true;
171 } else if (response_code == 400) {
172 // Bad syntax. Retransmission won't work.
173 discard_log = true;
174 }
175
176 if (upload_succeeded || discard_log) {
177 log_store()->DiscardStagedLog();
178 // Store the updated list to disk now that the removed log is uploaded.
179 log_store()->PersistUnsentLogs();
180 }
181
182 // Error 400 indicates a problem with the log, not with the server, so
183 // don't consider that a sign that the server is in trouble.
184 bool server_is_healthy = upload_succeeded || response_code == 400;
185 if (!log_store()->has_unsent_logs()) {
186 DVLOG(1) << "Stopping upload_scheduler_.";
187 upload_scheduler_->Stop();
188 }
189 upload_scheduler_->UploadFinished(server_is_healthy);
190 }
191
192 } // namespace metrics
OLDNEW
« components/metrics/reporting_service.h ('K') | « components/metrics/reporting_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698