Commit ff3940cc authored by tburkard@chromium.org's avatar tburkard@chromium.org

Move prerender histograms out of prerender manager.

Add a separate histogram label for GWS based prerendering.
R=cbentzel@chromium.org, dominich@chromium.org
Review URL: http://codereview.chromium.org/7605020

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96227 0039d316-1c4b-4281-b951-d872f2087c98
parent 9c235f04
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/prerender/prerender_histograms.h"
#include <string>
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "chrome/browser/prerender/prerender_util.h"
namespace prerender {
namespace {
// Time window for which we will record windowed PLT's from the last
// observed link rel=prefetch tag.
const int kWindowDurationSeconds = 30;
std::string ComposeHistogramName(const std::string& prefix_type,
const std::string& name) {
if (prefix_type.empty())
return std::string("Prerender.") + name;
return std::string("Prerender.") + prefix_type + std::string("_") + name;
}
std::string GetHistogramName(Origin origin, uint8 experiment_id,
const std::string& name) {
switch (origin) {
case ORIGIN_OMNIBOX:
if (experiment_id != kNoExperiment)
return ComposeHistogramName("wash", name);
return ComposeHistogramName("omnibox", name);
case ORIGIN_LINK_REL_PRERENDER:
if (experiment_id != kNoExperiment)
return ComposeHistogramName("wash", name);
return ComposeHistogramName("", name);
case ORIGIN_GWS_PRERENDER:
if (experiment_id == kNoExperiment)
return ComposeHistogramName("gws", name);
return ComposeHistogramName("exp" + std::string(1, experiment_id + '0'),
name);
default:
NOTREACHED();
break;
};
// Dummy return value to make the compiler happy.
NOTREACHED();
return ComposeHistogramName("wash", name);
}
} // namespace
// Helper macros for experiment-based and origin-based histogram reporting.
#define PREFIXED_HISTOGRAM(histogram) \
PREFIXED_HISTOGRAM_INTERNAL(GetCurrentOrigin(), GetCurrentExperimentId(), \
IsOriginExperimentWash(), histogram)
#define PREFIXED_HISTOGRAM_ORIGIN_EXPERIMENT(origin, experiment, histogram) \
PREFIXED_HISTOGRAM_INTERNAL(origin, experiment, false, histogram)
#define PREFIXED_HISTOGRAM_INTERNAL(origin, experiment, wash, histogram) { \
static uint8 recording_experiment = kNoExperiment; \
if (recording_experiment == kNoExperiment && experiment != kNoExperiment) \
recording_experiment = experiment; \
if (wash) { \
histogram; \
} else if (experiment != kNoExperiment && \
(origin != ORIGIN_GWS_PRERENDER || \
experiment != recording_experiment)) { \
} else if (origin == ORIGIN_LINK_REL_PRERENDER) { \
histogram; \
} else if (origin == ORIGIN_OMNIBOX) { \
histogram; \
} else if (experiment != kNoExperiment) { \
histogram; \
} else { \
histogram; \
} \
}
PrerenderHistograms::PrerenderHistograms()
: last_experiment_id_(kNoExperiment),
last_origin_(ORIGIN_LINK_REL_PRERENDER),
origin_experiment_wash_(false) {
}
void PrerenderHistograms::RecordPrerender(Origin origin, const GURL& url) {
// Check if we are doing an experiment.
uint8 experiment = GetQueryStringBasedExperiment(url);
// We need to update last_experiment_id_, last_origin_, and
// origin_experiment_wash_.
if (!WithinWindow()) {
// If we are outside a window, this is a fresh start and we are fine,
// and there is no mix.
origin_experiment_wash_ = false;
} else {
// If we are inside the last window, there is a mish mash of origins
// and experiments if either there was a mish mash before, or the current
// experiment/origin does not match the previous one.
if (experiment != last_experiment_id_ || origin != last_origin_)
origin_experiment_wash_ = true;
}
last_origin_ = origin;
last_experiment_id_ = experiment;
// If we observe multiple tags within the 30 second window, we will still
// reset the window to begin at the most recent occurrence, so that we will
// always be in a window in the 30 seconds from each occurrence.
last_prerender_seen_time_ = GetCurrentTimeTicks();
}
base::TimeTicks PrerenderHistograms::GetCurrentTimeTicks() const {
return base::TimeTicks::Now();
}
// Helper macro for histograms.
#define RECORD_PLT(tag, perceived_page_load_time) { \
PREFIXED_HISTOGRAM( \
UMA_HISTOGRAM_CUSTOM_TIMES( \
base::FieldTrial::MakeName(GetDefaultHistogramName(tag), "Prefetch"), \
perceived_page_load_time, \
base::TimeDelta::FromMilliseconds(10), \
base::TimeDelta::FromSeconds(60), \
100)); \
}
void PrerenderHistograms::RecordPerceivedPageLoadTime(
base::TimeDelta perceived_page_load_time, bool was_prerender) const {
bool within_window = WithinWindow();
RECORD_PLT("PerceivedPLT", perceived_page_load_time);
if (within_window)
RECORD_PLT("PerceivedPLTWindowed", perceived_page_load_time);
if (was_prerender) {
RECORD_PLT("PerceivedPLTMatched", perceived_page_load_time);
} else {
if (within_window)
RECORD_PLT("PerceivedPLTWindowNotMatched", perceived_page_load_time);
}
}
bool PrerenderHistograms::WithinWindow() const {
if (last_prerender_seen_time_.is_null())
return false;
base::TimeDelta elapsed_time =
base::TimeTicks::Now() - last_prerender_seen_time_;
return elapsed_time <= base::TimeDelta::FromSeconds(kWindowDurationSeconds);
}
void PrerenderHistograms::RecordTimeUntilUsed(
base::TimeDelta time_until_used, base::TimeDelta max_age) const {
PREFIXED_HISTOGRAM(UMA_HISTOGRAM_CUSTOM_TIMES(
GetDefaultHistogramName("TimeUntilUsed"),
time_until_used,
base::TimeDelta::FromMilliseconds(10),
max_age,
50));
}
void PrerenderHistograms::RecordPerSessionCount(int count) const {
PREFIXED_HISTOGRAM(UMA_HISTOGRAM_COUNTS(
GetDefaultHistogramName("PrerendersPerSessionCount"), count));
}
void PrerenderHistograms::RecordTimeBetweenPrerenderRequests(
base::TimeDelta time) const {
PREFIXED_HISTOGRAM(UMA_HISTOGRAM_TIMES(
GetDefaultHistogramName("TimeBetweenPrerenderRequests"), time));
}
void PrerenderHistograms::RecordFinalStatus(Origin origin,
uint8 experiment_id,
FinalStatus final_status) const {
DCHECK(final_status != FINAL_STATUS_MAX);
PREFIXED_HISTOGRAM_ORIGIN_EXPERIMENT(origin, experiment_id,
UMA_HISTOGRAM_ENUMERATION(
GetHistogramName(origin, experiment_id, "FinalStatus"),
final_status,
FINAL_STATUS_MAX));
}
std::string PrerenderHistograms::GetDefaultHistogramName(
const std::string& name) const {
if (!WithinWindow())
return ComposeHistogramName("", name);
if (origin_experiment_wash_)
return ComposeHistogramName("wash", name);
return GetHistogramName(last_origin_, last_experiment_id_, name);
}
uint8 PrerenderHistograms::GetCurrentExperimentId() const {
if (!WithinWindow())
return kNoExperiment;
return last_experiment_id_;
}
Origin PrerenderHistograms::GetCurrentOrigin() const {
if (!WithinWindow())
return ORIGIN_LINK_REL_PRERENDER;
return last_origin_;
}
bool PrerenderHistograms::IsOriginExperimentWash() const {
if (!WithinWindow())
return false;
return origin_experiment_wash_;
}
} // namespace prerender
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_PRERENDER_PRERENDER_HISTOGRAMS_H_
#define CHROME_BROWSER_PRERENDER_PRERENDER_HISTOGRAMS_H_
#pragma once
#include <string>
#include "base/time.h"
#include "chrome/browser/prerender/prerender_final_status.h"
#include "chrome/browser/prerender/prerender_origin.h"
#include "googleurl/src/gurl.h"
namespace prerender {
// PrerenderHistograms is responsible for recording all prerender specific
// histograms for PrerenderManager. It keeps track of the type of prerender
// currently underway (based on the PrerenderOrigin of the most recent
// prerenders, and any experiments detected).
// PrerenderHistograms does not necessarily record all histograms related to
// prerendering, only the ones in the context of PrerenderManager.
class PrerenderHistograms {
public:
// Owned by a PrerenderManager object for the lifetime of the
// PrerenderManager.
PrerenderHistograms();
// Records the perceived page load time for a page - effectively the time from
// when the user navigates to a page to when it finishes loading. The actual
// load may have started prior to navigation due to prerender hints.
void RecordPerceivedPageLoadTime(base::TimeDelta perceived_page_load_time,
bool was_prerender) const;
// Records the time from when a page starts prerendering to when the user
// navigates to it. This must be called on the UI thread.
void RecordTimeUntilUsed(base::TimeDelta time_until_used,
base::TimeDelta max_age) const;
// Record a PerSessionCount data point.
void RecordPerSessionCount(int count) const;
// Record time between two prerender requests.
void RecordTimeBetweenPrerenderRequests(base::TimeDelta time) const;
// Record a final status of a prerendered page in a histogram.
void RecordFinalStatus(Origin origin,
uint8 experiment_id,
FinalStatus final_status) const;
// To be called when a new prerender is added.
void RecordPrerender(Origin origin, const GURL& url);
private:
base::TimeTicks GetCurrentTimeTicks() const;
// Returns whether the PrerenderManager is currently within the prerender
// window - effectively, up to 30 seconds after a prerender tag has been
// observed.
bool WithinWindow() const;
// Returns the histogram name for the current window.
std::string GetDefaultHistogramName(const std::string& name) const;
// Returns the current experiment.
uint8 GetCurrentExperimentId() const;
// Returns the current origin.
Origin GetCurrentOrigin() const;
// Returns whether or not there is currently an origin/experiment wash.
bool IsOriginExperimentWash() const;
// An integer indicating a Prerendering Experiment being currently conducted.
// (The last experiment ID seen).
uint8 last_experiment_id_;
// Origin of the last prerender seen.
Origin last_origin_;
// A boolean indicating that we have recently encountered a combination of
// different experiments and origins, making an attribution of PPLT's to
// experiments / origins impossible.
bool origin_experiment_wash_;
// The time when we last saw a prerender request coming from a renderer.
// This is used to record perceived PLT's for a certain amount of time
// from the point that we last saw a <link rel=prerender> tag.
base::TimeTicks last_prerender_seen_time_;
DISALLOW_COPY_AND_ASSIGN(PrerenderHistograms);
};
} // namespace prerender
#endif // CHROME_BROWSER_PRERENDER_PRERENDER_HISTOGRAMS_H_
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <list> #include <list>
#include <map> #include <map>
#include <string>
#include <vector> #include <vector>
#include "base/hash_tables.h" #include "base/hash_tables.h"
...@@ -20,6 +21,7 @@ ...@@ -20,6 +21,7 @@
#include "base/timer.h" #include "base/timer.h"
#include "chrome/browser/prerender/prerender_config.h" #include "chrome/browser/prerender/prerender_config.h"
#include "chrome/browser/prerender/prerender_contents.h" #include "chrome/browser/prerender/prerender_contents.h"
#include "chrome/browser/prerender/prerender_final_status.h"
#include "chrome/browser/prerender/prerender_origin.h" #include "chrome/browser/prerender/prerender_origin.h"
#include "googleurl/src/gurl.h" #include "googleurl/src/gurl.h"
...@@ -42,6 +44,7 @@ struct hash<TabContents*> { ...@@ -42,6 +44,7 @@ struct hash<TabContents*> {
namespace prerender { namespace prerender {
class PrerenderCondition; class PrerenderCondition;
class PrerenderHistograms;
class PrerenderHistory; class PrerenderHistory;
class PrerenderTracker; class PrerenderTracker;
...@@ -324,26 +327,6 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>, ...@@ -324,26 +327,6 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
// Used both on destruction, and when clearing the browing history. // Used both on destruction, and when clearing the browing history.
void DestroyAllContents(FinalStatus final_status); void DestroyAllContents(FinalStatus final_status);
// Records the time from when a page starts prerendering to when the user
// navigates to it. This must be called on the UI thread.
void RecordTimeUntilUsed(base::TimeDelta time_until_used);
// Composes a histogram name based on a histogram type.
std::string ComposeHistogramName(const std::string& prefix_type,
const std::string& name) const;
// Returns the histogram name for a given origin and experiment.
std::string GetHistogramName(Origin origin, uint8 experiment_id,
const std::string& name) const;
// Returns the histogram name for the current window.
std::string GetDefaultHistogramName(const std::string& name) const;
// Returns the current experiment.
uint8 GetCurrentExperimentId() const;
// Returns the current origin.
Origin GetCurrentOrigin() const;
// Returns whether or not there is currently an origin/experiment wash.
bool IsOriginExperimentWash() const;
// The configuration. // The configuration.
Config config_; Config config_;
...@@ -383,23 +366,6 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>, ...@@ -383,23 +366,6 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
static PrerenderManagerMode mode_; static PrerenderManagerMode mode_;
// An integer indicating a Prerendering Experiment being currently conducted.
// (The last experiment ID seen).
uint8 last_experiment_id_;
// Origin of the last prerender seen.
Origin last_origin_;
// A boolean indicating that we have recently encountered a combination of
// different experiments and origins, making an attribution of PPLT's to
// experiments / origins impossible.
bool origin_experiment_wash_;
// The time when we last saw a prerender request coming from a renderer.
// This is used to record perceived PLT's for a certain amount of time
// from the point that we last saw a <link rel=prerender> tag.
base::TimeTicks last_prerender_seen_time_;
// A count of how many prerenders we do per session. Initialized to 0 then // A count of how many prerenders we do per session. Initialized to 0 then
// incremented and emitted to a histogram on each successful prerender. // incremented and emitted to a histogram on each successful prerender.
static int prerenders_per_session_count_; static int prerenders_per_session_count_;
...@@ -422,6 +388,8 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>, ...@@ -422,6 +388,8 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
std::list<const PrerenderCondition*> prerender_conditions_; std::list<const PrerenderCondition*> prerender_conditions_;
scoped_ptr<PrerenderHistograms> histograms_;
DISALLOW_COPY_AND_ASSIGN(PrerenderManager); DISALLOW_COPY_AND_ASSIGN(PrerenderManager);
}; };
......
...@@ -14,11 +14,11 @@ namespace { ...@@ -14,11 +14,11 @@ namespace {
const char* kOriginNames[] = { const char* kOriginNames[] = {
"Link Rel Prerender", "Link Rel Prerender",
"Omnibox", "Omnibox",
"GWS Prerender",
"Max" "Max"
}; };
COMPILE_ASSERT(arraysize(kOriginNames) == ORIGIN_MAX + 1, COMPILE_ASSERT(arraysize(kOriginNames) == ORIGIN_MAX + 1,
PrerenderOrigin_name_count_mismatch); PrerenderOrigin_name_count_mismatch);
} }
const char* NameFromOrigin(Origin origin) { const char* NameFromOrigin(Origin origin) {
......
...@@ -12,6 +12,7 @@ namespace prerender { ...@@ -12,6 +12,7 @@ namespace prerender {
enum Origin { enum Origin {
ORIGIN_LINK_REL_PRERENDER = 0, ORIGIN_LINK_REL_PRERENDER = 0,
ORIGIN_OMNIBOX = 1, ORIGIN_OMNIBOX = 1,
ORIGIN_GWS_PRERENDER = 2,
ORIGIN_MAX ORIGIN_MAX
}; };
......
...@@ -1767,6 +1767,8 @@ ...@@ -1767,6 +1767,8 @@
'browser/prerender/prerender_field_trial.h', 'browser/prerender/prerender_field_trial.h',
'browser/prerender/prerender_final_status.cc', 'browser/prerender/prerender_final_status.cc',
'browser/prerender/prerender_final_status.h', 'browser/prerender/prerender_final_status.h',
'browser/prerender/prerender_histograms.cc',
'browser/prerender/prerender_histograms.h',
'browser/prerender/prerender_history.cc', 'browser/prerender/prerender_history.cc',
'browser/prerender/prerender_history.h', 'browser/prerender/prerender_history.h',
'browser/prerender/prerender_manager.cc', 'browser/prerender/prerender_manager.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment