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 |