OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef BASE_METRICS_HISTOGRAM_SNAPSHOT_MANAGER_H_ | 5 #ifndef BASE_METRICS_HISTOGRAM_SNAPSHOT_MANAGER_H_ |
6 #define BASE_METRICS_HISTOGRAM_SNAPSHOT_MANAGER_H_ | 6 #define BASE_METRICS_HISTOGRAM_SNAPSHOT_MANAGER_H_ |
7 | 7 |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <map> | 10 #include <map> |
11 #include <string> | 11 #include <string> |
12 | 12 |
| 13 #include "base/gtest_prod_util.h" |
13 #include "base/macros.h" | 14 #include "base/macros.h" |
14 #include "base/metrics/histogram_base.h" | 15 #include "base/metrics/histogram_base.h" |
15 | 16 |
16 namespace base { | 17 namespace base { |
17 | 18 |
18 class HistogramSamples; | 19 class HistogramSamples; |
19 class HistogramFlattener; | 20 class HistogramFlattener; |
20 | 21 |
21 // HistogramSnapshotManager handles the logistics of gathering up available | 22 // HistogramSnapshotManager handles the logistics of gathering up available |
22 // histograms for recording either to disk or for transmission (such as from | 23 // histograms for recording either to disk or for transmission (such as from |
23 // renderer to browser, or from browser to UMA upload). Since histograms can sit | 24 // renderer to browser, or from browser to UMA upload). Since histograms can sit |
24 // in memory for an extended period of time, and are vulnerable to memory | 25 // in memory for an extended period of time, and are vulnerable to memory |
25 // corruption, this class also validates as much rendundancy as it can before | 26 // corruption, this class also validates as much rendundancy as it can before |
26 // calling for the marginal change (a.k.a., delta) in a histogram to be | 27 // calling for the marginal change (a.k.a., delta) in a histogram to be |
27 // recorded. | 28 // recorded. |
28 class BASE_EXPORT HistogramSnapshotManager { | 29 class BASE_EXPORT HistogramSnapshotManager { |
29 public: | 30 public: |
30 explicit HistogramSnapshotManager(HistogramFlattener* histogram_flattener); | 31 explicit HistogramSnapshotManager(HistogramFlattener* histogram_flattener); |
31 virtual ~HistogramSnapshotManager(); | 32 virtual ~HistogramSnapshotManager(); |
32 | 33 |
33 // Snapshot all histograms, and ask |histogram_flattener_| to record the | 34 // Snapshot all histograms, and ask |histogram_flattener_| to record the |
34 // delta. |flags_to_set| is used to set flags for each histogram. | 35 // delta. |flags_to_set| is used to set flags for each histogram. |
35 // |required_flags| is used to select histograms to be recorded. | 36 // |required_flags| is used to select histograms to be recorded. |
36 // Only histograms that have all the flags specified by the argument will be | 37 // Only histograms that have all the flags specified by the argument will be |
37 // chosen. If all histograms should be recorded, set it to | 38 // chosen. If all histograms should be recorded, set it to |
38 // |Histogram::kNoFlags|. | 39 // |Histogram::kNoFlags|. Though any "forward" iterator will work, the |
| 40 // histograms over which it iterates *must* remain valid until this method |
| 41 // returns; the iterator cannot deallocate histograms once it iterates past |
| 42 // them. |
39 template <class ForwardHistogramIterator> | 43 template <class ForwardHistogramIterator> |
40 void PrepareDeltas(ForwardHistogramIterator begin, | 44 void PrepareDeltas(ForwardHistogramIterator begin, |
41 ForwardHistogramIterator end, | 45 ForwardHistogramIterator end, |
42 HistogramBase::Flags flags_to_set, | 46 HistogramBase::Flags flags_to_set, |
43 HistogramBase::Flags required_flags) { | 47 HistogramBase::Flags required_flags) { |
| 48 StartDeltas(); |
44 for (ForwardHistogramIterator it = begin; it != end; ++it) { | 49 for (ForwardHistogramIterator it = begin; it != end; ++it) { |
45 (*it)->SetFlags(flags_to_set); | 50 (*it)->SetFlags(flags_to_set); |
46 if (((*it)->flags() & required_flags) == required_flags) | 51 if (((*it)->flags() & required_flags) == required_flags) |
47 PrepareDelta(**it); | 52 PrepareDelta(*it); |
48 } | 53 } |
| 54 FinishDeltas(); |
49 } | 55 } |
50 | 56 |
| 57 // When the collection is not so simple as can be done using a single |
| 58 // iterator, the steps can be performed separately. Call PerpareDelta() |
| 59 // as many times as necessary with a single StartDeltas() before and |
| 60 // a single FinishDeltas() after. All passed histograms must live |
| 61 // until FinishDeltas() completes. PrepareAbsolute() works the same |
| 62 // but assumes there were no previous logged values and no future deltas |
| 63 // will be created (and thus can work on read-only histograms). |
| 64 void StartDeltas(); |
| 65 void PrepareDelta(HistogramBase* histogram); |
| 66 void PrepareAbsolute(const HistogramBase* histogram); |
| 67 void FinishDeltas(); |
| 68 |
51 private: | 69 private: |
52 // Snapshot this histogram, and record the delta. | 70 FRIEND_TEST_ALL_PREFIXES(HistogramSnapshotManagerTest, CheckMerge); |
53 void PrepareDelta(const HistogramBase& histogram); | 71 |
| 72 // During a snapshot, samples are acquired and aggregated. This structure |
| 73 // contains all the information collected for a given histogram. Once a |
| 74 // snapshot operation is finished, it is generally emptied except for |
| 75 // information that must persist from one report to the next, such as |
| 76 // the "inconsistencies". |
| 77 struct SampleInfo { |
| 78 SampleInfo() : histogram(nullptr), |
| 79 accumulated_samples(nullptr), |
| 80 inconsistencies(0) {} |
| 81 |
| 82 // A histogram associated with this sample; it may be one of many if |
| 83 // several have been aggregated into the same "accumulated" sample set. |
| 84 // Ownership of the histogram remains elsewhere and this pointer is |
| 85 // cleared by FinishDeltas(). |
| 86 const HistogramBase* histogram; |
| 87 |
| 88 // The current snapshot-delta values being accumulated. |
| 89 // TODO(bcwhite): Change this to a scoped_ptr once all build architectures |
| 90 // support such as the value of a std::map. |
| 91 HistogramSamples* accumulated_samples; |
| 92 |
| 93 // The set of inconsistencies (flags) already seen for the histogram. |
| 94 // See HistogramBase::Inconsistency for values. |
| 95 uint32_t inconsistencies; |
| 96 }; |
| 97 |
| 98 // Capture and hold samples from a histogram. This does all the heavy |
| 99 // lifting for PrepareDelta() and PrepareAbsolute(). |
| 100 void PrepareSamples(const HistogramBase* histogram, |
| 101 scoped_ptr<HistogramSamples> samples); |
54 | 102 |
55 // Try to detect and fix count inconsistency of logged samples. | 103 // Try to detect and fix count inconsistency of logged samples. |
56 void InspectLoggedSamplesInconsistency( | 104 void InspectLoggedSamplesInconsistency( |
57 const HistogramSamples& new_snapshot, | 105 const HistogramSamples& new_snapshot, |
58 HistogramSamples* logged_samples); | 106 HistogramSamples* logged_samples); |
59 | 107 |
60 // For histograms, track what we've already recorded (as a sample for | 108 // For histograms, track what has been previously seen, indexed |
61 // each histogram) so that we can record only the delta with the next log. | 109 // by the hash of the histogram name. |
62 // The information is indexed by the hash of the histogram name. | 110 std::map<uint64_t, SampleInfo> known_histograms_; |
63 std::map<uint64_t, HistogramSamples*> logged_samples_; | |
64 | 111 |
65 // Set of histograms found to be corrupt and their problems, indexed | 112 // Indicates if deltas are currently being prepared. |
66 // by the hash of the histogram name. | 113 bool preparing_deltas_; |
67 std::map<uint64_t, int> inconsistencies_; | |
68 | 114 |
69 // |histogram_flattener_| handles the logistics of recording the histogram | 115 // |histogram_flattener_| handles the logistics of recording the histogram |
70 // deltas. | 116 // deltas. |
71 HistogramFlattener* histogram_flattener_; // Weak. | 117 HistogramFlattener* histogram_flattener_; // Weak. |
72 | 118 |
73 DISALLOW_COPY_AND_ASSIGN(HistogramSnapshotManager); | 119 DISALLOW_COPY_AND_ASSIGN(HistogramSnapshotManager); |
74 }; | 120 }; |
75 | 121 |
76 } // namespace base | 122 } // namespace base |
77 | 123 |
78 #endif // BASE_METRICS_HISTOGRAM_SNAPSHOT_MANAGER_H_ | 124 #endif // BASE_METRICS_HISTOGRAM_SNAPSHOT_MANAGER_H_ |
OLD | NEW |