diff options
author | halliwell <halliwell@chromium.org> | 2014-12-03 16:27:50 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-12-04 00:28:32 +0000 |
commit | 9cca2aca0a682dcb8acde4650d8f098c79eb0552 (patch) | |
tree | e9de048e12f2b05a0c172c2ebcc3e52479ea3ee9 /chromecast/base | |
parent | 2cd75c128306f0975c904574750c12c6cf8ea367 (diff) | |
download | chromium_src-9cca2aca0a682dcb8acde4650d8f098c79eb0552.zip chromium_src-9cca2aca0a682dcb8acde4650d8f098c79eb0552.tar.gz chromium_src-9cca2aca0a682dcb8acde4650d8f098c79eb0552.tar.bz2 |
Added new GroupedHistogram class which can intercept Add() calls and generates
new metrics of the form <metric-name>.<app-name>.
Chromecast startup code registers a specific set of histograms for grouped
collection.
Review URL: https://codereview.chromium.org/751603003
Cr-Commit-Position: refs/heads/master@{#306731}
Diffstat (limited to 'chromecast/base')
-rw-r--r-- | chromecast/base/metrics/cast_metrics_helper.cc | 3 | ||||
-rw-r--r-- | chromecast/base/metrics/grouped_histogram.cc | 181 | ||||
-rw-r--r-- | chromecast/base/metrics/grouped_histogram.h | 25 |
3 files changed, 209 insertions, 0 deletions
diff --git a/chromecast/base/metrics/cast_metrics_helper.cc b/chromecast/base/metrics/cast_metrics_helper.cc index b51439f..2a94019 100644 --- a/chromecast/base/metrics/cast_metrics_helper.cc +++ b/chromecast/base/metrics/cast_metrics_helper.cc @@ -11,6 +11,7 @@ #include "base/metrics/histogram.h" #include "base/metrics/user_metrics.h" #include "chromecast/base/metrics/cast_histograms.h" +#include "chromecast/base/metrics/grouped_histogram.h" namespace chromecast { namespace metrics { @@ -67,6 +68,8 @@ void CastMetricsHelper::TagAppStart(const std::string& arg_app_name) { app_name_ = arg_app_name; app_start_time_ = base::TimeTicks::Now(); new_startup_time_ = true; + + TagAppStartForGroupedHistograms(app_name_); } void CastMetricsHelper::LogMediaPlay() { diff --git a/chromecast/base/metrics/grouped_histogram.cc b/chromecast/base/metrics/grouped_histogram.cc new file mode 100644 index 0000000..8318850 --- /dev/null +++ b/chromecast/base/metrics/grouped_histogram.cc @@ -0,0 +1,181 @@ +// Copyright 2014 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 "chromecast/base/metrics/grouped_histogram.h" + +#include "base/lazy_instance.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/metrics/histogram.h" +#include "base/metrics/statistics_recorder.h" +#include "base/strings/stringprintf.h" +#include "base/synchronization/lock.h" +#include "base/time/time.h" + +namespace chromecast { +namespace metrics { + +namespace { + +const char kAppNameErrorNoApp[] = "ERROR_NO_APP_REGISTERED"; + +// Current app name guarded by lock. +struct CurrentAppNameWithLock { + base::Lock lock; + std::string app_name; +}; + +base::LazyInstance<CurrentAppNameWithLock> g_current_app = + LAZY_INSTANCE_INITIALIZER; + +std::string GetAppName() { + base::AutoLock lock(g_current_app.Get().lock); + const std::string& app_name = g_current_app.Get().app_name; + return app_name.empty() ? kAppNameErrorNoApp : app_name; +} + +struct HistogramArgs { + const char* name; + int minimum; + int maximum; + size_t bucket_count; +}; + +// List of metrics to collect using a GroupedHistogram. +// +// When adding more Histograms to this list, find the source of the +// Histogram and look for the construction arguments it uses to add it in. +const HistogramArgs kHistogramsToGroup[] = { + { + "DNS.TotalTime", + 1, + 1000 * 60 * 60, + 100, + }, + { + "Net.DNS_Resolution_And_TCP_Connection_Latency2", + 1, + 1000 * 60 * 10, + 100, + }, + { + "Net.SSL_Connection_Latency2", + 1, + 1000 * 60, + 100, + }, + { + "Net.TCP_Connection_Latency", + 1, + 1000 * 60 * 10, + 100, + }, + { + "Net.HttpJob.TotalTime", + 1, + 1000 * 10, + 50, + }, +}; + +// This class is used to override a Histogram to generate per-app metrics. +// It intercepts calls to Add() for a given metric and generates new metrics +// of the form "<metric-name>.<app-name>". +class GroupedHistogram : public base::Histogram { + public: + GroupedHistogram(const std::string& metric_to_override, + Sample minimum, + Sample maximum, + const base::BucketRanges* ranges) + : Histogram(metric_to_override, minimum, maximum, ranges), + metric_to_group_(metric_to_override), + minimum_(minimum), + maximum_(maximum), + bucket_count_(ranges->bucket_count()) { + } + + ~GroupedHistogram() override { + } + + // base::Histogram implementation: + void Add(Sample value) override { + Histogram::Add(value); + std::string name(base::StringPrintf("%s.%s", + histogram_name().c_str(), + GetAppName().c_str())); + HistogramBase* grouped_histogram = + base::Histogram::FactoryGet(name, + minimum_, + maximum_, + bucket_count_, + flags()); + DCHECK(grouped_histogram); + grouped_histogram->Add(value); + } + + private: + // Saved construction arguments for reconstructing the Histogram later (with + // a suffixed app name). + std::string metric_to_group_; + Sample minimum_; + Sample maximum_; + size_t bucket_count_; + + DISALLOW_COPY_AND_ASSIGN(GroupedHistogram); +}; + +// Registers a GroupedHistogram with StatisticsRecorder. Must be called +// before any Histogram of the same name has been used. +// It acts similarly to Histogram::FactoryGet but checks that +// the histogram is being newly created and does not already exist. +void PreregisterHistogram(const std::string& name, + GroupedHistogram::Sample minimum, + GroupedHistogram::Sample maximum, + size_t bucket_count, + int32 flags) { + DCHECK(base::StatisticsRecorder::IsActive()); + DCHECK(base::Histogram::InspectConstructionArguments( + name, &minimum, &maximum, &bucket_count)); + DCHECK(!base::StatisticsRecorder::FindHistogram(name)) + << "Failed to preregister " << name << ", Histogram already exists."; + + // To avoid racy destruction at shutdown, the following will be leaked. + base::BucketRanges* ranges = new base::BucketRanges(bucket_count + 1); + base::Histogram::InitializeBucketRanges(minimum, maximum, ranges); + const base::BucketRanges* registered_ranges = + base::StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); + + GroupedHistogram* tentative_histogram = + new GroupedHistogram(name, minimum, maximum, registered_ranges); + + tentative_histogram->SetFlags(flags); + base::HistogramBase* histogram = + base::StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); + + DCHECK_EQ(histogram, tentative_histogram); + DCHECK_EQ(base::HISTOGRAM, histogram->GetHistogramType()); + DCHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count)); +} + +} // namespace + +void PreregisterAllGroupedHistograms() { + base::StatisticsRecorder::Initialize(); + for (size_t i = 0; i < arraysize(kHistogramsToGroup); ++i) { + PreregisterHistogram( + kHistogramsToGroup[i].name, + kHistogramsToGroup[i].minimum, + kHistogramsToGroup[i].maximum, + kHistogramsToGroup[i].bucket_count, + base::HistogramBase::kUmaTargetedHistogramFlag); + } +} + +void TagAppStartForGroupedHistograms(const std::string& app_name) { + base::AutoLock lock(g_current_app.Get().lock); + g_current_app.Get().app_name = app_name; +} + +} // namespace metrics +} // namespace chromecast diff --git a/chromecast/base/metrics/grouped_histogram.h b/chromecast/base/metrics/grouped_histogram.h new file mode 100644 index 0000000..b5202e6 --- /dev/null +++ b/chromecast/base/metrics/grouped_histogram.h @@ -0,0 +1,25 @@ +// Copyright 2014 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 CHROMECAST_BASE_METRICS_GROUPED_HISTOGRAM_H_ +#define CHROMECAST_BASE_METRICS_GROUPED_HISTOGRAM_H_ + +#include <string> + +namespace chromecast { +namespace metrics { + +// Registers a predefined list of histograms to be collected per-app. Must be +// called before any histograms of the same name are used or registration will +// fail. +void PreregisterAllGroupedHistograms(); + +// Sets the current app name to be used for subsequent grouped histogram +// samples (a new metric is generated with the app name as a suffix). +void TagAppStartForGroupedHistograms(const std::string& app_name); + +} // namespace metrics +} // namespace chromecast + +#endif // CHROMECAST_BASE_METRICS_GROUPED_HISTOGRAM_H_ |