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.
5 #include "chrome/browser/mod_pagespeed/mod_pagespeed_metrics.h"
11 #include "base/metrics/histogram.h"
12 #include "base/metrics/sparse_histogram.h"
13 #include "net/http/http_response_headers.h"
16 namespace mod_pagespeed
{
20 const char kModPagespeedHeader
[] = "X-Mod-Pagespeed";
21 const char kPageSpeedHeader
[] = "X-Page-Speed";
23 // For historical reasons, mod_pagespeed usage metrics are named with a
25 const char kPagespeedServerHistogram
[] =
26 "Prerender.PagespeedHeader.ServerCounts";
27 const char kPagespeedVersionHistogram
[] =
28 "Prerender.PagespeedHeader.VersionCounts";
30 enum PagespeedHeaderServerType
{
31 PAGESPEED_TOTAL_RESPONSES
= 0,
32 PAGESPEED_MOD_PAGESPEED_SERVER
= 1,
33 PAGESPEED_NGX_PAGESPEED_SERVER
= 2,
34 PAGESPEED_PAGESPEED_SERVICE_SERVER
= 3,
35 PAGESPEED_UNKNOWN_SERVER
= 4,
36 PAGESPEED_SERVER_MAXIMUM
= 5
39 // Parse the PageSpeed version number and encodes it in buckets 2 through 99: if
40 // it is in the format MAJOR.MINOR.BRANCH.POINT-COMMIT the bucket will be 2 + 2
41 // * (max(BRANCH, 10) - 10) + (POINT > 1 ? 1 : 0); otherwise the bucket is
43 int GetXModPagespeedBucketFromVersion(const std::string
& version
) {
44 int unused_major
, unused_minor
, branch
, point
, unused_commit
;
45 int num_parsed
= sscanf(version
.c_str(), "%d.%d.%d.%d-%d", &unused_major
,
46 &unused_minor
, &branch
, &point
, &unused_commit
);
48 if (num_parsed
== 5) {
51 output
+= 2 * (branch
- 10);
54 if (output
< 2 || output
> 99)
60 // Parse the X-Page-Speed header value and determine whether it is in the
61 // PageSpeed Service format, namely MAJOR_MINOR_AB were MAJOR_MINOR is a version
62 // number and AB is an encoded 2-character value.
63 bool IsPageSpeedServiceVersionNumber(const std::string
& version
) {
65 // is_eol is to detect EOL as we check that it /isn't/ converted.
68 sscanf(version
.c_str(), "%d_%d_%c%c%c", &major
, &minor
, &a
, &b
, &is_eol
);
69 return (num_parsed
== 4);
74 void RecordMetrics(const content::ResourceType resource_type
,
75 const GURL
& request_url
,
76 const net::HttpResponseHeaders
* response_headers
) {
77 if (resource_type
!= content::RESOURCE_TYPE_MAIN_FRAME
||
78 !request_url
.SchemeIsHTTPOrHTTPS()) {
82 // Bucket 0 counts every response seen.
83 UMA_HISTOGRAM_ENUMERATION(kPagespeedServerHistogram
,
84 PAGESPEED_TOTAL_RESPONSES
,
85 PAGESPEED_SERVER_MAXIMUM
);
86 if (!response_headers
)
92 while (response_headers
->EnumerateHeaderLines(&iter
, &name
, &value
)) {
93 if (name
== kModPagespeedHeader
) {
94 // Bucket 1 counts occurrences of the X-Mod-Pagespeed header.
95 UMA_HISTOGRAM_ENUMERATION(kPagespeedServerHistogram
,
96 PAGESPEED_MOD_PAGESPEED_SERVER
,
97 PAGESPEED_SERVER_MAXIMUM
);
99 // If the header value is in the X-Mod-Pagespeed version number format
100 // then increment the appropriate bucket, otherwise increment bucket 1,
101 // which is the catch-all "unknown version number" bucket.
102 int bucket
= GetXModPagespeedBucketFromVersion(value
);
104 UMA_HISTOGRAM_SPARSE_SLOWLY(kPagespeedVersionHistogram
, bucket
);
106 UMA_HISTOGRAM_SPARSE_SLOWLY(kPagespeedVersionHistogram
, 1);
110 } else if (name
== kPageSpeedHeader
) {
111 // X-Page-Speed header versions are either in the X-Mod-Pagespeed format,
112 // indicating an nginx installation, or they're in the PageSpeed Service
113 // format, indicating a PSS installation, or in some other format,
114 // indicating an unknown installation [possibly IISpeed].
115 if (!value
.empty()) {
116 int bucket
= GetXModPagespeedBucketFromVersion(value
);
118 // Bucket 2 counts occurences of the X-Page-Speed header with a
119 // value in the X-Mod-Pagespeed version number format. We also
120 // count these responses in the version histogram.
121 UMA_HISTOGRAM_ENUMERATION(kPagespeedServerHistogram
,
122 PAGESPEED_NGX_PAGESPEED_SERVER
,
123 PAGESPEED_SERVER_MAXIMUM
);
124 UMA_HISTOGRAM_SPARSE_SLOWLY(kPagespeedVersionHistogram
, bucket
);
125 } else if (IsPageSpeedServiceVersionNumber(value
)) {
126 // Bucket 3 counts occurences of the X-Page-Speed header with a
127 // value in the PageSpeed Service version number format.
128 UMA_HISTOGRAM_ENUMERATION(kPagespeedServerHistogram
,
129 PAGESPEED_PAGESPEED_SERVICE_SERVER
,
130 PAGESPEED_SERVER_MAXIMUM
);
132 // Bucket 4 counts occurences of all other values.
133 UMA_HISTOGRAM_ENUMERATION(kPagespeedServerHistogram
,
134 PAGESPEED_UNKNOWN_SERVER
,
135 PAGESPEED_SERVER_MAXIMUM
);
143 } // namespace mod_pagespeed