summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/base.gypi2
-rw-r--r--base/message_loop.cc1
-rw-r--r--base/metrics/histogram.cc276
-rw-r--r--base/metrics/histogram.h85
-rw-r--r--base/metrics/histogram_snapshot_manager.cc2
-rw-r--r--base/metrics/histogram_unittest.cc4
-rw-r--r--base/metrics/statistics_recorder.cc285
-rw-r--r--base/metrics/statistics_recorder.h105
-rw-r--r--chrome/browser/chrome_browser_application_mac_unittest.mm3
-rw-r--r--chrome/browser/extensions/api/metrics/metrics_apitest.cc1
-rw-r--r--chrome/browser/metrics/metrics_service.cc1
-rw-r--r--chrome/browser/net/http_pipelining_compatibility_client_unittest.cc1
-rw-r--r--chrome/browser/protector/default_search_provider_change_browsertest.cc1
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc3
-rw-r--r--chrome/browser/ui/startup/startup_browser_creator_impl.cc1
-rw-r--r--chrome/browser/ui/webui/about_ui.cc1
-rw-r--r--chrome/renderer/chrome_render_process_observer.cc1
-rw-r--r--chrome_frame/metrics_service.cc1
-rw-r--r--content/browser/browser_main_runner.cc1
-rw-r--r--content/browser/histogram_internals_request_job.cc1
-rw-r--r--content/common/child_histogram_message_filter.cc1
-rw-r--r--content/renderer/renderer_main.cc1
-rw-r--r--net/base/run_all_unittests.cc2
-rw-r--r--net/curvecp/curvecp_transfer_unittest.cc4
-rw-r--r--net/disk_cache/stats_histogram.cc3
-rw-r--r--net/socket_stream/socket_stream_metrics_unittest.cc3
-rw-r--r--net/url_request/url_request_throttler_unittest.cc1
27 files changed, 421 insertions, 370 deletions
diff --git a/base/base.gypi b/base/base.gypi
index 6971953..92d66fa 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -239,6 +239,8 @@
'metrics/histogram_flattener.h',
'metrics/histogram_snapshot_manager.cc',
'metrics/histogram_snapshot_manager.h',
+ 'metrics/statistics_recorder.cc',
+ 'metrics/statistics_recorder.h',
'metrics/stats_counters.cc',
'metrics/stats_counters.h',
'metrics/stats_table.cc',
diff --git a/base/message_loop.cc b/base/message_loop.cc
index f3bb4bb..6b994bc 100644
--- a/base/message_loop.cc
+++ b/base/message_loop.cc
@@ -16,6 +16,7 @@
#include "base/message_loop_proxy_impl.h"
#include "base/message_pump_default.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/statistics_recorder.h"
#include "base/run_loop.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "base/thread_task_runner_handle.h"
diff --git a/base/metrics/histogram.cc b/base/metrics/histogram.cc
index 923ac9c..e176e8f 100644
--- a/base/metrics/histogram.cc
+++ b/base/metrics/histogram.cc
@@ -14,8 +14,8 @@
#include <algorithm>
#include <string>
-#include "base/debug/leak_annotations.h"
#include "base/logging.h"
+#include "base/metrics/statistics_recorder.h"
#include "base/pickle.h"
#include "base/stringprintf.h"
#include "base/synchronization/lock.h"
@@ -74,13 +74,6 @@ typedef Histogram::Count Count;
// static
const size_t Histogram::kBucketCount_MAX = 16384u;
-// Collect the number of histograms created.
-static uint32 number_of_histograms_ = 0;
-// Collect the number of vectors saved because of caching ranges.
-static uint32 number_of_vectors_saved_ = 0;
-// Collect the number of ranges_ elements saved because of caching ranges.
-static size_t saved_ranges_size_ = 0;
-
Histogram* Histogram::FactoryGet(const std::string& name,
Sample minimum,
Sample maximum,
@@ -1037,265 +1030,6 @@ double CustomHistogram::GetBucketSize(Count current, size_t i) const {
return 1;
}
-//------------------------------------------------------------------------------
-// The next section handles global (central) support for all histograms, as well
-// as startup/teardown of this service.
-//------------------------------------------------------------------------------
-
-// This singleton instance should be started during the single threaded portion
-// of main(), and hence it is not thread safe. It initializes globals to
-// provide support for all future calls.
-StatisticsRecorder::StatisticsRecorder() {
- DCHECK(!histograms_);
- if (lock_ == NULL) {
- // This will leak on purpose. It's the only way to make sure we won't race
- // against the static uninitialization of the module while one of our
- // static methods relying on the lock get called at an inappropriate time
- // during the termination phase. Since it's a static data member, we will
- // leak one per process, which would be similar to the instance allocated
- // during static initialization and released only on process termination.
- lock_ = new base::Lock;
- }
- base::AutoLock auto_lock(*lock_);
- histograms_ = new HistogramMap;
- ranges_ = new RangesMap;
-}
-
-StatisticsRecorder::~StatisticsRecorder() {
- DCHECK(histograms_ && lock_);
-
- if (dump_on_exit_) {
- std::string output;
- WriteGraph("", &output);
- DLOG(INFO) << output;
- }
- // Clean up.
- HistogramMap* histograms = NULL;
- {
- base::AutoLock auto_lock(*lock_);
- histograms = histograms_;
- histograms_ = NULL;
- }
- RangesMap* ranges = NULL;
- {
- base::AutoLock auto_lock(*lock_);
- ranges = ranges_;
- ranges_ = NULL;
- }
- // We are going to leak the histograms and the ranges.
- delete histograms;
- delete ranges;
- // We don't delete lock_ on purpose to avoid having to properly protect
- // against it going away after we checked for NULL in the static methods.
-}
-
-// static
-bool StatisticsRecorder::IsActive() {
- if (lock_ == NULL)
- return false;
- base::AutoLock auto_lock(*lock_);
- return NULL != histograms_;
-}
-
-Histogram* StatisticsRecorder::RegisterOrDeleteDuplicate(Histogram* histogram) {
- // As per crbug.com/79322 the histograms are intentionally leaked, so we need
- // to annotate them. Because ANNOTATE_LEAKING_OBJECT_PTR may be used only once
- // for an object, the duplicates should not be annotated.
- // Callers are responsible for not calling RegisterOrDeleteDuplicate(ptr)
- // twice if (lock_ == NULL) || (!histograms_).
- DCHECK(histogram->HasValidRangeChecksum());
- if (lock_ == NULL) {
- ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322
- return histogram;
- }
- base::AutoLock auto_lock(*lock_);
- if (!histograms_) {
- ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322
- return histogram;
- }
- const std::string name = histogram->histogram_name();
- HistogramMap::iterator it = histograms_->find(name);
- // Avoid overwriting a previous registration.
- if (histograms_->end() == it) {
- (*histograms_)[name] = histogram;
- ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322
- RegisterOrDeleteDuplicateRanges(histogram);
- ++number_of_histograms_;
- } else {
- delete histogram; // We already have one by this name.
- histogram = it->second;
- }
- return histogram;
-}
-
-// static
-void StatisticsRecorder::RegisterOrDeleteDuplicateRanges(Histogram* histogram) {
- DCHECK(histogram);
- CachedRanges* histogram_ranges = histogram->cached_ranges();
- DCHECK(histogram_ranges);
- uint32 checksum = histogram->range_checksum();
- histogram_ranges->SetRangeChecksum(checksum);
-
- RangesMap::iterator ranges_it = ranges_->find(checksum);
- if (ranges_->end() == ranges_it) {
- // Register the new CachedRanges.
- std::list<CachedRanges*>* checksum_matching_list(
- new std::list<CachedRanges*>());
- checksum_matching_list->push_front(histogram_ranges);
- (*ranges_)[checksum] = checksum_matching_list;
- return;
- }
-
- // Use the registered CachedRanges if the registered CachedRanges has same
- // ranges_ as |histogram|'s CachedRanges.
- std::list<CachedRanges*>* checksum_matching_list = ranges_it->second;
- std::list<CachedRanges*>::iterator checksum_matching_list_it;
- for (checksum_matching_list_it = checksum_matching_list->begin();
- checksum_matching_list_it != checksum_matching_list->end();
- ++checksum_matching_list_it) {
- CachedRanges* existing_histogram_ranges = *checksum_matching_list_it;
- DCHECK(existing_histogram_ranges);
- if (existing_histogram_ranges->Equals(histogram_ranges)) {
- histogram->set_cached_ranges(existing_histogram_ranges);
- ++number_of_vectors_saved_;
- saved_ranges_size_ += histogram_ranges->size();
- delete histogram_ranges;
- return;
- }
- }
-
- // We haven't found a CachedRanges which has the same ranges. Register the
- // new CachedRanges.
- DCHECK(checksum_matching_list_it == checksum_matching_list->end());
- checksum_matching_list->push_front(histogram_ranges);
-}
-
-// static
-void StatisticsRecorder::CollectHistogramStats(const std::string& suffix) {
- static int uma_upload_attempt = 0;
- ++uma_upload_attempt;
- if (uma_upload_attempt == 1) {
- UMA_HISTOGRAM_COUNTS_10000(
- "Histogram.SharedRange.Count.FirstUpload." + suffix,
- number_of_histograms_);
- UMA_HISTOGRAM_COUNTS_10000(
- "Histogram.SharedRange.RangesSaved.FirstUpload." + suffix,
- number_of_vectors_saved_);
- UMA_HISTOGRAM_COUNTS(
- "Histogram.SharedRange.ElementsSaved.FirstUpload." + suffix,
- static_cast<int>(saved_ranges_size_));
- number_of_histograms_ = 0;
- number_of_vectors_saved_ = 0;
- saved_ranges_size_ = 0;
- return;
- }
- if (uma_upload_attempt == 2) {
- UMA_HISTOGRAM_COUNTS_10000(
- "Histogram.SharedRange.Count.SecondUpload." + suffix,
- number_of_histograms_);
- UMA_HISTOGRAM_COUNTS_10000(
- "Histogram.SharedRange.RangesSaved.SecondUpload." + suffix,
- number_of_vectors_saved_);
- UMA_HISTOGRAM_COUNTS(
- "Histogram.SharedRange.ElementsSaved.SecondUpload." + suffix,
- static_cast<int>(saved_ranges_size_));
- number_of_histograms_ = 0;
- number_of_vectors_saved_ = 0;
- saved_ranges_size_ = 0;
- return;
- }
- UMA_HISTOGRAM_COUNTS_10000(
- "Histogram.SharedRange.Count.RestOfUploads." + suffix,
- number_of_histograms_);
- UMA_HISTOGRAM_COUNTS_10000(
- "Histogram.SharedRange.RangesSaved.RestOfUploads." + suffix,
- number_of_vectors_saved_);
- UMA_HISTOGRAM_COUNTS(
- "Histogram.SharedRange.ElementsSaved.RestOfUploads." + suffix,
- static_cast<int>(saved_ranges_size_));
-}
-
-// static
-void StatisticsRecorder::WriteHTMLGraph(const std::string& query,
- std::string* output) {
- if (!IsActive())
- return;
-
- Histograms snapshot;
- GetSnapshot(query, &snapshot);
- for (Histograms::iterator it = snapshot.begin();
- it != snapshot.end();
- ++it) {
- (*it)->WriteHTMLGraph(output);
- output->append("<br><hr><br>");
- }
-}
-
-// static
-void StatisticsRecorder::WriteGraph(const std::string& query,
- std::string* output) {
- if (!IsActive())
- return;
- if (query.length())
- StringAppendF(output, "Collections of histograms for %s\n", query.c_str());
- else
- output->append("Collections of all histograms\n");
-
- Histograms snapshot;
- GetSnapshot(query, &snapshot);
- for (Histograms::iterator it = snapshot.begin();
- it != snapshot.end();
- ++it) {
- (*it)->WriteAscii(true, "\n", output);
- output->append("\n");
- }
-}
-
-// static
-void StatisticsRecorder::GetHistograms(Histograms* output) {
- if (lock_ == NULL)
- return;
- base::AutoLock auto_lock(*lock_);
- if (!histograms_)
- return;
- for (HistogramMap::iterator it = histograms_->begin();
- histograms_->end() != it;
- ++it) {
- DCHECK_EQ(it->first, it->second->histogram_name());
- output->push_back(it->second);
- }
-}
-
-bool StatisticsRecorder::FindHistogram(const std::string& name,
- Histogram** histogram) {
- if (lock_ == NULL)
- return false;
- base::AutoLock auto_lock(*lock_);
- if (!histograms_)
- return false;
- HistogramMap::iterator it = histograms_->find(name);
- if (histograms_->end() == it)
- return false;
- *histogram = it->second;
- return true;
-}
-
-// private static
-void StatisticsRecorder::GetSnapshot(const std::string& query,
- Histograms* snapshot) {
- if (lock_ == NULL)
- return;
- base::AutoLock auto_lock(*lock_);
- if (!histograms_)
- return;
- for (HistogramMap::iterator it = histograms_->begin();
- histograms_->end() != it;
- ++it) {
- if (it->first.find(query) != std::string::npos)
- snapshot->push_back(it->second);
- }
-}
-
CachedRanges::CachedRanges(size_t bucket_count, int initial_value)
: ranges_(bucket_count, initial_value),
range_checksum_(0) {
@@ -1322,12 +1056,4 @@ bool CachedRanges::Equals(CachedRanges* other) const {
return true;
}
-// static
-StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL;
-// static
-StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL;
-// static
-base::Lock* StatisticsRecorder::lock_ = NULL;
-// static
-bool StatisticsRecorder::dump_on_exit_ = false;
} // namespace base
diff --git a/base/metrics/histogram.h b/base/metrics/histogram.h
index 39fe200..735de55 100644
--- a/base/metrics/histogram.h
+++ b/base/metrics/histogram.h
@@ -40,7 +40,6 @@
#ifndef BASE_METRICS_HISTOGRAM_H_
#define BASE_METRICS_HISTOGRAM_H_
-#include <list>
#include <map>
#include <string>
#include <vector>
@@ -774,90 +773,6 @@ class BASE_EXPORT CustomHistogram : public Histogram {
DISALLOW_COPY_AND_ASSIGN(CustomHistogram);
};
-//------------------------------------------------------------------------------
-// StatisticsRecorder handles all histograms in the system. It provides a
-// general place for histograms to register, and supports a global API for
-// accessing (i.e., dumping, or graphing) the data in all the histograms.
-
-class BASE_EXPORT StatisticsRecorder {
- public:
- typedef std::vector<Histogram*> Histograms;
-
- StatisticsRecorder();
-
- ~StatisticsRecorder();
-
- // Find out if histograms can now be registered into our list.
- static bool IsActive();
-
- // Register, or add a new histogram to the collection of statistics. If an
- // identically named histogram is already registered, then the argument
- // |histogram| will deleted. The returned value is always the registered
- // histogram (either the argument, or the pre-existing registered histogram).
- static Histogram* RegisterOrDeleteDuplicate(Histogram* histogram);
-
- // Register, or add a new cached_ranges_ of |histogram|. If an identical
- // cached_ranges_ is already registered, then the cached_ranges_ of
- // |histogram| is deleted and the |histogram|'s cached_ranges_ is reset to the
- // registered cached_ranges_. The cached_ranges_ of |histogram| is always the
- // registered CachedRanges (either the argument's cached_ranges_, or the
- // pre-existing registered cached_ranges_).
- static void RegisterOrDeleteDuplicateRanges(Histogram* histogram);
-
- // Method for collecting stats about histograms created in browser and
- // renderer processes. |suffix| is appended to histogram names. |suffix| could
- // be either browser or renderer.
- static void CollectHistogramStats(const std::string& suffix);
-
- // Methods for printing histograms. Only histograms which have query as
- // a substring are written to output (an empty string will process all
- // registered histograms).
- static void WriteHTMLGraph(const std::string& query, std::string* output);
- static void WriteGraph(const std::string& query, std::string* output);
-
- // Method for extracting histograms which were marked for use by UMA.
- static void GetHistograms(Histograms* output);
-
- // Find a histogram by name. It matches the exact name. This method is thread
- // safe. If a matching histogram is not found, then the |histogram| is
- // not changed.
- static bool FindHistogram(const std::string& query, Histogram** histogram);
-
- static bool dump_on_exit() { return dump_on_exit_; }
-
- static void set_dump_on_exit(bool enable) { dump_on_exit_ = enable; }
-
- // GetSnapshot copies some of the pointers to registered histograms into the
- // caller supplied vector (Histograms). Only histograms with names matching
- // query are returned. The query must be a substring of histogram name for its
- // pointer to be copied.
- static void GetSnapshot(const std::string& query, Histograms* snapshot);
-
-
- private:
- // We keep all registered histograms in a map, from name to histogram.
- typedef std::map<std::string, Histogram*> HistogramMap;
-
- // We keep all |cached_ranges_| in a map, from checksum to a list of
- // |cached_ranges_|. Checksum is calculated from the |ranges_| in
- // |cached_ranges_|.
- typedef std::map<uint32, std::list<CachedRanges*>*> RangesMap;
-
- static HistogramMap* histograms_;
-
- static RangesMap* ranges_;
-
- // lock protects access to the above map.
- static base::Lock* lock_;
-
- // Dump all known histograms to log.
- static bool dump_on_exit_;
-
- DISALLOW_COPY_AND_ASSIGN(StatisticsRecorder);
-};
-
-//------------------------------------------------------------------------------
-
// CachedRanges stores the Ranges vector. Histograms that have same Ranges
// vector will use the same CachedRanges object.
class BASE_EXPORT CachedRanges {
diff --git a/base/metrics/histogram_snapshot_manager.cc b/base/metrics/histogram_snapshot_manager.cc
index b325f73..9d9398d 100644
--- a/base/metrics/histogram_snapshot_manager.cc
+++ b/base/metrics/histogram_snapshot_manager.cc
@@ -4,6 +4,8 @@
#include "base/metrics/histogram_snapshot_manager.h"
+#include "base/metrics/statistics_recorder.h"
+
using base::Histogram;
using base::StatisticsRecorder;
diff --git a/base/metrics/histogram_unittest.cc b/base/metrics/histogram_unittest.cc
index bd8a427..5183460 100644
--- a/base/metrics/histogram_unittest.cc
+++ b/base/metrics/histogram_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -7,8 +7,10 @@
#include <algorithm>
#include <vector>
+#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/statistics_recorder.h"
#include "base/time.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/metrics/statistics_recorder.cc b/base/metrics/statistics_recorder.cc
new file mode 100644
index 0000000..37b6f43
--- /dev/null
+++ b/base/metrics/statistics_recorder.cc
@@ -0,0 +1,285 @@
+// Copyright (c) 2012 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 "base/metrics/statistics_recorder.h"
+
+#include "base/debug/leak_annotations.h"
+#include "base/logging.h"
+#include "base/metrics/histogram.h"
+#include "base/stringprintf.h"
+#include "base/synchronization/lock.h"
+
+namespace base {
+
+// Collect the number of histograms created.
+static uint32 number_of_histograms_ = 0;
+// Collect the number of vectors saved because of caching ranges.
+static uint32 number_of_vectors_saved_ = 0;
+// Collect the number of ranges_ elements saved because of caching ranges.
+static size_t saved_ranges_size_ = 0;
+
+// This singleton instance should be started during the single threaded portion
+// of main(), and hence it is not thread safe. It initializes globals to
+// provide support for all future calls.
+StatisticsRecorder::StatisticsRecorder() {
+ DCHECK(!histograms_);
+ if (lock_ == NULL) {
+ // This will leak on purpose. It's the only way to make sure we won't race
+ // against the static uninitialization of the module while one of our
+ // static methods relying on the lock get called at an inappropriate time
+ // during the termination phase. Since it's a static data member, we will
+ // leak one per process, which would be similar to the instance allocated
+ // during static initialization and released only on process termination.
+ lock_ = new base::Lock;
+ }
+ base::AutoLock auto_lock(*lock_);
+ histograms_ = new HistogramMap;
+ ranges_ = new RangesMap;
+}
+
+StatisticsRecorder::~StatisticsRecorder() {
+ DCHECK(histograms_ && lock_);
+
+ if (dump_on_exit_) {
+ std::string output;
+ WriteGraph("", &output);
+ DLOG(INFO) << output;
+ }
+ // Clean up.
+ HistogramMap* histograms = NULL;
+ {
+ base::AutoLock auto_lock(*lock_);
+ histograms = histograms_;
+ histograms_ = NULL;
+ }
+ RangesMap* ranges = NULL;
+ {
+ base::AutoLock auto_lock(*lock_);
+ ranges = ranges_;
+ ranges_ = NULL;
+ }
+ // We are going to leak the histograms and the ranges.
+ delete histograms;
+ delete ranges;
+ // We don't delete lock_ on purpose to avoid having to properly protect
+ // against it going away after we checked for NULL in the static methods.
+}
+
+// static
+bool StatisticsRecorder::IsActive() {
+ if (lock_ == NULL)
+ return false;
+ base::AutoLock auto_lock(*lock_);
+ return NULL != histograms_;
+}
+
+Histogram* StatisticsRecorder::RegisterOrDeleteDuplicate(Histogram* histogram) {
+ // As per crbug.com/79322 the histograms are intentionally leaked, so we need
+ // to annotate them. Because ANNOTATE_LEAKING_OBJECT_PTR may be used only once
+ // for an object, the duplicates should not be annotated.
+ // Callers are responsible for not calling RegisterOrDeleteDuplicate(ptr)
+ // twice if (lock_ == NULL) || (!histograms_).
+ DCHECK(histogram->HasValidRangeChecksum());
+ if (lock_ == NULL) {
+ ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322
+ return histogram;
+ }
+ base::AutoLock auto_lock(*lock_);
+ if (!histograms_) {
+ ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322
+ return histogram;
+ }
+ const std::string name = histogram->histogram_name();
+ HistogramMap::iterator it = histograms_->find(name);
+ // Avoid overwriting a previous registration.
+ if (histograms_->end() == it) {
+ (*histograms_)[name] = histogram;
+ ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322
+ RegisterOrDeleteDuplicateRanges(histogram);
+ ++number_of_histograms_;
+ } else {
+ delete histogram; // We already have one by this name.
+ histogram = it->second;
+ }
+ return histogram;
+}
+
+// static
+void StatisticsRecorder::RegisterOrDeleteDuplicateRanges(Histogram* histogram) {
+ DCHECK(histogram);
+ CachedRanges* histogram_ranges = histogram->cached_ranges();
+ DCHECK(histogram_ranges);
+ uint32 checksum = histogram->range_checksum();
+ histogram_ranges->SetRangeChecksum(checksum);
+
+ RangesMap::iterator ranges_it = ranges_->find(checksum);
+ if (ranges_->end() == ranges_it) {
+ // Register the new CachedRanges.
+ std::list<CachedRanges*>* checksum_matching_list(
+ new std::list<CachedRanges*>());
+ checksum_matching_list->push_front(histogram_ranges);
+ (*ranges_)[checksum] = checksum_matching_list;
+ return;
+ }
+
+ // Use the registered CachedRanges if the registered CachedRanges has same
+ // ranges_ as |histogram|'s CachedRanges.
+ std::list<CachedRanges*>* checksum_matching_list = ranges_it->second;
+ std::list<CachedRanges*>::iterator checksum_matching_list_it;
+ for (checksum_matching_list_it = checksum_matching_list->begin();
+ checksum_matching_list_it != checksum_matching_list->end();
+ ++checksum_matching_list_it) {
+ CachedRanges* existing_histogram_ranges = *checksum_matching_list_it;
+ DCHECK(existing_histogram_ranges);
+ if (existing_histogram_ranges->Equals(histogram_ranges)) {
+ histogram->set_cached_ranges(existing_histogram_ranges);
+ ++number_of_vectors_saved_;
+ saved_ranges_size_ += histogram_ranges->size();
+ delete histogram_ranges;
+ return;
+ }
+ }
+
+ // We haven't found a CachedRanges which has the same ranges. Register the
+ // new CachedRanges.
+ DCHECK(checksum_matching_list_it == checksum_matching_list->end());
+ checksum_matching_list->push_front(histogram_ranges);
+}
+
+// static
+void StatisticsRecorder::CollectHistogramStats(const std::string& suffix) {
+ static int uma_upload_attempt = 0;
+ ++uma_upload_attempt;
+ if (uma_upload_attempt == 1) {
+ UMA_HISTOGRAM_COUNTS_10000(
+ "Histogram.SharedRange.Count.FirstUpload." + suffix,
+ number_of_histograms_);
+ UMA_HISTOGRAM_COUNTS_10000(
+ "Histogram.SharedRange.RangesSaved.FirstUpload." + suffix,
+ number_of_vectors_saved_);
+ UMA_HISTOGRAM_COUNTS(
+ "Histogram.SharedRange.ElementsSaved.FirstUpload." + suffix,
+ static_cast<int>(saved_ranges_size_));
+ number_of_histograms_ = 0;
+ number_of_vectors_saved_ = 0;
+ saved_ranges_size_ = 0;
+ return;
+ }
+ if (uma_upload_attempt == 2) {
+ UMA_HISTOGRAM_COUNTS_10000(
+ "Histogram.SharedRange.Count.SecondUpload." + suffix,
+ number_of_histograms_);
+ UMA_HISTOGRAM_COUNTS_10000(
+ "Histogram.SharedRange.RangesSaved.SecondUpload." + suffix,
+ number_of_vectors_saved_);
+ UMA_HISTOGRAM_COUNTS(
+ "Histogram.SharedRange.ElementsSaved.SecondUpload." + suffix,
+ static_cast<int>(saved_ranges_size_));
+ number_of_histograms_ = 0;
+ number_of_vectors_saved_ = 0;
+ saved_ranges_size_ = 0;
+ return;
+ }
+ UMA_HISTOGRAM_COUNTS_10000(
+ "Histogram.SharedRange.Count.RestOfUploads." + suffix,
+ number_of_histograms_);
+ UMA_HISTOGRAM_COUNTS_10000(
+ "Histogram.SharedRange.RangesSaved.RestOfUploads." + suffix,
+ number_of_vectors_saved_);
+ UMA_HISTOGRAM_COUNTS(
+ "Histogram.SharedRange.ElementsSaved.RestOfUploads." + suffix,
+ static_cast<int>(saved_ranges_size_));
+}
+
+// static
+void StatisticsRecorder::WriteHTMLGraph(const std::string& query,
+ std::string* output) {
+ if (!IsActive())
+ return;
+
+ Histograms snapshot;
+ GetSnapshot(query, &snapshot);
+ for (Histograms::iterator it = snapshot.begin();
+ it != snapshot.end();
+ ++it) {
+ (*it)->WriteHTMLGraph(output);
+ output->append("<br><hr><br>");
+ }
+}
+
+// static
+void StatisticsRecorder::WriteGraph(const std::string& query,
+ std::string* output) {
+ if (!IsActive())
+ return;
+ if (query.length())
+ StringAppendF(output, "Collections of histograms for %s\n", query.c_str());
+ else
+ output->append("Collections of all histograms\n");
+
+ Histograms snapshot;
+ GetSnapshot(query, &snapshot);
+ for (Histograms::iterator it = snapshot.begin();
+ it != snapshot.end();
+ ++it) {
+ (*it)->WriteAscii(true, "\n", output);
+ output->append("\n");
+ }
+}
+
+// static
+void StatisticsRecorder::GetHistograms(Histograms* output) {
+ if (lock_ == NULL)
+ return;
+ base::AutoLock auto_lock(*lock_);
+ if (!histograms_)
+ return;
+ for (HistogramMap::iterator it = histograms_->begin();
+ histograms_->end() != it;
+ ++it) {
+ DCHECK_EQ(it->first, it->second->histogram_name());
+ output->push_back(it->second);
+ }
+}
+
+bool StatisticsRecorder::FindHistogram(const std::string& name,
+ Histogram** histogram) {
+ if (lock_ == NULL)
+ return false;
+ base::AutoLock auto_lock(*lock_);
+ if (!histograms_)
+ return false;
+ HistogramMap::iterator it = histograms_->find(name);
+ if (histograms_->end() == it)
+ return false;
+ *histogram = it->second;
+ return true;
+}
+
+// private static
+void StatisticsRecorder::GetSnapshot(const std::string& query,
+ Histograms* snapshot) {
+ if (lock_ == NULL)
+ return;
+ base::AutoLock auto_lock(*lock_);
+ if (!histograms_)
+ return;
+ for (HistogramMap::iterator it = histograms_->begin();
+ histograms_->end() != it;
+ ++it) {
+ if (it->first.find(query) != std::string::npos)
+ snapshot->push_back(it->second);
+ }
+}
+
+// static
+StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL;
+// static
+StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL;
+// static
+base::Lock* StatisticsRecorder::lock_ = NULL;
+// static
+bool StatisticsRecorder::dump_on_exit_ = false;
+
+} // namespace base
diff --git a/base/metrics/statistics_recorder.h b/base/metrics/statistics_recorder.h
new file mode 100644
index 0000000..b947c53
--- /dev/null
+++ b/base/metrics/statistics_recorder.h
@@ -0,0 +1,105 @@
+// Copyright (c) 2012 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.
+
+// StatisticsRecorder handles all histograms in the system. It provides a
+// general place for histograms to register, and supports a global API for
+// accessing (i.e., dumping, or graphing) the data in all the histograms.
+
+#ifndef BASE_METRICS_STATISTICS_RECORDER_H_
+#define BASE_METRICS_STATISTICS_RECORDER_H_
+
+#include <list>
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/base_export.h"
+#include "base/basictypes.h"
+
+namespace base {
+
+class CachedRanges;
+class Histogram;
+class Lock;
+
+class BASE_EXPORT StatisticsRecorder {
+ public:
+ typedef std::vector<Histogram*> Histograms;
+
+ StatisticsRecorder();
+
+ ~StatisticsRecorder();
+
+ // Find out if histograms can now be registered into our list.
+ static bool IsActive();
+
+ // Register, or add a new histogram to the collection of statistics. If an
+ // identically named histogram is already registered, then the argument
+ // |histogram| will deleted. The returned value is always the registered
+ // histogram (either the argument, or the pre-existing registered histogram).
+ static Histogram* RegisterOrDeleteDuplicate(Histogram* histogram);
+
+ // Register, or add a new cached_ranges_ of |histogram|. If an identical
+ // cached_ranges_ is already registered, then the cached_ranges_ of
+ // |histogram| is deleted and the |histogram|'s cached_ranges_ is reset to the
+ // registered cached_ranges_. The cached_ranges_ of |histogram| is always the
+ // registered CachedRanges (either the argument's cached_ranges_, or the
+ // pre-existing registered cached_ranges_).
+ static void RegisterOrDeleteDuplicateRanges(Histogram* histogram);
+
+ // Method for collecting stats about histograms created in browser and
+ // renderer processes. |suffix| is appended to histogram names. |suffix| could
+ // be either browser or renderer.
+ static void CollectHistogramStats(const std::string& suffix);
+
+ // Methods for printing histograms. Only histograms which have query as
+ // a substring are written to output (an empty string will process all
+ // registered histograms).
+ static void WriteHTMLGraph(const std::string& query, std::string* output);
+ static void WriteGraph(const std::string& query, std::string* output);
+
+ // Method for extracting histograms which were marked for use by UMA.
+ static void GetHistograms(Histograms* output);
+
+ // Find a histogram by name. It matches the exact name. This method is thread
+ // safe. If a matching histogram is not found, then the |histogram| is
+ // not changed.
+ static bool FindHistogram(const std::string& query, Histogram** histogram);
+
+ static bool dump_on_exit() { return dump_on_exit_; }
+
+ static void set_dump_on_exit(bool enable) { dump_on_exit_ = enable; }
+
+ // GetSnapshot copies some of the pointers to registered histograms into the
+ // caller supplied vector (Histograms). Only histograms with names matching
+ // query are returned. The query must be a substring of histogram name for its
+ // pointer to be copied.
+ static void GetSnapshot(const std::string& query, Histograms* snapshot);
+
+
+ private:
+ // We keep all registered histograms in a map, from name to histogram.
+ typedef std::map<std::string, Histogram*> HistogramMap;
+
+ // We keep all |cached_ranges_| in a map, from checksum to a list of
+ // |cached_ranges_|. Checksum is calculated from the |ranges_| in
+ // |cached_ranges_|.
+ typedef std::map<uint32, std::list<CachedRanges*>*> RangesMap;
+
+ static HistogramMap* histograms_;
+
+ static RangesMap* ranges_;
+
+ // lock protects access to the above map.
+ static base::Lock* lock_;
+
+ // Dump all known histograms to log.
+ static bool dump_on_exit_;
+
+ DISALLOW_COPY_AND_ASSIGN(StatisticsRecorder);
+};
+
+} // namespace base
+
+#endif // BASE_METRICS_STATISTICS_RECORDER_H_
diff --git a/chrome/browser/chrome_browser_application_mac_unittest.mm b/chrome/browser/chrome_browser_application_mac_unittest.mm
index 9aa005a..5c12f27 100644
--- a/chrome/browser/chrome_browser_application_mac_unittest.mm
+++ b/chrome/browser/chrome_browser_application_mac_unittest.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -6,6 +6,7 @@
#import "base/mac/scoped_nsexception_enabler.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/statistics_recorder.h"
#import "chrome/browser/chrome_browser_application_mac.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/extensions/api/metrics/metrics_apitest.cc b/chrome/browser/extensions/api/metrics/metrics_apitest.cc
index 5194977..61edec7 100644
--- a/chrome/browser/extensions/api/metrics/metrics_apitest.cc
+++ b/chrome/browser/extensions/api/metrics/metrics_apitest.cc
@@ -5,6 +5,7 @@
#include <map>
#include "base/metrics/histogram.h"
+#include "base/metrics/statistics_recorder.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/metrics/metrics_service.cc b/chrome/browser/metrics/metrics_service.cc
index d2e5a84..a688d41 100644
--- a/chrome/browser/metrics/metrics_service.cc
+++ b/chrome/browser/metrics/metrics_service.cc
@@ -152,6 +152,7 @@
#include "base/guid.h"
#include "base/md5.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/statistics_recorder.h"
#include "base/rand_util.h"
#include "base/string_number_conversions.h"
#include "base/threading/platform_thread.h"
diff --git a/chrome/browser/net/http_pipelining_compatibility_client_unittest.cc b/chrome/browser/net/http_pipelining_compatibility_client_unittest.cc
index b60dabb..83598f9 100644
--- a/chrome/browser/net/http_pipelining_compatibility_client_unittest.cc
+++ b/chrome/browser/net/http_pipelining_compatibility_client_unittest.cc
@@ -11,6 +11,7 @@
#include "base/basictypes.h"
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/statistics_recorder.h"
#include "base/stl_util.h"
#include "base/stringprintf.h"
#include "content/public/test/test_browser_thread.h"
diff --git a/chrome/browser/protector/default_search_provider_change_browsertest.cc b/chrome/browser/protector/default_search_provider_change_browsertest.cc
index 9f32e9e..32d987e 100644
--- a/chrome/browser/protector/default_search_provider_change_browsertest.cc
+++ b/chrome/browser/protector/default_search_provider_change_browsertest.cc
@@ -4,6 +4,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/statistics_recorder.h"
#include "base/message_loop.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/protector/base_setting_change.h"
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
index 066c9e9..d2a57f0 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -12,7 +12,6 @@
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/memory/ref_counted.h"
-#include "base/metrics/histogram.h"
#include "base/path_service.h"
#include "base/scoped_temp_dir.h"
#include "base/string_split.h"
@@ -42,8 +41,6 @@
#include "sql/statement.h"
#include "testing/gmock/include/gmock/gmock.h"
-using base::Histogram;
-using base::StatisticsRecorder;
using content::BrowserThread;
using content::InterstitialPage;
using content::WebContents;
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
index 9db6e38..5551980 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
@@ -12,6 +12,7 @@
#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/statistics_recorder.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/string_split.h"
diff --git a/chrome/browser/ui/webui/about_ui.cc b/chrome/browser/ui/webui/about_ui.cc
index e441804..71980a6 100644
--- a/chrome/browser/ui/webui/about_ui.cc
+++ b/chrome/browser/ui/webui/about_ui.cc
@@ -18,6 +18,7 @@
#include "base/json/json_writer.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/singleton.h"
+#include "base/metrics/statistics_recorder.h"
#include "base/metrics/stats_table.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
diff --git a/chrome/renderer/chrome_render_process_observer.cc b/chrome/renderer/chrome_render_process_observer.cc
index 44b98d6..4106360 100644
--- a/chrome/renderer/chrome_render_process_observer.cc
+++ b/chrome/renderer/chrome_render_process_observer.cc
@@ -12,6 +12,7 @@
#include "base/memory/weak_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/statistics_recorder.h"
#include "base/native_library.h"
#include "base/path_service.h"
#include "base/process_util.h"
diff --git a/chrome_frame/metrics_service.cc b/chrome_frame/metrics_service.cc
index 640e02e..2a5e8b1 100644
--- a/chrome_frame/metrics_service.cc
+++ b/chrome_frame/metrics_service.cc
@@ -50,6 +50,7 @@
#include "third_party/bzip2/bzlib.h"
#endif
+#include "base/metrics/statistics_recorder.h"
#include "base/string16.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
diff --git a/content/browser/browser_main_runner.cc b/content/browser/browser_main_runner.cc
index f859683..a2ecb74 100644
--- a/content/browser/browser_main_runner.cc
+++ b/content/browser/browser_main_runner.cc
@@ -10,6 +10,7 @@
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/statistics_recorder.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/notification_service_impl.h"
#include "content/common/child_process.h"
diff --git a/content/browser/histogram_internals_request_job.cc b/content/browser/histogram_internals_request_job.cc
index cb3c8fc..6614642 100644
--- a/content/browser/histogram_internals_request_job.cc
+++ b/content/browser/histogram_internals_request_job.cc
@@ -5,6 +5,7 @@
#include "content/browser/histogram_internals_request_job.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/statistics_recorder.h"
#include "content/browser/histogram_synchronizer.h"
#include "googleurl/src/gurl.h"
#include "net/base/escape.h"
diff --git a/content/common/child_histogram_message_filter.cc b/content/common/child_histogram_message_filter.cc
index 5cc137c..79d4fdb 100644
--- a/content/common/child_histogram_message_filter.cc
+++ b/content/common/child_histogram_message_filter.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/message_loop.h"
+#include "base/metrics/statistics_recorder.h"
#include "content/common/child_process.h"
#include "content/common/child_process_messages.h"
#include "content/common/child_thread.h"
diff --git a/content/renderer/renderer_main.cc b/content/renderer/renderer_main.cc
index b98030b..18a64b7 100644
--- a/content/renderer/renderer_main.cc
+++ b/content/renderer/renderer_main.cc
@@ -12,6 +12,7 @@
#include "base/metrics/field_trial.h"
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/statistics_recorder.h"
#include "base/metrics/stats_counters.h"
#include "base/path_service.h"
#include "base/process_util.h"
diff --git a/net/base/run_all_unittests.cc b/net/base/run_all_unittests.cc
index a139a8f..131653f 100644
--- a/net/base/run_all_unittests.cc
+++ b/net/base/run_all_unittests.cc
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/metrics/statistics_recorder.h"
#include "build/build_config.h"
-#include "base/metrics/histogram.h"
#include "crypto/nss_util.h"
#include "net/base/net_test_suite.h"
#include "net/socket/client_socket_pool_base.h"
diff --git a/net/curvecp/curvecp_transfer_unittest.cc b/net/curvecp/curvecp_transfer_unittest.cc
index 11c5d3f..8180da4 100644
--- a/net/curvecp/curvecp_transfer_unittest.cc
+++ b/net/curvecp/curvecp_transfer_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -6,7 +6,7 @@
#include "base/basictypes.h"
#include "base/message_loop.h"
-#include "base/metrics/histogram.h"
+#include "base/metrics/statistics_recorder.h"
#include "net/base/net_test_suite.h"
#include "net/base/test_completion_callback.h"
#include "net/curvecp/circular_buffer.h"
diff --git a/net/disk_cache/stats_histogram.cc b/net/disk_cache/stats_histogram.cc
index 943990a3..22343d5 100644
--- a/net/disk_cache/stats_histogram.cc
+++ b/net/disk_cache/stats_histogram.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -6,6 +6,7 @@
#include "base/debug/leak_annotations.h"
#include "base/logging.h"
+#include "base/metrics/statistics_recorder.h"
#include "net/disk_cache/stats.h"
namespace disk_cache {
diff --git a/net/socket_stream/socket_stream_metrics_unittest.cc b/net/socket_stream/socket_stream_metrics_unittest.cc
index 5646302..e0e11d6 100644
--- a/net/socket_stream/socket_stream_metrics_unittest.cc
+++ b/net/socket_stream/socket_stream_metrics_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -6,6 +6,7 @@
#include "base/basictypes.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/statistics_recorder.h"
#include "googleurl/src/gurl.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
diff --git a/net/url_request/url_request_throttler_unittest.cc b/net/url_request/url_request_throttler_unittest.cc
index 7809af6..a082779 100644
--- a/net/url_request/url_request_throttler_unittest.cc
+++ b/net/url_request/url_request_throttler_unittest.cc
@@ -6,6 +6,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/statistics_recorder.h"
#include "base/pickle.h"
#include "base/stringprintf.h"
#include "base/string_number_conversions.h"