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, |
| 82 const net::HttpResponseHeaders* headers) { |
| 83 if (HasDataReductionProxyViaHeader(headers, NULL)) { |
| 84 // The data reduction proxy via header is present, so don't record anything. |
| 85 return; |
| 86 } |
| 87 |
| 88 if (is_primary) { |
| 89 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 90 "DataReductionProxy.MissingViaHeader.ResponseCode.Primary", |
| 91 net::HttpUtil::MapStatusCodeForHistogram(headers->response_code())); |
| 92 } else { |
| 93 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 94 "DataReductionProxy.MissingViaHeader.ResponseCode.Fallback", |
| 95 net::HttpUtil::MapStatusCodeForHistogram(headers->response_code())); |
| 96 } |
| 97 } |
| 98 |
75 DataReductionProxyUsageStats::DataReductionProxyUsageStats( | 99 DataReductionProxyUsageStats::DataReductionProxyUsageStats( |
76 DataReductionProxyParams* params, | 100 DataReductionProxyParams* params, |
77 MessageLoopProxy* ui_thread_proxy) | 101 MessageLoopProxy* ui_thread_proxy) |
78 : data_reduction_proxy_params_(params), | 102 : data_reduction_proxy_params_(params), |
79 last_bypass_type_(BYPASS_EVENT_TYPE_MAX), | 103 last_bypass_type_(BYPASS_EVENT_TYPE_MAX), |
80 triggering_request_(true), | 104 triggering_request_(true), |
81 ui_thread_proxy_(ui_thread_proxy), | 105 ui_thread_proxy_(ui_thread_proxy), |
82 eligible_num_requests_through_proxy_(0), | 106 eligible_num_requests_through_proxy_(0), |
83 actual_num_requests_through_proxy_(0), | 107 actual_num_requests_through_proxy_(0), |
84 unavailable_(false) { | 108 unavailable_(false) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 if (!unavailable_callback_.is_null()) | 176 if (!unavailable_callback_.is_null()) |
153 unavailable_callback_.Run(unavailable); | 177 unavailable_callback_.Run(unavailable); |
154 } | 178 } |
155 | 179 |
156 void DataReductionProxyUsageStats::SetBypassType( | 180 void DataReductionProxyUsageStats::SetBypassType( |
157 DataReductionProxyBypassType type) { | 181 DataReductionProxyBypassType type) { |
158 last_bypass_type_ = type; | 182 last_bypass_type_ = type; |
159 triggering_request_ = true; | 183 triggering_request_ = true; |
160 } | 184 } |
161 | 185 |
162 void DataReductionProxyUsageStats::RecordBypassedBytesHistograms( | 186 void DataReductionProxyUsageStats::RecordBytesHistograms( |
163 net::URLRequest& request, | 187 net::URLRequest* request, |
164 const BooleanPrefMember& data_reduction_proxy_enabled, | 188 const BooleanPrefMember& data_reduction_proxy_enabled, |
165 const net::ProxyConfig& data_reduction_proxy_config) { | 189 const net::ProxyConfig& data_reduction_proxy_config) { |
166 int64 content_length = request.received_response_content_length(); | 190 RecordBypassedBytesHistograms(request, data_reduction_proxy_enabled, |
| 191 data_reduction_proxy_config); |
| 192 RecordMissingViaHeaderBytes(request); |
| 193 } |
| 194 |
| 195 void DataReductionProxyUsageStats::RecordBypassedBytesHistograms( |
| 196 net::URLRequest* request, |
| 197 const BooleanPrefMember& data_reduction_proxy_enabled, |
| 198 const net::ProxyConfig& data_reduction_proxy_config) { |
| 199 int64 content_length = request->received_response_content_length(); |
167 | 200 |
168 if (data_reduction_proxy_enabled.GetValue() && | 201 if (data_reduction_proxy_enabled.GetValue() && |
169 !data_reduction_proxy_config.Equals( | 202 !data_reduction_proxy_config.Equals( |
170 request.context()->proxy_service()->config())) { | 203 request->context()->proxy_service()->config())) { |
171 RecordBypassedBytes(last_bypass_type_, | 204 RecordBypassedBytes(last_bypass_type_, |
172 DataReductionProxyUsageStats::MANAGED_PROXY_CONFIG, | 205 DataReductionProxyUsageStats::MANAGED_PROXY_CONFIG, |
173 content_length); | 206 content_length); |
174 return; | 207 return; |
175 } | 208 } |
176 | 209 |
177 if (data_reduction_proxy_params_->WasDataReductionProxyUsed(&request, NULL)) { | 210 if (data_reduction_proxy_params_->WasDataReductionProxyUsed(request, NULL)) { |
178 RecordBypassedBytes(last_bypass_type_, | 211 RecordBypassedBytes(last_bypass_type_, |
179 DataReductionProxyUsageStats::NOT_BYPASSED, | 212 DataReductionProxyUsageStats::NOT_BYPASSED, |
180 content_length); | 213 content_length); |
181 return; | 214 return; |
182 } | 215 } |
183 | 216 |
184 if (data_reduction_proxy_enabled.GetValue() && | 217 if (data_reduction_proxy_enabled.GetValue() && |
185 request.url().SchemeIs(url::kHttpsScheme)) { | 218 request->url().SchemeIs(url::kHttpsScheme)) { |
186 RecordBypassedBytes(last_bypass_type_, | 219 RecordBypassedBytes(last_bypass_type_, |
187 DataReductionProxyUsageStats::SSL, | 220 DataReductionProxyUsageStats::SSL, |
188 content_length); | 221 content_length); |
189 return; | 222 return; |
190 } | 223 } |
191 | 224 |
192 if (data_reduction_proxy_enabled.GetValue() && | 225 if (data_reduction_proxy_enabled.GetValue() && |
193 data_reduction_proxy_params_->IsBypassedByDataReductionProxyLocalRules( | 226 data_reduction_proxy_params_->IsBypassedByDataReductionProxyLocalRules( |
194 request, data_reduction_proxy_config)) { | 227 *request, data_reduction_proxy_config)) { |
195 RecordBypassedBytes(last_bypass_type_, | 228 RecordBypassedBytes(last_bypass_type_, |
196 DataReductionProxyUsageStats::LOCAL_BYPASS_RULES, | 229 DataReductionProxyUsageStats::LOCAL_BYPASS_RULES, |
197 content_length); | 230 content_length); |
198 return; | 231 return; |
199 } | 232 } |
200 | 233 |
201 // Only record separate triggering request UMA for short, medium, and long | 234 // Only record separate triggering request UMA for short, medium, and long |
202 // bypass events. | 235 // bypass events. |
203 if (triggering_request_ && | 236 if (triggering_request_ && |
204 (last_bypass_type_ == BYPASS_EVENT_TYPE_SHORT || | 237 (last_bypass_type_ == BYPASS_EVENT_TYPE_SHORT || |
205 last_bypass_type_ == BYPASS_EVENT_TYPE_MEDIUM || | 238 last_bypass_type_ == BYPASS_EVENT_TYPE_MEDIUM || |
206 last_bypass_type_ == BYPASS_EVENT_TYPE_LONG)) { | 239 last_bypass_type_ == BYPASS_EVENT_TYPE_LONG)) { |
207 std::string mime_type; | 240 std::string mime_type; |
208 request.GetMimeType(&mime_type); | 241 request->GetMimeType(&mime_type); |
209 // MIME types are named by <media-type>/<subtype>. Check to see if the | 242 // 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, | 243 // 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. | 244 // there isn't an audio or video bucket for medium or long bypasses. |
212 if (last_bypass_type_ == BYPASS_EVENT_TYPE_SHORT && | 245 if (last_bypass_type_ == BYPASS_EVENT_TYPE_SHORT && |
213 (mime_type.compare(0, 6, "audio/") == 0 || | 246 (mime_type.compare(0, 6, "audio/") == 0 || |
214 mime_type.compare(0, 6, "video/") == 0)) { | 247 mime_type.compare(0, 6, "video/") == 0)) { |
215 RecordBypassedBytes(last_bypass_type_, | 248 RecordBypassedBytes(last_bypass_type_, |
216 DataReductionProxyUsageStats::AUDIO_VIDEO, | 249 DataReductionProxyUsageStats::AUDIO_VIDEO, |
217 content_length); | 250 content_length); |
218 return; | 251 return; |
219 } | 252 } |
220 | 253 |
221 RecordBypassedBytes(last_bypass_type_, | 254 RecordBypassedBytes(last_bypass_type_, |
222 DataReductionProxyUsageStats::TRIGGERING_REQUEST, | 255 DataReductionProxyUsageStats::TRIGGERING_REQUEST, |
223 content_length); | 256 content_length); |
224 triggering_request_ = false; | 257 triggering_request_ = false; |
225 return; | 258 return; |
226 } | 259 } |
227 | 260 |
228 if (last_bypass_type_ != BYPASS_EVENT_TYPE_MAX) { | 261 if (last_bypass_type_ != BYPASS_EVENT_TYPE_MAX) { |
229 RecordBypassedBytes(last_bypass_type_, | 262 RecordBypassedBytes(last_bypass_type_, |
230 DataReductionProxyUsageStats::BYPASSED_BYTES_TYPE_MAX, | 263 DataReductionProxyUsageStats::BYPASSED_BYTES_TYPE_MAX, |
231 content_length); | 264 content_length); |
232 return; | 265 return; |
233 } | 266 } |
234 | 267 |
235 if (data_reduction_proxy_params_->AreDataReductionProxiesBypassed(request, | 268 if (data_reduction_proxy_params_->AreDataReductionProxiesBypassed(*request, |
236 NULL)) { | 269 NULL)) { |
237 RecordBypassedBytes(last_bypass_type_, | 270 RecordBypassedBytes(last_bypass_type_, |
238 DataReductionProxyUsageStats::NETWORK_ERROR, | 271 DataReductionProxyUsageStats::NETWORK_ERROR, |
239 content_length); | 272 content_length); |
240 } | 273 } |
241 } | 274 } |
242 | 275 |
243 void DataReductionProxyUsageStats::RecordBypassEventHistograms( | 276 void DataReductionProxyUsageStats::RecordBypassEventHistograms( |
244 const net::ProxyServer& bypassed_proxy, | 277 const net::ProxyServer& bypassed_proxy, |
245 int net_error) const { | 278 int net_error) const { |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 "Status503HttpServiceUnavailable", | 404 "Status503HttpServiceUnavailable", |
372 content_length); | 405 content_length); |
373 break; | 406 break; |
374 default: | 407 default: |
375 break; | 408 break; |
376 } | 409 } |
377 break; | 410 break; |
378 } | 411 } |
379 } | 412 } |
380 | 413 |
| 414 void DataReductionProxyUsageStats::RecordMissingViaHeaderBytes( |
| 415 URLRequest* request) { |
| 416 // Responses that were served from cache should have been filtered out |
| 417 // already. |
| 418 DCHECK(!request->was_cached()); |
| 419 |
| 420 if (!data_reduction_proxy_params_->WasDataReductionProxyUsed(request, NULL) || |
| 421 HasDataReductionProxyViaHeader(request->response_headers(), NULL)) { |
| 422 // Only track requests that used the data reduction proxy and had responses |
| 423 // that were missing the data reduction proxy via header. |
| 424 return; |
| 425 } |
| 426 |
| 427 if (request->GetResponseCode() >= net::HTTP_BAD_REQUEST && |
| 428 request->GetResponseCode() < net::HTTP_INTERNAL_SERVER_ERROR) { |
| 429 // Track 4xx responses that are missing via headers separately. |
| 430 UMA_HISTOGRAM_COUNTS("DataReductionProxy.MissingViaHeader.Bytes.4xx", |
| 431 request->received_response_content_length()); |
| 432 } else { |
| 433 UMA_HISTOGRAM_COUNTS("DataReductionProxy.MissingViaHeader.Bytes.Other", |
| 434 request->received_response_content_length()); |
| 435 } |
| 436 } |
| 437 |
381 } // namespace data_reduction_proxy | 438 } // namespace data_reduction_proxy |
382 | 439 |
383 | 440 |
OLD | NEW |