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

Side by Side Diff: chrome/browser/metrics/metrics_service.cc

Issue 10546044: [Metrics] Re-try failed protocol buffer uploads as well as failed XML uploads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Revert DiscardStagedLog() visibility change Created 8 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/metrics/metrics_service.h ('k') | chrome/common/metrics/metrics_log_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 10 // A MetricsService instance is typically created at application startup. It
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 232
233 // If an upload fails, and the transmission was over this byte count, then we 233 // If an upload fails, and the transmission was over this byte count, then we
234 // will discard the log, and not try to retransmit it. We also don't persist 234 // will discard the log, and not try to retransmit it. We also don't persist
235 // the log to the prefs for transmission during the next chrome session if this 235 // the log to the prefs for transmission during the next chrome session if this
236 // limit is exceeded. 236 // limit is exceeded.
237 const size_t kUploadLogAvoidRetransmitSize = 50000; 237 const size_t kUploadLogAvoidRetransmitSize = 50000;
238 238
239 // Interval, in minutes, between state saves. 239 // Interval, in minutes, between state saves.
240 const int kSaveStateIntervalMinutes = 5; 240 const int kSaveStateIntervalMinutes = 5;
241 241
242 // Used to indicate that the response code is currently not set at all --
243 // RESPONSE_CODE_INVALID can sometimes be returned in response to a request if,
244 // e.g., the server is down.
245 const int kNoResponseCode = net::URLFetcher::RESPONSE_CODE_INVALID - 1;
246
247 enum ResponseStatus { 242 enum ResponseStatus {
248 UNKNOWN_FAILURE, 243 UNKNOWN_FAILURE,
249 SUCCESS, 244 SUCCESS,
250 BAD_REQUEST, // Invalid syntax or log too large. 245 BAD_REQUEST, // Invalid syntax or log too large.
251 NO_RESPONSE, 246 NO_RESPONSE,
252 NUM_RESPONSE_STATUSES 247 NUM_RESPONSE_STATUSES
253 }; 248 };
254 249
255 ResponseStatus ResponseCodeToStatus(int response_code) { 250 ResponseStatus ResponseCodeToStatus(int response_code) {
256 switch (response_code) { 251 switch (response_code) {
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 } 1005 }
1011 1006
1012 void MetricsService::PushPendingLogsToPersistentStorage() { 1007 void MetricsService::PushPendingLogsToPersistentStorage() {
1013 if (state_ < INITIAL_LOG_READY) 1008 if (state_ < INITIAL_LOG_READY)
1014 return; // We didn't and still don't have time to get plugin list etc. 1009 return; // We didn't and still don't have time to get plugin list etc.
1015 1010
1016 if (log_manager_.has_staged_log()) { 1011 if (log_manager_.has_staged_log()) {
1017 // We may race here, and send second copy of initial log later. 1012 // We may race here, and send second copy of initial log later.
1018 if (state_ == INITIAL_LOG_READY) 1013 if (state_ == INITIAL_LOG_READY)
1019 state_ = SENDING_OLD_LOGS; 1014 state_ = SENDING_OLD_LOGS;
1020 MetricsLogManager::StoreType store_type = current_fetch_xml_.get() ? 1015
1021 MetricsLogManager::PROVISIONAL_STORE : MetricsLogManager::NORMAL_STORE; 1016 MetricsLogManager::StoreType store_type;
1017 if (current_fetch_xml_.get() || current_fetch_proto_.get())
1018 store_type = MetricsLogManager::PROVISIONAL_STORE;
1019 else
1020 store_type = MetricsLogManager::NORMAL_STORE;
1022 log_manager_.StoreStagedLogAsUnsent(store_type); 1021 log_manager_.StoreStagedLogAsUnsent(store_type);
1023 } 1022 }
1024 DCHECK(!log_manager_.has_staged_log()); 1023 DCHECK(!log_manager_.has_staged_log());
1025 StopRecording(); 1024 StopRecording();
1026 StoreUnsentLogs(); 1025 StoreUnsentLogs();
1027 } 1026 }
1028 1027
1029 //------------------------------------------------------------------------------ 1028 //------------------------------------------------------------------------------
1030 // Transmission of logs methods 1029 // Transmission of logs methods
1031 1030
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 // stop the scheduler. 1113 // stop the scheduler.
1115 // Similarly, if logs should no longer be uploaded, stop here. 1114 // Similarly, if logs should no longer be uploaded, stop here.
1116 if (idle_since_last_transmission_ || 1115 if (idle_since_last_transmission_ ||
1117 !recording_active() || !reporting_active()) { 1116 !recording_active() || !reporting_active()) {
1118 scheduler_->Stop(); 1117 scheduler_->Stop();
1119 scheduler_->UploadCancelled(); 1118 scheduler_->UploadCancelled();
1120 return; 1119 return;
1121 } 1120 }
1122 1121
1123 MakeStagedLog(); 1122 MakeStagedLog();
1124
1125 // MakeStagedLog should have prepared log text; if it didn't, skip this
1126 // upload and hope things work out next time.
1127 if (log_manager_.staged_log_text().empty()) {
1128 scheduler_->UploadCancelled();
1129 return;
1130 }
1131
1132 SendStagedLog(); 1123 SendStagedLog();
1133 } 1124 }
1134 1125
1135 void MetricsService::MakeStagedLog() { 1126 void MetricsService::MakeStagedLog() {
1136 if (log_manager_.has_staged_log()) 1127 if (log_manager_.has_staged_log())
1137 return; 1128 return;
1138 1129
1139 switch (state_) { 1130 switch (state_) {
1140 case INITIALIZED: 1131 case INITIALIZED:
1141 case INIT_TASK_SCHEDULED: // We should be further along by now. 1132 case INIT_TASK_SCHEDULED: // We should be further along by now.
1142 DCHECK(false); 1133 NOTREACHED();
1143 return; 1134 return;
1144 1135
1145 case INIT_TASK_DONE: 1136 case INIT_TASK_DONE:
1146 // We need to wait for the initial log to be ready before sending 1137 // We need to wait for the initial log to be ready before sending
1147 // anything, because the server will tell us whether it wants to hear 1138 // anything, because the server will tell us whether it wants to hear
1148 // from us. 1139 // from us.
1149 PrepareInitialLog(); 1140 PrepareInitialLog();
1150 DCHECK_EQ(INIT_TASK_DONE, state_); 1141 DCHECK_EQ(INIT_TASK_DONE, state_);
1151 log_manager_.LoadPersistedUnsentLogs(); 1142 log_manager_.LoadPersistedUnsentLogs();
1152 state_ = INITIAL_LOG_READY; 1143 state_ = INITIAL_LOG_READY;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1200 return; // We never Recalled the prior unsent logs. 1191 return; // We never Recalled the prior unsent logs.
1201 1192
1202 log_manager_.PersistUnsentLogs(); 1193 log_manager_.PersistUnsentLogs();
1203 } 1194 }
1204 1195
1205 void MetricsService::SendStagedLog() { 1196 void MetricsService::SendStagedLog() {
1206 DCHECK(log_manager_.has_staged_log()); 1197 DCHECK(log_manager_.has_staged_log());
1207 1198
1208 PrepareFetchWithStagedLog(); 1199 PrepareFetchWithStagedLog();
1209 1200
1210 if (!current_fetch_xml_.get()) { 1201 if (!current_fetch_xml_.get() && !current_fetch_proto_.get()) {
1211 DCHECK(!current_fetch_proto_.get());
1212 // Compression failed, and log discarded :-/. 1202 // Compression failed, and log discarded :-/.
1203 // Skip this upload and hope things work out next time.
1213 log_manager_.DiscardStagedLog(); 1204 log_manager_.DiscardStagedLog();
1214 scheduler_->UploadCancelled(); 1205 scheduler_->UploadCancelled();
1215 // TODO(jar): If compression failed, we should have created a tiny log and 1206 // TODO(jar): If compression failed, we should have created a tiny log and
1216 // compressed that, so that we can signal that we're losing logs. 1207 // compressed that, so that we can signal that we're losing logs.
1217 return; 1208 return;
1218 } 1209 }
1219 // Currently, the staged log for the protobuf version of the data is discarded
1220 // after we create the URL request, so that there is no chance for
1221 // re-transmission in case the corresponding XML request fails. We will
1222 // handle protobuf failures more carefully once that becomes the main
1223 // pipeline, i.e. once we switch away from the XML pipeline.
1224 DCHECK(current_fetch_proto_.get() || !log_manager_.has_staged_log_proto());
1225 1210
1226 DCHECK(!waiting_for_asynchronous_reporting_step_); 1211 DCHECK(!waiting_for_asynchronous_reporting_step_);
1212 waiting_for_asynchronous_reporting_step_ = true;
1227 1213
1228 waiting_for_asynchronous_reporting_step_ = true; 1214 if (current_fetch_xml_.get())
1229 current_fetch_xml_->Start(); 1215 current_fetch_xml_->Start();
1230 if (current_fetch_proto_.get()) 1216 if (current_fetch_proto_.get())
1231 current_fetch_proto_->Start(); 1217 current_fetch_proto_->Start();
1232 1218
1233 HandleIdleSinceLastTransmission(true); 1219 HandleIdleSinceLastTransmission(true);
1234 } 1220 }
1235 1221
1236 void MetricsService::PrepareFetchWithStagedLog() { 1222 void MetricsService::PrepareFetchWithStagedLog() {
1237 DCHECK(!log_manager_.staged_log_text().empty()); 1223 DCHECK(log_manager_.has_staged_log());
1238 1224
1239 // Prepare the XML version. 1225 // Prepare the XML version.
1240 DCHECK(!current_fetch_xml_.get()); 1226 DCHECK(!current_fetch_xml_.get());
1241 current_fetch_xml_.reset(content::URLFetcher::Create( 1227 if (log_manager_.has_staged_log_xml()) {
1242 GURL(server_url_xml_), net::URLFetcher::POST, this)); 1228 current_fetch_xml_.reset(content::URLFetcher::Create(
1243 current_fetch_xml_->SetRequestContext( 1229 GURL(server_url_xml_), net::URLFetcher::POST, this));
1244 g_browser_process->system_request_context()); 1230 current_fetch_xml_->SetRequestContext(
1245 current_fetch_xml_->SetUploadData(kMimeTypeXml, 1231 g_browser_process->system_request_context());
1246 log_manager_.staged_log_text().xml); 1232 current_fetch_xml_->SetUploadData(kMimeTypeXml,
1247 // We already drop cookies server-side, but we might as well strip them out 1233 log_manager_.staged_log_text().xml);
1248 // client-side as well. 1234 // We already drop cookies server-side, but we might as well strip them out
1249 current_fetch_xml_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | 1235 // client-side as well.
1250 net::LOAD_DO_NOT_SEND_COOKIES); 1236 current_fetch_xml_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
1237 net::LOAD_DO_NOT_SEND_COOKIES);
1238 }
1251 1239
1252 // Prepare the protobuf version. 1240 // Prepare the protobuf version.
1253 DCHECK(!current_fetch_proto_.get()); 1241 DCHECK(!current_fetch_proto_.get());
1254 if (log_manager_.has_staged_log_proto()) { 1242 if (log_manager_.has_staged_log_proto()) {
1255 current_fetch_proto_.reset(content::URLFetcher::Create( 1243 current_fetch_proto_.reset(content::URLFetcher::Create(
1256 GURL(server_url_proto_), net::URLFetcher::POST, this)); 1244 GURL(server_url_proto_), net::URLFetcher::POST, this));
1257 current_fetch_proto_->SetRequestContext( 1245 current_fetch_proto_->SetRequestContext(
1258 g_browser_process->system_request_context()); 1246 g_browser_process->system_request_context());
1259 current_fetch_proto_->SetUploadData(kMimeTypeProto, 1247 current_fetch_proto_->SetUploadData(kMimeTypeProto,
1260 log_manager_.staged_log_text().proto); 1248 log_manager_.staged_log_text().proto);
1261 // We already drop cookies server-side, but we might as well strip them out 1249 // We already drop cookies server-side, but we might as well strip them out
1262 // client-side as well. 1250 // client-side as well.
1263 current_fetch_proto_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | 1251 current_fetch_proto_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
1264 net::LOAD_DO_NOT_SEND_COOKIES); 1252 net::LOAD_DO_NOT_SEND_COOKIES);
1265
1266 // Discard the protobuf version of the staged log, so that we will avoid
1267 // re-uploading it even if we need to re-upload the XML version.
1268 // TODO(isherman): Handle protobuf upload failures more gracefully once we
1269 // transition away from the XML-based pipeline.
1270 log_manager_.DiscardStagedLogProto();
1271 } 1253 }
1272 } 1254 }
1273 1255
1274 static const char* StatusToString(const net::URLRequestStatus& status) { 1256 static const char* StatusToString(const net::URLRequestStatus& status) {
1275 switch (status.status()) { 1257 switch (status.status()) {
1276 case net::URLRequestStatus::SUCCESS: 1258 case net::URLRequestStatus::SUCCESS:
1277 return "SUCCESS"; 1259 return "SUCCESS";
1278 1260
1279 case net::URLRequestStatus::IO_PENDING: 1261 case net::URLRequestStatus::IO_PENDING:
1280 return "IO_PENDING"; 1262 return "IO_PENDING";
1281 1263
1282 case net::URLRequestStatus::HANDLED_EXTERNALLY: 1264 case net::URLRequestStatus::HANDLED_EXTERNALLY:
1283 return "HANDLED_EXTERNALLY"; 1265 return "HANDLED_EXTERNALLY";
1284 1266
1285 case net::URLRequestStatus::CANCELED: 1267 case net::URLRequestStatus::CANCELED:
1286 return "CANCELED"; 1268 return "CANCELED";
1287 1269
1288 case net::URLRequestStatus::FAILED: 1270 case net::URLRequestStatus::FAILED:
1289 return "FAILED"; 1271 return "FAILED";
1290 1272
1291 default: 1273 default:
1292 NOTREACHED(); 1274 NOTREACHED();
1293 return "Unknown"; 1275 return "Unknown";
1294 } 1276 }
1295 } 1277 }
1296 1278
1297 // We need to wait for two responses: the response to the XML upload, and the 1279 // We need to wait for two responses: the response to the XML upload, and the
1298 // response to the protobuf upload. For now, only the XML upload's response 1280 // response to the protobuf upload. In the case that exactly one of the uploads
1299 // affects decisions like whether to retry the upload, whether to abandon the 1281 // fails and needs to be retried, we "zap" the other pipeline's staged log to
1300 // upload because it is too large, etc. However, we still need to wait for the 1282 // avoid incorrectly re-uploading it as well.
1301 // protobuf upload, as we cannot reset |current_fetch_proto_| until we have
1302 // confirmation that the network request was sent; and the easiest way to do
1303 // that is to wait for the response. In case the XML upload's response arrives
1304 // first, we cache that response until the protobuf upload's response also
1305 // arrives.
1306 //
1307 // Note that if the XML upload succeeds but the protobuf upload fails, we will
1308 // not retry the protobuf upload. If the XML upload fails while the protobuf
1309 // upload succeeds, we will still avoid re-uploading the protobuf data because
1310 // we "zap" the data after the first upload attempt. This means that we might
1311 // lose protobuf uploads when XML ones succeed; but we will never duplicate any
1312 // protobuf uploads. Protobuf failures should be rare enough to where this
1313 // should be ok while we have the two pipelines running in parallel.
1314 void MetricsService::OnURLFetchComplete(const net::URLFetcher* source) { 1283 void MetricsService::OnURLFetchComplete(const net::URLFetcher* source) {
1315 DCHECK(waiting_for_asynchronous_reporting_step_); 1284 DCHECK(waiting_for_asynchronous_reporting_step_);
1316 1285
1317 // We're not allowed to re-use the existing |URLFetcher|s, so free them here. 1286 // We're not allowed to re-use the existing |URLFetcher|s, so free them here.
1318 // Note however that |source| is aliased to one of these, so we should be 1287 // Note however that |source| is aliased to one of these, so we should be
1319 // careful not to delete it too early. 1288 // careful not to delete it too early.
1320 scoped_ptr<net::URLFetcher> s; 1289 scoped_ptr<net::URLFetcher> s;
1290 bool is_xml;
1321 if (source == current_fetch_xml_.get()) { 1291 if (source == current_fetch_xml_.get()) {
1322 s.reset(current_fetch_xml_.release()); 1292 s.reset(current_fetch_xml_.release());
1323 1293 is_xml = true;
1324 // Cache the XML responses, in case we still need to wait for the protobuf
1325 // response.
1326 response_code_ = source->GetResponseCode();
1327 response_status_ = StatusToString(source->GetStatus());
1328 source->GetResponseAsString(&response_data_);
1329
1330 // Log a histogram to track response success vs. failure rates.
1331 UMA_HISTOGRAM_ENUMERATION("UMA.UploadResponseStatus.XML",
1332 ResponseCodeToStatus(response_code_),
1333 NUM_RESPONSE_STATUSES);
1334 } else if (source == current_fetch_proto_.get()) { 1294 } else if (source == current_fetch_proto_.get()) {
1335 s.reset(current_fetch_proto_.release()); 1295 s.reset(current_fetch_proto_.release());
1336 1296 is_xml = false;
1337 // Log a histogram to track response success vs. failure rates.
1338 UMA_HISTOGRAM_ENUMERATION("UMA.UploadResponseStatus.Protobuf",
1339 ResponseCodeToStatus(source->GetResponseCode()),
1340 NUM_RESPONSE_STATUSES);
1341 } else { 1297 } else {
1342 NOTREACHED(); 1298 NOTREACHED();
1343 return; 1299 return;
1344 } 1300 }
1345 1301
1302 int response_code = source->GetResponseCode();
1303
1304 // Log a histogram to track response success vs. failure rates.
1305 if (is_xml) {
1306 UMA_HISTOGRAM_ENUMERATION("UMA.UploadResponseStatus.XML",
1307 ResponseCodeToStatus(response_code),
1308 NUM_RESPONSE_STATUSES);
1309 } else {
1310 UMA_HISTOGRAM_ENUMERATION("UMA.UploadResponseStatus.Protobuf",
1311 ResponseCodeToStatus(response_code),
1312 NUM_RESPONSE_STATUSES);
1313 }
1314
1315 // If the upload was provisionally stored, drop it now that the upload is
1316 // known to have gone through.
1317 log_manager_.DiscardLastProvisionalStore();
1318
1319 // Confirm send so that we can move on.
1320 VLOG(1) << "Metrics response code: " << response_code
1321 << " status=" << StatusToString(source->GetStatus()) << " for "
1322 << (is_xml ? "xml" : "protobuf") << " upload.";
1323
1324 bool upload_succeeded = response_code == 200;
1325
1326 // Provide boolean for error recovery (allow us to ignore response_code).
1327 bool discard_log = false;
1328 const size_t log_size = is_xml ?
1329 log_manager_.staged_log_text().xml.length() :
1330 log_manager_.staged_log_text().proto.length();
1331 if (!upload_succeeded && log_size > kUploadLogAvoidRetransmitSize) {
1332 UMA_HISTOGRAM_COUNTS("UMA.Large Rejected Log was Discarded",
1333 static_cast<int>(log_size));
1334 discard_log = true;
1335 } else if (response_code == 400) {
1336 // Bad syntax. Retransmission won't work.
1337 discard_log = true;
1338 }
1339
1340 if (!upload_succeeded && !discard_log) {
1341 LogBadResponseCode(response_code, is_xml);
1342 } else { // Successful receipt (or we are discarding log).
1343 std::string response_data;
1344 source->GetResponseAsString(&response_data);
1345 VLOG(1) << "Metrics response data: " << response_data;
1346
1347 if (is_xml)
1348 log_manager_.DiscardStagedLogXml();
1349 else
1350 log_manager_.DiscardStagedLogProto();
1351 }
1352
1346 // If we're still waiting for one of the responses, keep waiting... 1353 // If we're still waiting for one of the responses, keep waiting...
1347 if (current_fetch_xml_.get() || current_fetch_proto_.get()) 1354 if (current_fetch_xml_.get() || current_fetch_proto_.get())
1348 return; 1355 return;
1349 1356
1350 // We should only be able to reach here once we've received responses to both
1351 // the XML and the protobuf requests. We should always have the response code
1352 // available.
1353 DCHECK_NE(response_code_, kNoResponseCode);
1354 waiting_for_asynchronous_reporting_step_ = false; 1357 waiting_for_asynchronous_reporting_step_ = false;
1355 1358
1356 // If the upload was provisionally stored, drop it now that the upload is 1359 if (!log_manager_.has_staged_log()) {
1357 // known to have gone through.
1358 log_manager_.DiscardLastProvisionalStore();
1359
1360 // Confirm send so that we can move on.
1361 VLOG(1) << "Metrics response code: " << response_code_
1362 << " status=" << response_status_;
1363
1364 bool upload_succeeded = response_code_ == 200;
1365
1366 // Provide boolean for error recovery (allow us to ignore response_code).
1367 bool discard_log = false;
1368
1369 if (!upload_succeeded &&
1370 log_manager_.staged_log_text().xml.length() >
1371 kUploadLogAvoidRetransmitSize) {
1372 UMA_HISTOGRAM_COUNTS(
1373 "UMA.Large Rejected Log was Discarded",
1374 static_cast<int>(log_manager_.staged_log_text().xml.length()));
1375 discard_log = true;
1376 } else if (response_code_ == 400) {
1377 // Bad syntax. Retransmission won't work.
1378 discard_log = true;
1379 }
1380
1381 if (!upload_succeeded && !discard_log) {
1382 VLOG(1) << "Metrics: transmission attempt returned a failure code: "
1383 << response_code_ << ". Verify network connectivity";
1384 LogBadResponseCode();
1385 } else { // Successful receipt (or we are discarding log).
1386 VLOG(1) << "Metrics response data: " << response_data_;
1387 switch (state_) { 1360 switch (state_) {
1388 case INITIAL_LOG_READY: 1361 case INITIAL_LOG_READY:
1389 state_ = SENDING_OLD_LOGS; 1362 state_ = SENDING_OLD_LOGS;
1390 break; 1363 break;
1391 1364
1392 case SENDING_OLD_LOGS: 1365 case SENDING_OLD_LOGS:
1393 // Store the updated list to disk now that the removed log is uploaded. 1366 // Store the updated list to disk now that the removed log is uploaded.
1394 StoreUnsentLogs(); 1367 StoreUnsentLogs();
1395 break; 1368 break;
1396 1369
1397 case SENDING_CURRENT_LOGS: 1370 case SENDING_CURRENT_LOGS:
1398 break; 1371 break;
1399 1372
1400 default: 1373 default:
1401 NOTREACHED(); 1374 NOTREACHED();
1402 break; 1375 break;
1403 } 1376 }
1404 1377
1405 log_manager_.DiscardStagedLog();
1406
1407 if (log_manager_.has_unsent_logs()) 1378 if (log_manager_.has_unsent_logs())
1408 DCHECK_LT(state_, SENDING_CURRENT_LOGS); 1379 DCHECK_LT(state_, SENDING_CURRENT_LOGS);
1409 } 1380 }
1410 1381
1411 // Error 400 indicates a problem with the log, not with the server, so 1382 // Error 400 indicates a problem with the log, not with the server, so
1412 // don't consider that a sign that the server is in trouble. 1383 // don't consider that a sign that the server is in trouble.
1413 bool server_is_healthy = upload_succeeded || response_code_ == 400; 1384 bool server_is_healthy = upload_succeeded || response_code == 400;
1414 1385
1415 scheduler_->UploadFinished(server_is_healthy, 1386 // Note that we are essentially randomly choosing to report either the XML or
1416 log_manager_.has_unsent_logs()); 1387 // the protobuf server's health status, but this is ok: In the case that the
1388 // two statuses are not the same, one of the uploads succeeded but the other
1389 // did not. In this case, we'll re-try only the upload that failed. This first
1390 // re-try might ignore the server's unhealthiness; but the response to the
1391 // re-tried upload will correctly propagate the server's health status for any
1392 // subsequent re-tries. Hence, we'll at most delay slowing the upload rate by
1393 // one re-try, which is fine.
1394 scheduler_->UploadFinished(server_is_healthy, log_manager_.has_unsent_logs());
1417 1395
1418 // Collect network stats if UMA upload succeeded. 1396 // Collect network stats if UMA upload succeeded.
1419 IOThread* io_thread = g_browser_process->io_thread(); 1397 IOThread* io_thread = g_browser_process->io_thread();
1420 if (server_is_healthy && io_thread) { 1398 if (server_is_healthy && io_thread) {
1421 chrome_browser_net::CollectNetworkStats(network_stats_server_, io_thread); 1399 chrome_browser_net::CollectNetworkStats(network_stats_server_, io_thread);
1422 chrome_browser_net::CollectPipeliningCapabilityStatsOnUIThread( 1400 chrome_browser_net::CollectPipeliningCapabilityStatsOnUIThread(
1423 http_pipelining_test_server_, io_thread); 1401 http_pipelining_test_server_, io_thread);
1424 } 1402 }
1425
1426 // Reset the cached response data.
1427 response_code_ = kNoResponseCode;
1428 response_data_ = std::string();
1429 response_status_ = std::string();
1430 } 1403 }
1431 1404
1432 void MetricsService::LogBadResponseCode() { 1405 void MetricsService::LogBadResponseCode(int response_code, bool is_xml) {
1433 VLOG(1) << "Verify your metrics logs are formatted correctly. Verify server " 1406 VLOG(1) << "Metrics: transmission attempt returned a failure code: "
1434 "is active at " << server_url_xml_; 1407 << response_code << ". Verify network connectivity and that your "
1408 << "metrics logs are formatted correctly. Verify server is active at "
1409 << (is_xml ? server_url_xml_ : server_url_proto_) << ".";
1410
1435 if (!log_manager_.has_staged_log()) { 1411 if (!log_manager_.has_staged_log()) {
1436 VLOG(1) << "METRICS: Recorder shutdown during log transmission."; 1412 // TODO(isherman): I don't think this code is reachable...
1413 VLOG(1) << "Metrics: Recorder shutdown during log transmission.";
1437 } else { 1414 } else {
1438 VLOG(1) << "METRICS: transmission retry being scheduled for " 1415 if (is_xml) {
1439 << log_manager_.staged_log_text().xml; 1416 VLOG(1) << "Metrics: transmission retry being scheduled for \n"
1417 << log_manager_.staged_log_text().xml;
1418 } else {
1419 VLOG(1)
1420 << "Metrics: transmission retry being scheduled for protobuf upload.";
1421 }
1440 } 1422 }
1441 } 1423 }
1442 1424
1443 void MetricsService::LogWindowChange( 1425 void MetricsService::LogWindowChange(
1444 int type, 1426 int type,
1445 const content::NotificationSource& source, 1427 const content::NotificationSource& source,
1446 const content::NotificationDetails& details) { 1428 const content::NotificationDetails& details) {
1447 int controller_id = -1; 1429 int controller_id = -1;
1448 uintptr_t window_or_tab = source.map_key(); 1430 uintptr_t window_or_tab = source.map_key();
1449 MetricsLog::WindowEventType window_type; 1431 MetricsLog::WindowEventType window_type;
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
1821 if (local_state) { 1803 if (local_state) {
1822 const PrefService::Preference* uma_pref = 1804 const PrefService::Preference* uma_pref =
1823 local_state->FindPreference(prefs::kMetricsReportingEnabled); 1805 local_state->FindPreference(prefs::kMetricsReportingEnabled);
1824 if (uma_pref) { 1806 if (uma_pref) {
1825 bool success = uma_pref->GetValue()->GetAsBoolean(&result); 1807 bool success = uma_pref->GetValue()->GetAsBoolean(&result);
1826 DCHECK(success); 1808 DCHECK(success);
1827 } 1809 }
1828 } 1810 }
1829 return result; 1811 return result;
1830 } 1812 }
OLDNEW
« no previous file with comments | « chrome/browser/metrics/metrics_service.h ('k') | chrome/common/metrics/metrics_log_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698