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 unsigned inconsistencies; | |
Alexei Svitkine (slow)
2016/02/18 19:06:36
uint32_t
bcwhite
2016/02/18 19:33:55
Done.
| |
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 |