Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 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 #include "chrome/browser/mod_pagespeed_metrics.h" | |
| 6 | |
| 7 #include <stdio.h> | |
| 8 | |
| 9 #include <string> | |
| 10 | |
| 11 #include "base/metrics/histogram.h" | |
| 12 #include "base/metrics/sparse_histogram.h" | |
| 13 #include "net/http/http_response_headers.h" | |
| 14 #include "url/gurl.h" | |
| 15 | |
| 16 namespace { | |
| 17 | |
| 18 const char kModPagespeedHeader[] = "X-Mod-Pagespeed"; | |
| 19 const char kPageSpeedHeader[] = "X-Page-Speed"; | |
| 20 | |
| 21 // For historical reasons, mod_pagespeed usage metrics are named with a | |
| 22 // prerender prefix. | |
| 23 const char kPagespeedServerHistogram[] = | |
| 24 "Prerender.PagespeedHeader.ServerCounts"; | |
| 25 const char kPagespeedVersionHistogram[] = | |
| 26 "Prerender.PagespeedHeader.VersionCounts"; | |
| 27 | |
| 28 enum PagespeedHeaderServerType { | |
| 29 PAGESPEED_TOTAL_RESPONSES = 0, | |
| 30 PAGESPEED_MOD_PAGESPEED_SERVER = 1, | |
| 31 PAGESPEED_NGX_PAGESPEED_SERVER = 2, | |
| 32 PAGESPEED_PAGESPEED_SERVICE_SERVER = 3, | |
| 33 PAGESPEED_UNKNOWN_SERVER = 4, | |
| 34 PAGESPEED_SERVER_MAXIMUM = 5 | |
| 35 }; | |
| 36 | |
| 37 // Parse the PageSpeed version number and encodes it in buckets 2 through 99: | |
| 38 // if it is in the format a.b.c.d-e the bucket will be 2 + 2 * (max(c, 10) - | |
| 39 // 10) + (d > 1 ? 1 : 0); otherwise the bucket is zero. | |
| 40 int GetXModPagespeedBucketFromVersion(const std::string& version) { | |
| 41 int a, b, c, d, e; | |
|
sky
2015/03/31 23:51:55
I realize you're just moving code, but since you'r
davidben
2015/04/08 21:07:46
Done.
| |
| 42 int num_parsed = | |
| 43 sscanf(version.c_str(), "%d.%d.%d.%d-%d", &a, &b, &c, &d, &e); | |
| 44 int output = 0; | |
| 45 if (num_parsed == 5) { | |
| 46 output = 2; | |
| 47 if (c > 10) | |
| 48 output += 2 * (c - 10); | |
| 49 if (d > 1) | |
| 50 output++; | |
| 51 if (output < 2 || output > 99) | |
| 52 output = 0; | |
| 53 } | |
| 54 return output; | |
| 55 } | |
| 56 | |
| 57 // Parse the X-Page-Speed header value and determine whether it is in the | |
| 58 // PageSpeed Service format, namely m_n_dc were m_n is a version number and dc | |
| 59 // is an encoded 2-character value. | |
| 60 bool IsPageSpeedServiceVersionNumber(const std::string& version) { | |
| 61 int a, b; | |
| 62 char c, d, e; // e is to detect EOL as we check that it /isn't/ converted. | |
| 63 int num_parsed = sscanf(version.c_str(), "%d_%d_%c%c%c", &a, &b, &c, &d, &e); | |
| 64 return (num_parsed == 4); | |
| 65 } | |
| 66 | |
| 67 } // namespace | |
| 68 | |
| 69 void RecordModPagespeedMetrics( | |
| 70 const content::ResourceType resource_type, | |
| 71 const GURL& request_url, | |
| 72 const net::HttpResponseHeaders* response_headers) { | |
| 73 if (resource_type != content::RESOURCE_TYPE_MAIN_FRAME || | |
| 74 !request_url.SchemeIsHTTPOrHTTPS()) { | |
| 75 return; | |
| 76 } | |
| 77 | |
| 78 // Bucket 0 counts every response seen. | |
| 79 UMA_HISTOGRAM_ENUMERATION(kPagespeedServerHistogram, | |
| 80 PAGESPEED_TOTAL_RESPONSES, | |
| 81 PAGESPEED_SERVER_MAXIMUM); | |
| 82 if (!response_headers) | |
| 83 return; | |
| 84 | |
| 85 void* iter = NULL; | |
|
sky
2015/03/31 23:51:55
nullptr
davidben
2015/04/08 21:07:45
Done.
| |
| 86 std::string name; | |
| 87 std::string value; | |
| 88 while (response_headers->EnumerateHeaderLines(&iter, &name, &value)) { | |
| 89 if (name == kModPagespeedHeader) { | |
| 90 // Bucket 1 counts occurrences of the X-Mod-Pagespeed header. | |
| 91 UMA_HISTOGRAM_ENUMERATION(kPagespeedServerHistogram, | |
| 92 PAGESPEED_MOD_PAGESPEED_SERVER, | |
| 93 PAGESPEED_SERVER_MAXIMUM); | |
| 94 if (!value.empty()) { | |
| 95 // If the header value is in the X-Mod-Pagespeed version number format | |
| 96 // then increment the appropriate bucket, otherwise increment bucket 1, | |
| 97 // which is the catch-all "unknown version number" bucket. | |
| 98 int bucket = GetXModPagespeedBucketFromVersion(value); | |
| 99 if (bucket > 0) { | |
| 100 UMA_HISTOGRAM_SPARSE_SLOWLY(kPagespeedVersionHistogram, bucket); | |
| 101 } else { | |
| 102 UMA_HISTOGRAM_SPARSE_SLOWLY(kPagespeedVersionHistogram, 1); | |
| 103 } | |
| 104 } | |
| 105 break; | |
| 106 } else if (name == kPageSpeedHeader) { | |
| 107 // X-Page-Speed header versions are either in the X-Mod-Pagespeed format, | |
| 108 // indicating an nginx installation, or they're in the PageSpeed Service | |
| 109 // format, indicating a PSS installation, or in some other format, | |
| 110 // indicating an unknown installation [possibly IISpeed]. | |
| 111 if (!value.empty()) { | |
| 112 int bucket = GetXModPagespeedBucketFromVersion(value); | |
| 113 if (bucket > 0) { | |
| 114 // Bucket 2 counts occurences of the X-Page-Speed header with a | |
| 115 // value in the X-Mod-Pagespeed version number format. We also | |
| 116 // count these responses in the version histogram. | |
| 117 UMA_HISTOGRAM_ENUMERATION(kPagespeedServerHistogram, | |
| 118 PAGESPEED_NGX_PAGESPEED_SERVER, | |
| 119 PAGESPEED_SERVER_MAXIMUM); | |
| 120 UMA_HISTOGRAM_SPARSE_SLOWLY(kPagespeedVersionHistogram, bucket); | |
| 121 } else if (IsPageSpeedServiceVersionNumber(value)) { | |
| 122 // Bucket 3 counts occurences of the X-Page-Speed header with a | |
| 123 // value in the PageSpeed Service version number format. | |
| 124 UMA_HISTOGRAM_ENUMERATION(kPagespeedServerHistogram, | |
| 125 PAGESPEED_PAGESPEED_SERVICE_SERVER, | |
| 126 PAGESPEED_SERVER_MAXIMUM); | |
| 127 } else { | |
| 128 // Bucket 4 counts occurences of all other values. | |
| 129 UMA_HISTOGRAM_ENUMERATION(kPagespeedServerHistogram, | |
| 130 PAGESPEED_UNKNOWN_SERVER, | |
| 131 PAGESPEED_SERVER_MAXIMUM); | |
| 132 } | |
| 133 } | |
| 134 break; | |
| 135 } | |
| 136 } | |
| 137 } | |
| OLD | NEW |