Chromium Code Reviews| 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/data_reduction_proxy/browser/data_reduction_proxy_usage_sta ts.h" | 5 #include "components/data_reduction_proxy/browser/data_reduction_proxy_usage_sta ts.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/message_loop/message_loop_proxy.h" | 9 #include "base/message_loop/message_loop_proxy.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| 11 #include "base/metrics/sparse_histogram.h" | 11 #include "base/metrics/sparse_histogram.h" |
| 12 #include "base/prefs/pref_member.h" | |
| 12 #include "components/data_reduction_proxy/common/data_reduction_proxy_headers.h" | 13 #include "components/data_reduction_proxy/common/data_reduction_proxy_headers.h" |
| 13 #include "net/base/net_errors.h" | 14 #include "net/base/net_errors.h" |
| 15 #include "net/http/http_response_headers.h" | |
| 16 #include "net/http/http_status_code.h" | |
| 17 #include "net/http/http_util.h" | |
| 14 #include "net/proxy/proxy_retry_info.h" | 18 #include "net/proxy/proxy_retry_info.h" |
| 15 #include "net/proxy/proxy_server.h" | 19 #include "net/proxy/proxy_server.h" |
| 16 #include "net/proxy/proxy_service.h" | 20 #include "net/proxy/proxy_service.h" |
| 17 #include "net/url_request/url_request.h" | 21 #include "net/url_request/url_request.h" |
| 18 #include "net/url_request/url_request_context.h" | 22 #include "net/url_request/url_request_context.h" |
| 19 | 23 |
| 20 using base::MessageLoopProxy; | 24 using base::MessageLoopProxy; |
| 21 using net::HostPortPair; | 25 using net::HostPortPair; |
| 22 using net::ProxyServer; | 26 using net::ProxyServer; |
| 23 using net::ProxyService; | 27 using net::ProxyService; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 65 if (is_primary) { | 69 if (is_primary) { |
| 66 UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.BypassTypePrimary", | 70 UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.BypassTypePrimary", |
| 67 bypass_type, BYPASS_EVENT_TYPE_MAX); | 71 bypass_type, BYPASS_EVENT_TYPE_MAX); |
| 68 } else { | 72 } else { |
| 69 UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.BypassTypeFallback", | 73 UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.BypassTypeFallback", |
| 70 bypass_type, BYPASS_EVENT_TYPE_MAX); | 74 bypass_type, BYPASS_EVENT_TYPE_MAX); |
| 71 } | 75 } |
| 72 } | 76 } |
| 73 } | 77 } |
| 74 | 78 |
| 79 // static | |
| 80 void DataReductionProxyUsageStats::DetectAndRecordMissingViaHeaderResponseCode( | |
| 81 bool is_primary, const net::HttpResponseHeaders* headers) { | |
|
Alexei Svitkine (slow)
2014/09/23 15:12:13
Nit: 1 param per line if first one is wrapped.
sclittle
2014/09/23 18:13:41
Done.
| |
| 82 if (HasDataReductionProxyViaHeader(headers, NULL)) { | |
| 83 // The data reduction proxy via header is present, so don't record anything. | |
| 84 return; | |
| 85 } | |
| 86 | |
| 87 // Record the response code in the same way that net::HttpResponseHeaders | |
| 88 // records the response code for the histogram Net.HttpResponseCode. | |
| 89 if (is_primary) { | |
| 90 UMA_HISTOGRAM_CUSTOM_ENUMERATION( | |
|
Alexei Svitkine (slow)
2014/09/23 15:12:13
It's better to use an UMA_HISTOGRAM_SPARSE_SLOWLY(
sclittle
2014/09/23 18:13:41
Done. I'll keep the call to MapStatusCodeForHistog
Alexei Svitkine (slow)
2014/09/23 18:20:06
Sorry, I don't understand what you mean for your r
sclittle
2014/09/23 19:58:30
On second thought, you're right, we don't need thi
| |
| 91 "DataReductionProxy.MissingViaHeaderResponseCodePrimary", | |
|
Alexei Svitkine (slow)
2014/09/23 15:12:13
Consider adding .'s to delimit different parts of
sclittle
2014/09/23 18:13:41
Done.
| |
| 92 net::HttpUtil::MapStatusCodeForHistogram(headers->response_code()), | |
| 93 net::HttpUtil::GetStatusCodesForHistogram()); | |
| 94 } else { | |
| 95 UMA_HISTOGRAM_CUSTOM_ENUMERATION( | |
| 96 "DataReductionProxy.MissingViaHeaderResponseCodeFallback", | |
| 97 net::HttpUtil::MapStatusCodeForHistogram(headers->response_code()), | |
| 98 net::HttpUtil::GetStatusCodesForHistogram()); | |
| 99 } | |
| 100 } | |
| 101 | |
| 75 DataReductionProxyUsageStats::DataReductionProxyUsageStats( | 102 DataReductionProxyUsageStats::DataReductionProxyUsageStats( |
| 76 DataReductionProxyParams* params, | 103 DataReductionProxyParams* params, |
| 77 MessageLoopProxy* ui_thread_proxy) | 104 MessageLoopProxy* ui_thread_proxy) |
| 78 : data_reduction_proxy_params_(params), | 105 : data_reduction_proxy_params_(params), |
| 79 last_bypass_type_(BYPASS_EVENT_TYPE_MAX), | 106 last_bypass_type_(BYPASS_EVENT_TYPE_MAX), |
| 80 triggering_request_(true), | 107 triggering_request_(true), |
| 81 ui_thread_proxy_(ui_thread_proxy), | 108 ui_thread_proxy_(ui_thread_proxy), |
| 82 eligible_num_requests_through_proxy_(0), | 109 eligible_num_requests_through_proxy_(0), |
| 83 actual_num_requests_through_proxy_(0), | 110 actual_num_requests_through_proxy_(0), |
| 84 unavailable_(false) { | 111 unavailable_(false) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 152 if (!unavailable_callback_.is_null()) | 179 if (!unavailable_callback_.is_null()) |
| 153 unavailable_callback_.Run(unavailable); | 180 unavailable_callback_.Run(unavailable); |
| 154 } | 181 } |
| 155 | 182 |
| 156 void DataReductionProxyUsageStats::SetBypassType( | 183 void DataReductionProxyUsageStats::SetBypassType( |
| 157 DataReductionProxyBypassType type) { | 184 DataReductionProxyBypassType type) { |
| 158 last_bypass_type_ = type; | 185 last_bypass_type_ = type; |
| 159 triggering_request_ = true; | 186 triggering_request_ = true; |
| 160 } | 187 } |
| 161 | 188 |
| 162 void DataReductionProxyUsageStats::RecordBypassedBytesHistograms( | 189 void DataReductionProxyUsageStats::RecordBytesHistograms( |
| 163 net::URLRequest& request, | 190 net::URLRequest* request, |
| 164 const BooleanPrefMember& data_reduction_proxy_enabled, | 191 const BooleanPrefMember& data_reduction_proxy_enabled, |
| 165 const net::ProxyConfig& data_reduction_proxy_config) { | 192 const net::ProxyConfig& data_reduction_proxy_config) { |
| 166 int64 content_length = request.received_response_content_length(); | 193 RecordBypassedBytesHistograms(request, data_reduction_proxy_enabled, |
| 194 data_reduction_proxy_config); | |
| 195 RecordMissingViaHeaderBytes(request); | |
| 196 } | |
| 197 | |
| 198 void DataReductionProxyUsageStats::RecordBypassedBytesHistograms( | |
| 199 net::URLRequest* request, | |
| 200 const BooleanPrefMember& data_reduction_proxy_enabled, | |
| 201 const net::ProxyConfig& data_reduction_proxy_config) { | |
| 202 int64 content_length = request->received_response_content_length(); | |
| 167 | 203 |
| 168 if (data_reduction_proxy_enabled.GetValue() && | 204 if (data_reduction_proxy_enabled.GetValue() && |
| 169 !data_reduction_proxy_config.Equals( | 205 !data_reduction_proxy_config.Equals( |
| 170 request.context()->proxy_service()->config())) { | 206 request->context()->proxy_service()->config())) { |
| 171 RecordBypassedBytes(last_bypass_type_, | 207 RecordBypassedBytes(last_bypass_type_, |
| 172 DataReductionProxyUsageStats::MANAGED_PROXY_CONFIG, | 208 DataReductionProxyUsageStats::MANAGED_PROXY_CONFIG, |
| 173 content_length); | 209 content_length); |
| 174 return; | 210 return; |
| 175 } | 211 } |
| 176 | 212 |
| 177 if (data_reduction_proxy_params_->WasDataReductionProxyUsed(&request, NULL)) { | 213 if (data_reduction_proxy_params_->WasDataReductionProxyUsed(request, NULL)) { |
| 178 RecordBypassedBytes(last_bypass_type_, | 214 RecordBypassedBytes(last_bypass_type_, |
| 179 DataReductionProxyUsageStats::NOT_BYPASSED, | 215 DataReductionProxyUsageStats::NOT_BYPASSED, |
| 180 content_length); | 216 content_length); |
| 181 return; | 217 return; |
| 182 } | 218 } |
| 183 | 219 |
| 184 if (data_reduction_proxy_enabled.GetValue() && | 220 if (data_reduction_proxy_enabled.GetValue() && |
| 185 request.url().SchemeIs(url::kHttpsScheme)) { | 221 request->url().SchemeIs(url::kHttpsScheme)) { |
| 186 RecordBypassedBytes(last_bypass_type_, | 222 RecordBypassedBytes(last_bypass_type_, |
| 187 DataReductionProxyUsageStats::SSL, | 223 DataReductionProxyUsageStats::SSL, |
| 188 content_length); | 224 content_length); |
| 189 return; | 225 return; |
| 190 } | 226 } |
| 191 | 227 |
| 192 if (data_reduction_proxy_enabled.GetValue() && | 228 if (data_reduction_proxy_enabled.GetValue() && |
| 193 data_reduction_proxy_params_->IsBypassedByDataReductionProxyLocalRules( | 229 data_reduction_proxy_params_->IsBypassedByDataReductionProxyLocalRules( |
| 194 request, data_reduction_proxy_config)) { | 230 *request, data_reduction_proxy_config)) { |
| 195 RecordBypassedBytes(last_bypass_type_, | 231 RecordBypassedBytes(last_bypass_type_, |
| 196 DataReductionProxyUsageStats::LOCAL_BYPASS_RULES, | 232 DataReductionProxyUsageStats::LOCAL_BYPASS_RULES, |
| 197 content_length); | 233 content_length); |
| 198 return; | 234 return; |
| 199 } | 235 } |
| 200 | 236 |
| 201 // Only record separate triggering request UMA for short, medium, and long | 237 // Only record separate triggering request UMA for short, medium, and long |
| 202 // bypass events. | 238 // bypass events. |
| 203 if (triggering_request_ && | 239 if (triggering_request_ && |
| 204 (last_bypass_type_ == BYPASS_EVENT_TYPE_SHORT || | 240 (last_bypass_type_ == BYPASS_EVENT_TYPE_SHORT || |
| 205 last_bypass_type_ == BYPASS_EVENT_TYPE_MEDIUM || | 241 last_bypass_type_ == BYPASS_EVENT_TYPE_MEDIUM || |
| 206 last_bypass_type_ == BYPASS_EVENT_TYPE_LONG)) { | 242 last_bypass_type_ == BYPASS_EVENT_TYPE_LONG)) { |
| 207 std::string mime_type; | 243 std::string mime_type; |
| 208 request.GetMimeType(&mime_type); | 244 request->GetMimeType(&mime_type); |
| 209 // MIME types are named by <media-type>/<subtype>. Check to see if the | 245 // MIME types are named by <media-type>/<subtype>. Check to see if the |
| 210 // media type is audio or video. Only record when triggered by short bypass, | 246 // media type is audio or video. Only record when triggered by short bypass, |
| 211 // there isn't an audio or video bucket for medium or long bypasses. | 247 // there isn't an audio or video bucket for medium or long bypasses. |
| 212 if (last_bypass_type_ == BYPASS_EVENT_TYPE_SHORT && | 248 if (last_bypass_type_ == BYPASS_EVENT_TYPE_SHORT && |
| 213 (mime_type.compare(0, 6, "audio/") == 0 || | 249 (mime_type.compare(0, 6, "audio/") == 0 || |
| 214 mime_type.compare(0, 6, "video/") == 0)) { | 250 mime_type.compare(0, 6, "video/") == 0)) { |
| 215 RecordBypassedBytes(last_bypass_type_, | 251 RecordBypassedBytes(last_bypass_type_, |
| 216 DataReductionProxyUsageStats::AUDIO_VIDEO, | 252 DataReductionProxyUsageStats::AUDIO_VIDEO, |
| 217 content_length); | 253 content_length); |
| 218 return; | 254 return; |
| 219 } | 255 } |
| 220 | 256 |
| 221 RecordBypassedBytes(last_bypass_type_, | 257 RecordBypassedBytes(last_bypass_type_, |
| 222 DataReductionProxyUsageStats::TRIGGERING_REQUEST, | 258 DataReductionProxyUsageStats::TRIGGERING_REQUEST, |
| 223 content_length); | 259 content_length); |
| 224 triggering_request_ = false; | 260 triggering_request_ = false; |
| 225 return; | 261 return; |
| 226 } | 262 } |
| 227 | 263 |
| 228 if (last_bypass_type_ != BYPASS_EVENT_TYPE_MAX) { | 264 if (last_bypass_type_ != BYPASS_EVENT_TYPE_MAX) { |
| 229 RecordBypassedBytes(last_bypass_type_, | 265 RecordBypassedBytes(last_bypass_type_, |
| 230 DataReductionProxyUsageStats::BYPASSED_BYTES_TYPE_MAX, | 266 DataReductionProxyUsageStats::BYPASSED_BYTES_TYPE_MAX, |
| 231 content_length); | 267 content_length); |
| 232 return; | 268 return; |
| 233 } | 269 } |
| 234 | 270 |
| 235 if (data_reduction_proxy_params_->AreDataReductionProxiesBypassed(request, | 271 if (data_reduction_proxy_params_->AreDataReductionProxiesBypassed(*request, |
| 236 NULL)) { | 272 NULL)) { |
| 237 RecordBypassedBytes(last_bypass_type_, | 273 RecordBypassedBytes(last_bypass_type_, |
| 238 DataReductionProxyUsageStats::NETWORK_ERROR, | 274 DataReductionProxyUsageStats::NETWORK_ERROR, |
| 239 content_length); | 275 content_length); |
| 240 } | 276 } |
| 241 } | 277 } |
| 242 | 278 |
| 243 void DataReductionProxyUsageStats::RecordBypassEventHistograms( | 279 void DataReductionProxyUsageStats::RecordBypassEventHistograms( |
| 244 const net::ProxyServer& bypassed_proxy, | 280 const net::ProxyServer& bypassed_proxy, |
| 245 int net_error) const { | 281 int net_error) const { |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 371 "Status503HttpServiceUnavailable", | 407 "Status503HttpServiceUnavailable", |
| 372 content_length); | 408 content_length); |
| 373 break; | 409 break; |
| 374 default: | 410 default: |
| 375 break; | 411 break; |
| 376 } | 412 } |
| 377 break; | 413 break; |
| 378 } | 414 } |
| 379 } | 415 } |
| 380 | 416 |
| 417 void DataReductionProxyUsageStats::RecordMissingViaHeaderBytes( | |
| 418 URLRequest* request) { | |
| 419 // Responses that were served from cache should have been filtered out | |
| 420 // already. | |
| 421 DCHECK(!request->was_cached()); | |
| 422 | |
| 423 if (!data_reduction_proxy_params_->WasDataReductionProxyUsed(request, NULL) || | |
| 424 HasDataReductionProxyViaHeader(request->response_headers(), NULL)) { | |
| 425 // Only track requests that used the data reduction proxy and had responses | |
| 426 // that were missing the data reduction proxy via header. | |
| 427 return; | |
| 428 } | |
| 429 | |
| 430 if (request->GetResponseCode() >= net::HTTP_BAD_REQUEST && | |
| 431 request->GetResponseCode() < net::HTTP_INTERNAL_SERVER_ERROR) { | |
| 432 // Track 4xx responses that are missing via headers separately. | |
| 433 UMA_HISTOGRAM_COUNTS("DataReductionProxy.MissingViaHeader4xxResponseBytes", | |
| 434 request->received_response_content_length()); | |
| 435 } else { | |
| 436 UMA_HISTOGRAM_COUNTS( | |
| 437 "DataReductionProxy.MissingViaHeaderOtherResponseBytes", | |
| 438 request->received_response_content_length()); | |
| 439 } | |
| 440 } | |
| 441 | |
| 381 } // namespace data_reduction_proxy | 442 } // namespace data_reduction_proxy |
| 382 | 443 |
| 383 | 444 |
| OLD | NEW |