OLD | NEW |
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 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 const size_t kUploadLogAvoidRetransmitSize = 50000; | 236 const size_t kUploadLogAvoidRetransmitSize = 50000; |
237 | 237 |
238 // Interval, in minutes, between state saves. | 238 // Interval, in minutes, between state saves. |
239 const int kSaveStateIntervalMinutes = 5; | 239 const int kSaveStateIntervalMinutes = 5; |
240 | 240 |
241 // Used to indicate that the response code is currently not set at all -- | 241 // Used to indicate that the response code is currently not set at all -- |
242 // RESPONSE_CODE_INVALID can sometimes be returned in response to a request if, | 242 // RESPONSE_CODE_INVALID can sometimes be returned in response to a request if, |
243 // e.g., the server is down. | 243 // e.g., the server is down. |
244 const int kNoResponseCode = content::URLFetcher::RESPONSE_CODE_INVALID - 1; | 244 const int kNoResponseCode = content::URLFetcher::RESPONSE_CODE_INVALID - 1; |
245 | 245 |
| 246 enum ResponseStatus { |
| 247 UNKNOWN_FAILURE, |
| 248 SUCCESS, |
| 249 BAD_REQUEST, // Invalid syntax or log too large. |
| 250 NUM_RESPONSE_STATUSES |
| 251 }; |
| 252 |
| 253 ResponseStatus ResponseCodeToStatus(int response_code) { |
| 254 switch (response_code) { |
| 255 case 200: |
| 256 return SUCCESS; |
| 257 case 400: |
| 258 return BAD_REQUEST; |
| 259 default: |
| 260 return UNKNOWN_FAILURE; |
| 261 } |
| 262 } |
| 263 |
246 } | 264 } |
247 | 265 |
248 // static | 266 // static |
249 MetricsService::ShutdownCleanliness MetricsService::clean_shutdown_status_ = | 267 MetricsService::ShutdownCleanliness MetricsService::clean_shutdown_status_ = |
250 MetricsService::CLEANLY_SHUTDOWN; | 268 MetricsService::CLEANLY_SHUTDOWN; |
251 | 269 |
252 // This is used to quickly log stats from child process related notifications in | 270 // This is used to quickly log stats from child process related notifications in |
253 // MetricsService::child_stats_buffer_. The buffer's contents are transferred | 271 // MetricsService::child_stats_buffer_. The buffer's contents are transferred |
254 // out when Local State is periodically saved. The information is then | 272 // out when Local State is periodically saved. The information is then |
255 // reported to the UMA server on next launch. | 273 // reported to the UMA server on next launch. |
(...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1235 // not retry the protobuf upload. If the XML upload fails while the protobuf | 1253 // not retry the protobuf upload. If the XML upload fails while the protobuf |
1236 // upload succeeds, we will still avoid re-uploading the protobuf data because | 1254 // upload succeeds, we will still avoid re-uploading the protobuf data because |
1237 // we "zap" the data after the first upload attempt. This means that we might | 1255 // we "zap" the data after the first upload attempt. This means that we might |
1238 // lose protobuf uploads when XML ones succeed; but we will never duplicate any | 1256 // lose protobuf uploads when XML ones succeed; but we will never duplicate any |
1239 // protobuf uploads. Protobuf failures should be rare enough to where this | 1257 // protobuf uploads. Protobuf failures should be rare enough to where this |
1240 // should be ok while we have the two pipelines running in parallel. | 1258 // should be ok while we have the two pipelines running in parallel. |
1241 void MetricsService::OnURLFetchComplete(const net::URLFetcher* source) { | 1259 void MetricsService::OnURLFetchComplete(const net::URLFetcher* source) { |
1242 DCHECK(waiting_for_asynchronus_reporting_step_); | 1260 DCHECK(waiting_for_asynchronus_reporting_step_); |
1243 | 1261 |
1244 // We're not allowed to re-use the existing |URLFetcher|s, so free them here. | 1262 // We're not allowed to re-use the existing |URLFetcher|s, so free them here. |
| 1263 // Note however that |source| is aliased to one of these, so we should be |
| 1264 // careful not to delete it too early. |
1245 scoped_ptr<content::URLFetcher> s; | 1265 scoped_ptr<content::URLFetcher> s; |
1246 if (source == current_fetch_xml_.get()) { | 1266 if (source == current_fetch_xml_.get()) { |
1247 s.reset(current_fetch_xml_.release()); | 1267 s.reset(current_fetch_xml_.release()); |
1248 | 1268 |
1249 // Cache the XML responses, in case we still need to wait for the protobuf | 1269 // Cache the XML responses, in case we still need to wait for the protobuf |
1250 // response. | 1270 // response. |
1251 response_code_ = source->GetResponseCode(); | 1271 response_code_ = source->GetResponseCode(); |
1252 response_status_ = StatusToString(source->GetStatus()); | 1272 response_status_ = StatusToString(source->GetStatus()); |
1253 source->GetResponseAsString(&response_data_); | 1273 source->GetResponseAsString(&response_data_); |
| 1274 |
| 1275 // Log a histogram to track response success vs. failure rates. |
| 1276 UMA_HISTOGRAM_ENUMERATION("UMA.UploadResponseStatus.XML", |
| 1277 ResponseCodeToStatus(response_code_), |
| 1278 NUM_RESPONSE_STATUSES); |
1254 } else if (source == current_fetch_proto_.get()) { | 1279 } else if (source == current_fetch_proto_.get()) { |
1255 s.reset(current_fetch_proto_.release()); | 1280 s.reset(current_fetch_proto_.release()); |
| 1281 |
| 1282 // Log a histogram to track response success vs. failure rates. |
| 1283 UMA_HISTOGRAM_ENUMERATION("UMA.UploadResponseStatus.Protobuf", |
| 1284 ResponseCodeToStatus(source->GetResponseCode()), |
| 1285 NUM_RESPONSE_STATUSES); |
1256 } else { | 1286 } else { |
1257 NOTREACHED(); | 1287 NOTREACHED(); |
1258 return; | 1288 return; |
1259 } | 1289 } |
1260 | 1290 |
1261 // If we're still waiting for one of the responses, keep waiting... | 1291 // If we're still waiting for one of the responses, keep waiting... |
1262 if (current_fetch_xml_.get() || current_fetch_proto_.get()) | 1292 if (current_fetch_xml_.get() || current_fetch_proto_.get()) |
1263 return; | 1293 return; |
1264 | 1294 |
1265 // We should only be able to reach here once we've received responses to both | 1295 // We should only be able to reach here once we've received responses to both |
1266 // the XML and the protobuf requests. We should always have the response code | 1296 // the XML and the protobuf requests. We should always have the response code |
1267 // available. | 1297 // available. |
1268 DCHECK_NE(response_code_, kNoResponseCode); | 1298 DCHECK_NE(response_code_, kNoResponseCode); |
1269 waiting_for_asynchronus_reporting_step_ = false; | 1299 waiting_for_asynchronus_reporting_step_ = false; |
1270 | 1300 |
1271 // If the upload was provisionally stored, drop it now that the upload is | 1301 // If the upload was provisionally stored, drop it now that the upload is |
1272 // known to have gone through. | 1302 // known to have gone through. |
1273 log_manager_.DiscardLastProvisionalStore(); | 1303 log_manager_.DiscardLastProvisionalStore(); |
1274 | 1304 |
1275 // Confirm send so that we can move on. | 1305 // Confirm send so that we can move on. |
1276 VLOG(1) << "METRICS RESPONSE CODE: " << response_code_ | 1306 VLOG(1) << "Metrics response code: " << response_code_ |
1277 << " status=" << response_status_; | 1307 << " status=" << response_status_; |
1278 | 1308 |
1279 bool upload_succeeded = response_code_ == 200; | 1309 bool upload_succeeded = response_code_ == 200; |
1280 | 1310 |
1281 // Provide boolean for error recovery (allow us to ignore response_code). | 1311 // Provide boolean for error recovery (allow us to ignore response_code). |
1282 bool discard_log = false; | 1312 bool discard_log = false; |
1283 | 1313 |
1284 if (!upload_succeeded && | 1314 if (!upload_succeeded && |
1285 log_manager_.staged_log_text().xml.length() > | 1315 log_manager_.staged_log_text().xml.length() > |
1286 kUploadLogAvoidRetransmitSize) { | 1316 kUploadLogAvoidRetransmitSize) { |
1287 UMA_HISTOGRAM_COUNTS( | 1317 UMA_HISTOGRAM_COUNTS( |
1288 "UMA.Large Rejected Log was Discarded", | 1318 "UMA.Large Rejected Log was Discarded", |
1289 static_cast<int>(log_manager_.staged_log_text().xml.length())); | 1319 static_cast<int>(log_manager_.staged_log_text().xml.length())); |
1290 discard_log = true; | 1320 discard_log = true; |
1291 } else if (response_code_ == 400) { | 1321 } else if (response_code_ == 400) { |
1292 // Bad syntax. Retransmission won't work. | 1322 // Bad syntax. Retransmission won't work. |
1293 UMA_HISTOGRAM_COUNTS("UMA.Unacceptable_Log_Discarded", state_); | |
1294 discard_log = true; | 1323 discard_log = true; |
1295 } | 1324 } |
1296 | 1325 |
1297 if (!upload_succeeded && !discard_log) { | 1326 if (!upload_succeeded && !discard_log) { |
1298 VLOG(1) << "METRICS: transmission attempt returned a failure code: " | 1327 VLOG(1) << "Metrics: transmission attempt returned a failure code: " |
1299 << response_code_ << ". Verify network connectivity"; | 1328 << response_code_ << ". Verify network connectivity"; |
1300 LogBadResponseCode(); | 1329 LogBadResponseCode(); |
1301 } else { // Successful receipt (or we are discarding log). | 1330 } else { // Successful receipt (or we are discarding log). |
1302 VLOG(1) << "METRICS RESPONSE DATA: " << response_data_; | 1331 VLOG(1) << "Metrics response data: " << response_data_; |
1303 switch (state_) { | 1332 switch (state_) { |
1304 case INITIAL_LOG_READY: | 1333 case INITIAL_LOG_READY: |
1305 state_ = SENDING_OLD_LOGS; | 1334 state_ = SENDING_OLD_LOGS; |
1306 break; | 1335 break; |
1307 | 1336 |
1308 case SENDING_OLD_LOGS: | 1337 case SENDING_OLD_LOGS: |
1309 // Store the updated list to disk now that the removed log is uploaded. | 1338 // Store the updated list to disk now that the removed log is uploaded. |
1310 StoreUnsentLogs(); | 1339 StoreUnsentLogs(); |
1311 break; | 1340 break; |
1312 | 1341 |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1737 if (local_state) { | 1766 if (local_state) { |
1738 const PrefService::Preference* uma_pref = | 1767 const PrefService::Preference* uma_pref = |
1739 local_state->FindPreference(prefs::kMetricsReportingEnabled); | 1768 local_state->FindPreference(prefs::kMetricsReportingEnabled); |
1740 if (uma_pref) { | 1769 if (uma_pref) { |
1741 bool success = uma_pref->GetValue()->GetAsBoolean(&result); | 1770 bool success = uma_pref->GetValue()->GetAsBoolean(&result); |
1742 DCHECK(success); | 1771 DCHECK(success); |
1743 } | 1772 } |
1744 } | 1773 } |
1745 return result; | 1774 return result; |
1746 } | 1775 } |
OLD | NEW |