summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorrtenneti@google.com <rtenneti@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-12 18:19:45 +0000
committerrtenneti@google.com <rtenneti@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-12 18:19:45 +0000
commit83ab4a28583780761ec6e3cddd4418c2c16c049c (patch)
tree7c0ae2b3048546848331bb46ec14f493954eb8fc /base
parent447a5b6333539c309e015ee8f98ff6d9e131fa85 (diff)
downloadchromium_src-83ab4a28583780761ec6e3cddd4418c2c16c049c.zip
chromium_src-83ab4a28583780761ec6e3cddd4418c2c16c049c.tar.gz
chromium_src-83ab4a28583780761ec6e3cddd4418c2c16c049c.tar.bz2
Histograms - Support histograms for Plugins, GPU
and all child processes. Renderer processes also use this new method to send histograms to browser. This code is similar to the code that gets profiler data from all processes. R=jar@chromium.org,jam@chromium.org TEST=browser unit tests, interactive UI tests BUG=114013 Review URL: https://chromiumcodereview.appspot.com/10454086 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146394 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/base.gypi3
-rw-r--r--base/metrics/histogram_flattener.h40
-rw-r--r--base/metrics/histogram_snapshot_manager.cc104
-rw-r--r--base/metrics/histogram_snapshot_manager.h60
4 files changed, 207 insertions, 0 deletions
diff --git a/base/base.gypi b/base/base.gypi
index b605ae5..cfc904c 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -235,6 +235,9 @@
'message_pump_win.h',
'metrics/histogram.cc',
'metrics/histogram.h',
+ 'metrics/histogram_flattener.h',
+ 'metrics/histogram_snapshot_manager.cc',
+ 'metrics/histogram_snapshot_manager.h',
'metrics/stats_counters.cc',
'metrics/stats_counters.h',
'metrics/stats_table.cc',
diff --git a/base/metrics/histogram_flattener.h b/base/metrics/histogram_flattener.h
new file mode 100644
index 0000000..edb1511
--- /dev/null
+++ b/base/metrics/histogram_flattener.h
@@ -0,0 +1,40 @@
+// 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.
+
+#ifndef BASE_METRICS_HISTOGRAM_FLATTENER_H_
+#define BASE_METRICS_HISTOGRAM_FLATTENER_H_
+
+#include <map>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/metrics/histogram.h"
+
+namespace base {
+
+// HistogramFlattener is an interface for the logistics of gathering up
+// available histograms for recording. The implementors handle the exact lower
+// level recording mechanism, or error report mechanism.
+class BASE_EXPORT HistogramFlattener {
+ public:
+ virtual void RecordDelta(const base::Histogram& histogram,
+ const base::Histogram::SampleSet& snapshot) = 0;
+
+ // Record various errors found during attempts to record histograms.
+ virtual void InconsistencyDetected(int problem) = 0;
+ virtual void UniqueInconsistencyDetected(int problem) = 0;
+ virtual void SnapshotProblemResolved(int amount) = 0;
+
+ protected:
+ HistogramFlattener() {}
+ virtual ~HistogramFlattener() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(HistogramFlattener);
+};
+
+} // namespace base
+
+#endif // BASE_METRICS_HISTOGRAM_FLATTENER_H_
diff --git a/base/metrics/histogram_snapshot_manager.cc b/base/metrics/histogram_snapshot_manager.cc
new file mode 100644
index 0000000..b325f73
--- /dev/null
+++ b/base/metrics/histogram_snapshot_manager.cc
@@ -0,0 +1,104 @@
+// 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/histogram_snapshot_manager.h"
+
+using base::Histogram;
+using base::StatisticsRecorder;
+
+namespace base {
+
+HistogramSnapshotManager::HistogramSnapshotManager(
+ HistogramFlattener* histogram_flattener)
+ : histogram_flattener_(histogram_flattener) {
+ DCHECK(histogram_flattener_);
+}
+
+HistogramSnapshotManager::~HistogramSnapshotManager() {}
+
+void HistogramSnapshotManager::PrepareDeltas(Histogram::Flags flag_to_set,
+ bool record_only_uma) {
+ StatisticsRecorder::Histograms histograms;
+ StatisticsRecorder::GetHistograms(&histograms);
+ for (StatisticsRecorder::Histograms::const_iterator it = histograms.begin();
+ histograms.end() != it;
+ ++it) {
+ (*it)->SetFlags(flag_to_set);
+ if (record_only_uma &&
+ 0 == ((*it)->flags() & Histogram::kUmaTargetedHistogramFlag))
+ continue;
+ PrepareDelta(**it);
+ }
+}
+
+void HistogramSnapshotManager::PrepareDelta(const Histogram& histogram) {
+ DCHECK(histogram_flattener_);
+
+ // Get up-to-date snapshot of sample stats.
+ Histogram::SampleSet snapshot;
+ histogram.SnapshotSample(&snapshot);
+ const std::string& histogram_name = histogram.histogram_name();
+
+ int corruption = histogram.FindCorruption(snapshot);
+
+ // Crash if we detect that our histograms have been overwritten. This may be
+ // a fair distance from the memory smasher, but we hope to correlate these
+ // crashes with other events, such as plugins, or usage patterns, etc.
+ if (Histogram::BUCKET_ORDER_ERROR & corruption) {
+ // The checksum should have caught this, so crash separately if it didn't.
+ CHECK_NE(0, Histogram::RANGE_CHECKSUM_ERROR & corruption);
+ CHECK(false); // Crash for the bucket order corruption.
+ }
+ // Checksum corruption might not have caused order corruption.
+ CHECK_EQ(0, Histogram::RANGE_CHECKSUM_ERROR & corruption);
+
+ if (corruption) {
+ NOTREACHED();
+ histogram_flattener_->InconsistencyDetected(corruption);
+ // Don't record corrupt data to metrics survices.
+ if (NULL == inconsistencies_.get())
+ inconsistencies_.reset(new ProblemMap);
+ int old_corruption = (*inconsistencies_)[histogram_name];
+ if (old_corruption == (corruption | old_corruption))
+ return; // We've already seen this corruption for this histogram.
+ (*inconsistencies_)[histogram_name] |= corruption;
+ histogram_flattener_->UniqueInconsistencyDetected(corruption);
+ return;
+ }
+
+ // Find the already recorded stats, or create an empty set. Remove from our
+ // snapshot anything that we've already recorded.
+ LoggedSampleMap::iterator it = logged_samples_.find(histogram_name);
+ Histogram::SampleSet* already_logged;
+ if (logged_samples_.end() == it) {
+ // Add new entry
+ already_logged = &logged_samples_[histogram.histogram_name()];
+ already_logged->Resize(histogram); // Complete initialization.
+ } else {
+ already_logged = &(it->second);
+ int64 discrepancy(already_logged->TotalCount() -
+ already_logged->redundant_count());
+ if (discrepancy) {
+ NOTREACHED(); // Already_logged has become corrupt.
+ int problem = static_cast<int>(discrepancy);
+ if (problem != discrepancy)
+ problem = INT_MAX;
+ histogram_flattener_->SnapshotProblemResolved(problem);
+ // With no valid baseline, we'll act like we've recorded everything in our
+ // snapshot.
+ already_logged->Subtract(*already_logged);
+ already_logged->Add(snapshot);
+ }
+ // Deduct any stats we've already logged from our snapshot.
+ snapshot.Subtract(*already_logged);
+ }
+
+ // Snapshot now contains only a delta to what we've already_logged.
+ if (snapshot.redundant_count() > 0) {
+ histogram_flattener_->RecordDelta(histogram, snapshot);
+ // Add new data into our running total.
+ already_logged->Add(snapshot);
+ }
+}
+} // namespace base
diff --git a/base/metrics/histogram_snapshot_manager.h b/base/metrics/histogram_snapshot_manager.h
new file mode 100644
index 0000000..a945ac7
--- /dev/null
+++ b/base/metrics/histogram_snapshot_manager.h
@@ -0,0 +1,60 @@
+// 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.
+
+#ifndef BASE_METRICS_HISTOGRAM_SNAPSHOT_MANAGER_H_
+#define BASE_METRICS_HISTOGRAM_SNAPSHOT_MANAGER_H_
+
+#include <map>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/metrics/histogram.h"
+#include "base/metrics/histogram_flattener.h"
+
+namespace base {
+
+// HistogramSnapshotManager handles the logistics of gathering up available
+// histograms for recording either to disk or for transmission (such as from
+// renderer to browser, or from browser to UMA upload). Since histograms can sit
+// in memory for an extended period of time, and are vulnerable to memory
+// corruption, this class also validates as much rendundancy as it can before
+// calling for the marginal change (a.k.a., delta) in a histogram to be
+// recorded.
+class BASE_EXPORT HistogramSnapshotManager {
+ public:
+ explicit HistogramSnapshotManager(HistogramFlattener* histogram_flattener);
+ virtual ~HistogramSnapshotManager();
+
+ // Snapshot all histograms, and ask |histogram_flattener_| to record the
+ // delta. The arguments allow selecting only a subset of histograms for
+ // recording, or to set a flag in each recorded histogram.
+ void PrepareDeltas(base::Histogram::Flags flags_to_set, bool record_only_uma);
+
+ private:
+ // Maintain a map of histogram names to the sample stats we've recorded.
+ typedef std::map<std::string, base::Histogram::SampleSet> LoggedSampleMap;
+ // List of histograms names, and their encontered corruptions.
+ typedef std::map<std::string, int> ProblemMap;
+
+ // Snapshot this histogram, and record the delta.
+ void PrepareDelta(const base::Histogram& histogram);
+
+ // For histograms, track what we've already recorded (as a sample for
+ // each histogram) so that we can record only the delta with the next log.
+ LoggedSampleMap logged_samples_;
+
+ // List of histograms found corrupt to be corrupt, and their problems.
+ scoped_ptr<ProblemMap> inconsistencies_;
+
+ // |histogram_flattener_| handles the logistics of recording the histogram
+ // deltas.
+ HistogramFlattener* histogram_flattener_; // Weak.
+
+ DISALLOW_COPY_AND_ASSIGN(HistogramSnapshotManager);
+};
+
+} // namespace base
+
+#endif // BASE_METRICS_HISTOGRAM_SNAPSHOT_MANAGER_H_