OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 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/prerender/prerender_histograms.h" |
| 6 |
| 7 #include <string> |
| 8 |
| 9 #include "base/metrics/field_trial.h" |
| 10 #include "base/metrics/histogram.h" |
| 11 #include "chrome/browser/prerender/prerender_util.h" |
| 12 |
| 13 namespace prerender { |
| 14 |
| 15 namespace { |
| 16 |
| 17 // Time window for which we will record windowed PLT's from the last |
| 18 // observed link rel=prefetch tag. |
| 19 const int kWindowDurationSeconds = 30; |
| 20 |
| 21 std::string ComposeHistogramName(const std::string& prefix_type, |
| 22 const std::string& name) { |
| 23 if (prefix_type.empty()) |
| 24 return std::string("Prerender.") + name; |
| 25 return std::string("Prerender.") + prefix_type + std::string("_") + name; |
| 26 } |
| 27 |
| 28 std::string GetHistogramName(Origin origin, uint8 experiment_id, |
| 29 const std::string& name) { |
| 30 switch (origin) { |
| 31 case ORIGIN_OMNIBOX: |
| 32 if (experiment_id != kNoExperiment) |
| 33 return ComposeHistogramName("wash", name); |
| 34 return ComposeHistogramName("omnibox", name); |
| 35 case ORIGIN_LINK_REL_PRERENDER: |
| 36 if (experiment_id != kNoExperiment) |
| 37 return ComposeHistogramName("wash", name); |
| 38 return ComposeHistogramName("", name); |
| 39 case ORIGIN_GWS_PRERENDER: |
| 40 if (experiment_id == kNoExperiment) |
| 41 return ComposeHistogramName("gws", name); |
| 42 return ComposeHistogramName("exp" + std::string(1, experiment_id + '0'), |
| 43 name); |
| 44 default: |
| 45 NOTREACHED(); |
| 46 break; |
| 47 }; |
| 48 |
| 49 // Dummy return value to make the compiler happy. |
| 50 NOTREACHED(); |
| 51 return ComposeHistogramName("wash", name); |
| 52 } |
| 53 |
| 54 } // namespace |
| 55 |
| 56 // Helper macros for experiment-based and origin-based histogram reporting. |
| 57 #define PREFIXED_HISTOGRAM(histogram) \ |
| 58 PREFIXED_HISTOGRAM_INTERNAL(GetCurrentOrigin(), GetCurrentExperimentId(), \ |
| 59 IsOriginExperimentWash(), histogram) |
| 60 |
| 61 #define PREFIXED_HISTOGRAM_ORIGIN_EXPERIMENT(origin, experiment, histogram) \ |
| 62 PREFIXED_HISTOGRAM_INTERNAL(origin, experiment, false, histogram) |
| 63 |
| 64 #define PREFIXED_HISTOGRAM_INTERNAL(origin, experiment, wash, histogram) { \ |
| 65 static uint8 recording_experiment = kNoExperiment; \ |
| 66 if (recording_experiment == kNoExperiment && experiment != kNoExperiment) \ |
| 67 recording_experiment = experiment; \ |
| 68 if (wash) { \ |
| 69 histogram; \ |
| 70 } else if (experiment != kNoExperiment && \ |
| 71 (origin != ORIGIN_GWS_PRERENDER || \ |
| 72 experiment != recording_experiment)) { \ |
| 73 } else if (origin == ORIGIN_LINK_REL_PRERENDER) { \ |
| 74 histogram; \ |
| 75 } else if (origin == ORIGIN_OMNIBOX) { \ |
| 76 histogram; \ |
| 77 } else if (experiment != kNoExperiment) { \ |
| 78 histogram; \ |
| 79 } else { \ |
| 80 histogram; \ |
| 81 } \ |
| 82 } |
| 83 |
| 84 PrerenderHistograms::PrerenderHistograms() |
| 85 : last_experiment_id_(kNoExperiment), |
| 86 last_origin_(ORIGIN_LINK_REL_PRERENDER), |
| 87 origin_experiment_wash_(false) { |
| 88 } |
| 89 |
| 90 void PrerenderHistograms::RecordPrerender(Origin origin, const GURL& url) { |
| 91 // Check if we are doing an experiment. |
| 92 uint8 experiment = GetQueryStringBasedExperiment(url); |
| 93 |
| 94 // We need to update last_experiment_id_, last_origin_, and |
| 95 // origin_experiment_wash_. |
| 96 if (!WithinWindow()) { |
| 97 // If we are outside a window, this is a fresh start and we are fine, |
| 98 // and there is no mix. |
| 99 origin_experiment_wash_ = false; |
| 100 } else { |
| 101 // If we are inside the last window, there is a mish mash of origins |
| 102 // and experiments if either there was a mish mash before, or the current |
| 103 // experiment/origin does not match the previous one. |
| 104 if (experiment != last_experiment_id_ || origin != last_origin_) |
| 105 origin_experiment_wash_ = true; |
| 106 } |
| 107 |
| 108 last_origin_ = origin; |
| 109 last_experiment_id_ = experiment; |
| 110 |
| 111 // If we observe multiple tags within the 30 second window, we will still |
| 112 // reset the window to begin at the most recent occurrence, so that we will |
| 113 // always be in a window in the 30 seconds from each occurrence. |
| 114 last_prerender_seen_time_ = GetCurrentTimeTicks(); |
| 115 } |
| 116 |
| 117 base::TimeTicks PrerenderHistograms::GetCurrentTimeTicks() const { |
| 118 return base::TimeTicks::Now(); |
| 119 } |
| 120 |
| 121 // Helper macro for histograms. |
| 122 #define RECORD_PLT(tag, perceived_page_load_time) { \ |
| 123 PREFIXED_HISTOGRAM( \ |
| 124 UMA_HISTOGRAM_CUSTOM_TIMES( \ |
| 125 base::FieldTrial::MakeName(GetDefaultHistogramName(tag), "Prefetch"), \ |
| 126 perceived_page_load_time, \ |
| 127 base::TimeDelta::FromMilliseconds(10), \ |
| 128 base::TimeDelta::FromSeconds(60), \ |
| 129 100)); \ |
| 130 } |
| 131 |
| 132 void PrerenderHistograms::RecordPerceivedPageLoadTime( |
| 133 base::TimeDelta perceived_page_load_time, bool was_prerender) const { |
| 134 bool within_window = WithinWindow(); |
| 135 RECORD_PLT("PerceivedPLT", perceived_page_load_time); |
| 136 if (within_window) |
| 137 RECORD_PLT("PerceivedPLTWindowed", perceived_page_load_time); |
| 138 if (was_prerender) { |
| 139 RECORD_PLT("PerceivedPLTMatched", perceived_page_load_time); |
| 140 } else { |
| 141 if (within_window) |
| 142 RECORD_PLT("PerceivedPLTWindowNotMatched", perceived_page_load_time); |
| 143 } |
| 144 } |
| 145 |
| 146 bool PrerenderHistograms::WithinWindow() const { |
| 147 if (last_prerender_seen_time_.is_null()) |
| 148 return false; |
| 149 base::TimeDelta elapsed_time = |
| 150 base::TimeTicks::Now() - last_prerender_seen_time_; |
| 151 return elapsed_time <= base::TimeDelta::FromSeconds(kWindowDurationSeconds); |
| 152 } |
| 153 |
| 154 |
| 155 void PrerenderHistograms::RecordTimeUntilUsed( |
| 156 base::TimeDelta time_until_used, base::TimeDelta max_age) const { |
| 157 PREFIXED_HISTOGRAM(UMA_HISTOGRAM_CUSTOM_TIMES( |
| 158 GetDefaultHistogramName("TimeUntilUsed"), |
| 159 time_until_used, |
| 160 base::TimeDelta::FromMilliseconds(10), |
| 161 max_age, |
| 162 50)); |
| 163 } |
| 164 |
| 165 void PrerenderHistograms::RecordPerSessionCount(int count) const { |
| 166 PREFIXED_HISTOGRAM(UMA_HISTOGRAM_COUNTS( |
| 167 GetDefaultHistogramName("PrerendersPerSessionCount"), count)); |
| 168 } |
| 169 |
| 170 void PrerenderHistograms::RecordTimeBetweenPrerenderRequests( |
| 171 base::TimeDelta time) const { |
| 172 PREFIXED_HISTOGRAM(UMA_HISTOGRAM_TIMES( |
| 173 GetDefaultHistogramName("TimeBetweenPrerenderRequests"), time)); |
| 174 } |
| 175 |
| 176 void PrerenderHistograms::RecordFinalStatus(Origin origin, |
| 177 uint8 experiment_id, |
| 178 FinalStatus final_status) const { |
| 179 DCHECK(final_status != FINAL_STATUS_MAX); |
| 180 PREFIXED_HISTOGRAM_ORIGIN_EXPERIMENT(origin, experiment_id, |
| 181 UMA_HISTOGRAM_ENUMERATION( |
| 182 GetHistogramName(origin, experiment_id, "FinalStatus"), |
| 183 final_status, |
| 184 FINAL_STATUS_MAX)); |
| 185 } |
| 186 |
| 187 std::string PrerenderHistograms::GetDefaultHistogramName( |
| 188 const std::string& name) const { |
| 189 if (!WithinWindow()) |
| 190 return ComposeHistogramName("", name); |
| 191 if (origin_experiment_wash_) |
| 192 return ComposeHistogramName("wash", name); |
| 193 return GetHistogramName(last_origin_, last_experiment_id_, name); |
| 194 } |
| 195 |
| 196 uint8 PrerenderHistograms::GetCurrentExperimentId() const { |
| 197 if (!WithinWindow()) |
| 198 return kNoExperiment; |
| 199 return last_experiment_id_; |
| 200 } |
| 201 |
| 202 Origin PrerenderHistograms::GetCurrentOrigin() const { |
| 203 if (!WithinWindow()) |
| 204 return ORIGIN_LINK_REL_PRERENDER; |
| 205 return last_origin_; |
| 206 } |
| 207 |
| 208 bool PrerenderHistograms::IsOriginExperimentWash() const { |
| 209 if (!WithinWindow()) |
| 210 return false; |
| 211 return origin_experiment_wash_; |
| 212 } |
| 213 |
| 214 } // namespace prerender |
OLD | NEW |