[email protected] | c884117b | 2012-07-19 05:31:49 | [diff] [blame] | 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 |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef BASE_METRICS_HISTOGRAM_BASE_H_ |
| 6 | #define BASE_METRICS_HISTOGRAM_BASE_H_ |
| 7 | |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 8 | #include <limits.h> |
| 9 | #include <stddef.h> |
isherman | bed49a6 | 2014-08-28 07:21:52 | [diff] [blame] | 10 | #include <stdint.h> |
| 11 | |
[email protected] | c884117b | 2012-07-19 05:31:49 | [diff] [blame] | 12 | #include <string> |
[email protected] | 6afa90f | 2013-10-23 01:16:04 | [diff] [blame] | 13 | #include <vector> |
[email protected] | c884117b | 2012-07-19 05:31:49 | [diff] [blame] | 14 | |
[email protected] | 9905345 | 2013-09-04 13:37:41 | [diff] [blame] | 15 | #include "base/atomicops.h" |
[email protected] | c884117b | 2012-07-19 05:31:49 | [diff] [blame] | 16 | #include "base/base_export.h" |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 17 | #include "base/macros.h" |
[email protected] | 877ef56 | 2012-10-20 02:56:18 | [diff] [blame] | 18 | #include "base/memory/scoped_ptr.h" |
[email protected] | 5bfd0a4 | 2014-02-15 03:11:45 | [diff] [blame] | 19 | #include "base/strings/string_piece.h" |
[email protected] | 99084f6 | 2013-06-28 00:49:07 | [diff] [blame] | 20 | #include "base/time/time.h" |
[email protected] | c884117b | 2012-07-19 05:31:49 | [diff] [blame] | 21 | |
| 22 | namespace base { |
| 23 | |
bcwhite | 5cb99eb | 2016-02-01 21:07:56 | [diff] [blame] | 24 | class BucketRanges; |
[email protected] | 24a7ec5e | 2012-10-08 10:31:50 | [diff] [blame] | 25 | class DictionaryValue; |
[email protected] | c50c21d | 2013-01-11 21:52:44 | [diff] [blame] | 26 | class HistogramBase; |
[email protected] | 07c0240 | 2012-10-31 06:20:25 | [diff] [blame] | 27 | class HistogramSamples; |
[email protected] | 24a7ec5e | 2012-10-08 10:31:50 | [diff] [blame] | 28 | class ListValue; |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame] | 29 | class Pickle; |
| 30 | class PickleIterator; |
[email protected] | 24a7ec5e | 2012-10-08 10:31:50 | [diff] [blame] | 31 | |
[email protected] | 07c0240 | 2012-10-31 06:20:25 | [diff] [blame] | 32 | //////////////////////////////////////////////////////////////////////////////// |
bcwhite | d723c25 | 2016-03-16 17:25:41 | [diff] [blame] | 33 | // This enum is used to facilitate deserialization of histograms from other |
[email protected] | 07c0240 | 2012-10-31 06:20:25 | [diff] [blame] | 34 | // processes into the browser. If you create another class that inherits from |
| 35 | // HistogramBase, add new histogram types and names below. |
| 36 | |
benwells | e574178 | 2015-07-06 18:18:41 | [diff] [blame] | 37 | enum HistogramType { |
[email protected] | 07c0240 | 2012-10-31 06:20:25 | [diff] [blame] | 38 | HISTOGRAM, |
| 39 | LINEAR_HISTOGRAM, |
| 40 | BOOLEAN_HISTOGRAM, |
| 41 | CUSTOM_HISTOGRAM, |
| 42 | SPARSE_HISTOGRAM, |
| 43 | }; |
| 44 | |
| 45 | std::string HistogramTypeToString(HistogramType type); |
| 46 | |
bcwhite | d723c25 | 2016-03-16 17:25:41 | [diff] [blame] | 47 | // This enum is used for reporting how many histograms and of what types and |
| 48 | // variations are being created. It has to be in the main .h file so it is |
| 49 | // visible to files that define the various histogram types. |
| 50 | enum HistogramReport { |
| 51 | // Count the number of reports created. The other counts divided by this |
| 52 | // number will give the average per run of the program. |
| 53 | HISTOGRAM_REPORT_CREATED = 0, |
| 54 | |
| 55 | // Count the total number of histograms created. It is the limit against |
| 56 | // which all others are compared. |
| 57 | HISTOGRAM_REPORT_HISTOGRAM_CREATED = 1, |
| 58 | |
| 59 | // Count the total number of histograms looked-up. It's better to cache |
| 60 | // the result of a single lookup rather than do it repeatedly. |
| 61 | HISTOGRAM_REPORT_HISTOGRAM_LOOKUP = 2, |
| 62 | |
| 63 | // These count the individual histogram types. This must follow the order |
| 64 | // of HistogramType above. |
| 65 | HISTOGRAM_REPORT_TYPE_LOGARITHMIC = 3, |
| 66 | HISTOGRAM_REPORT_TYPE_LINEAR = 4, |
| 67 | HISTOGRAM_REPORT_TYPE_BOOLEAN = 5, |
| 68 | HISTOGRAM_REPORT_TYPE_CUSTOM = 6, |
| 69 | HISTOGRAM_REPORT_TYPE_SPARSE = 7, |
| 70 | |
| 71 | // These indicate the individual flags that were set. |
| 72 | HISTOGRAM_REPORT_FLAG_UMA_TARGETED = 8, |
| 73 | HISTOGRAM_REPORT_FLAG_UMA_STABILITY = 9, |
| 74 | HISTOGRAM_REPORT_FLAG_PERSISTENT = 10, |
| 75 | |
| 76 | // This must be last. |
| 77 | HISTOGRAM_REPORT_MAX = 11 |
| 78 | }; |
| 79 | |
[email protected] | c50c21d | 2013-01-11 21:52:44 | [diff] [blame] | 80 | // Create or find existing histogram that matches the pickled info. |
| 81 | // Returns NULL if the pickled data has problems. |
xhwang | 3e9ca56 | 2015-11-06 18:50:36 | [diff] [blame] | 82 | BASE_EXPORT HistogramBase* DeserializeHistogramInfo(base::PickleIterator* iter); |
[email protected] | c50c21d | 2013-01-11 21:52:44 | [diff] [blame] | 83 | |
[email protected] | 07c0240 | 2012-10-31 06:20:25 | [diff] [blame] | 84 | //////////////////////////////////////////////////////////////////////////////// |
[email protected] | 877ef56 | 2012-10-20 02:56:18 | [diff] [blame] | 85 | |
[email protected] | c884117b | 2012-07-19 05:31:49 | [diff] [blame] | 86 | class BASE_EXPORT HistogramBase { |
| 87 | public: |
isherman | bed49a6 | 2014-08-28 07:21:52 | [diff] [blame] | 88 | typedef int32_t Sample; // Used for samples. |
[email protected] | 5bfd0a4 | 2014-02-15 03:11:45 | [diff] [blame] | 89 | typedef subtle::Atomic32 AtomicCount; // Used to count samples. |
isherman | bed49a6 | 2014-08-28 07:21:52 | [diff] [blame] | 90 | typedef int32_t Count; // Used to manipulate counts in temporaries. |
[email protected] | c884117b | 2012-07-19 05:31:49 | [diff] [blame] | 91 | |
[email protected] | 34d06232 | 2012-08-01 21:34:08 | [diff] [blame] | 92 | static const Sample kSampleType_MAX; // INT_MAX |
[email protected] | c884117b | 2012-07-19 05:31:49 | [diff] [blame] | 93 | |
[email protected] | 7c7a4275 | 2012-08-09 05:14:15 | [diff] [blame] | 94 | enum Flags { |
| 95 | kNoFlags = 0, |
[email protected] | 7c7a4275 | 2012-08-09 05:14:15 | [diff] [blame] | 96 | |
[email protected] | c778687a | 2014-02-11 14:46:45 | [diff] [blame] | 97 | // Histogram should be UMA uploaded. |
| 98 | kUmaTargetedHistogramFlag = 0x1, |
| 99 | |
| 100 | // Indicates that this is a stability histogram. This flag exists to specify |
| 101 | // which histograms should be included in the initial stability log. Please |
| 102 | // refer to |MetricsService::PrepareInitialStabilityLog|. |
| 103 | kUmaStabilityHistogramFlag = kUmaTargetedHistogramFlag | 0x2, |
| 104 | |
| 105 | // Indicates that the histogram was pickled to be sent across an IPC |
| 106 | // Channel. If we observe this flag on a histogram being aggregated into |
| 107 | // after IPC, then we are running in a single process mode, and the |
| 108 | // aggregation should not take place (as we would be aggregating back into |
| 109 | // the source histogram!). |
[email protected] | 7c7a4275 | 2012-08-09 05:14:15 | [diff] [blame] | 110 | kIPCSerializationSourceFlag = 0x10, |
| 111 | |
simonhatch | df5a814 | 2015-07-15 22:22:57 | [diff] [blame] | 112 | // Indicates that a callback exists for when a new sample is recorded on |
| 113 | // this histogram. We store this as a flag with the histogram since |
| 114 | // histograms can be in performance critical code, and this allows us |
| 115 | // to shortcut looking up the callback if it doesn't exist. |
| 116 | kCallbackExists = 0x20, |
| 117 | |
bcwhite | 5cb99eb | 2016-02-01 21:07:56 | [diff] [blame] | 118 | // Indicates that the histogram is held in "persistent" memory and may |
| 119 | // be accessible between processes. This is only possible if such a |
| 120 | // memory segment has been created/attached, used to create a Persistent- |
| 121 | // MemoryAllocator, and that loaded into the Histogram module before this |
| 122 | // histogram is created. |
| 123 | kIsPersistent = 0x40, |
| 124 | |
[email protected] | 7c7a4275 | 2012-08-09 05:14:15 | [diff] [blame] | 125 | // Only for Histogram and its sub classes: fancy bucket-naming support. |
| 126 | kHexRangePrintingFlag = 0x8000, |
| 127 | }; |
| 128 | |
[email protected] | cc7dec21 | 2013-03-01 03:53:25 | [diff] [blame] | 129 | // Histogram data inconsistency types. |
bcwhite | c85a1f82 | 2016-02-18 21:22:14 | [diff] [blame] | 130 | enum Inconsistency : uint32_t { |
[email protected] | cc7dec21 | 2013-03-01 03:53:25 | [diff] [blame] | 131 | NO_INCONSISTENCIES = 0x0, |
| 132 | RANGE_CHECKSUM_ERROR = 0x1, |
| 133 | BUCKET_ORDER_ERROR = 0x2, |
| 134 | COUNT_HIGH_ERROR = 0x4, |
| 135 | COUNT_LOW_ERROR = 0x8, |
| 136 | |
bcwhite | c85a1f82 | 2016-02-18 21:22:14 | [diff] [blame] | 137 | NEVER_EXCEEDED_VALUE = 0x10, |
| 138 | |
| 139 | // This value is used only in HistogramSnapshotManager for marking |
| 140 | // internally when new inconsistencies are found. |
| 141 | NEW_INCONSISTENCY_FOUND = 0x8000000 |
[email protected] | cc7dec21 | 2013-03-01 03:53:25 | [diff] [blame] | 142 | }; |
| 143 | |
[email protected] | f3c697c5 | 2013-01-15 10:52:11 | [diff] [blame] | 144 | explicit HistogramBase(const std::string& name); |
[email protected] | c884117b | 2012-07-19 05:31:49 | [diff] [blame] | 145 | virtual ~HistogramBase(); |
| 146 | |
asvitkine | 33d9fd6 | 2015-06-15 22:36:22 | [diff] [blame] | 147 | const std::string& histogram_name() const { return histogram_name_; } |
[email protected] | c884117b | 2012-07-19 05:31:49 | [diff] [blame] | 148 | |
[email protected] | 5bfd0a4 | 2014-02-15 03:11:45 | [diff] [blame] | 149 | // Comapres |name| to the histogram name and triggers a DCHECK if they do not |
| 150 | // match. This is a helper function used by histogram macros, which results in |
| 151 | // in more compact machine code being generated by the macros. |
| 152 | void CheckName(const StringPiece& name) const; |
| 153 | |
bcwhite | b036e432 | 2015-12-10 18:36:34 | [diff] [blame] | 154 | // Get a unique ID for this histogram's samples. |
| 155 | virtual uint64_t name_hash() const = 0; |
| 156 | |
[email protected] | 7c7a4275 | 2012-08-09 05:14:15 | [diff] [blame] | 157 | // Operations with Flags enum. |
asvitkine | a74e3d5 | 2015-11-20 02:37:56 | [diff] [blame] | 158 | int32_t flags() const { return subtle::NoBarrier_Load(&flags_); } |
isherman | bed49a6 | 2014-08-28 07:21:52 | [diff] [blame] | 159 | void SetFlags(int32_t flags); |
| 160 | void ClearFlags(int32_t flags); |
[email protected] | 7c7a4275 | 2012-08-09 05:14:15 | [diff] [blame] | 161 | |
[email protected] | 07c0240 | 2012-10-31 06:20:25 | [diff] [blame] | 162 | virtual HistogramType GetHistogramType() const = 0; |
| 163 | |
[email protected] | abae9b02 | 2012-10-24 08:18:52 | [diff] [blame] | 164 | // Whether the histogram has construction arguments as parameters specified. |
[email protected] | 15ce384 | 2013-06-27 14:38:45 | [diff] [blame] | 165 | // For histograms that don't have the concept of minimum, maximum or |
| 166 | // bucket_count, this function always returns false. |
jam | 1eacd7e | 2016-02-08 22:48:16 | [diff] [blame] | 167 | virtual bool HasConstructionArguments( |
| 168 | Sample expected_minimum, |
| 169 | Sample expected_maximum, |
| 170 | uint32_t expected_bucket_count) const = 0; |
[email protected] | abae9b02 | 2012-10-24 08:18:52 | [diff] [blame] | 171 | |
[email protected] | c884117b | 2012-07-19 05:31:49 | [diff] [blame] | 172 | virtual void Add(Sample value) = 0; |
| 173 | |
amohammadkhan | 6779b5c3 | 2015-08-05 20:31:11 | [diff] [blame] | 174 | // In Add function the |value| bucket is increased by one, but in some use |
| 175 | // cases we need to increase this value by an arbitrary integer. AddCount |
| 176 | // function increases the |value| bucket by |count|. |count| should be greater |
| 177 | // than or equal to 1. |
| 178 | virtual void AddCount(Sample value, int count) = 0; |
| 179 | |
[email protected] | de41555 | 2013-01-23 04:12:17 | [diff] [blame] | 180 | // 2 convenient functions that call Add(Sample). |
| 181 | void AddTime(const TimeDelta& time); |
| 182 | void AddBoolean(bool value); |
| 183 | |
[email protected] | c50c21d | 2013-01-11 21:52:44 | [diff] [blame] | 184 | virtual void AddSamples(const HistogramSamples& samples) = 0; |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame] | 185 | virtual bool AddSamplesFromPickle(base::PickleIterator* iter) = 0; |
[email protected] | c50c21d | 2013-01-11 21:52:44 | [diff] [blame] | 186 | |
| 187 | // Serialize the histogram info into |pickle|. |
| 188 | // Note: This only serializes the construction arguments of the histogram, but |
| 189 | // does not serialize the samples. |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame] | 190 | bool SerializeInfo(base::Pickle* pickle) const; |
[email protected] | c50c21d | 2013-01-11 21:52:44 | [diff] [blame] | 191 | |
[email protected] | cc7dec21 | 2013-03-01 03:53:25 | [diff] [blame] | 192 | // Try to find out data corruption from histogram and the samples. |
| 193 | // The returned value is a combination of Inconsistency enum. |
bcwhite | c85a1f82 | 2016-02-18 21:22:14 | [diff] [blame] | 194 | virtual uint32_t FindCorruption(const HistogramSamples& samples) const; |
[email protected] | cc7dec21 | 2013-03-01 03:53:25 | [diff] [blame] | 195 | |
[email protected] | abae9b02 | 2012-10-24 08:18:52 | [diff] [blame] | 196 | // Snapshot the current complete set of sample data. |
| 197 | // Override with atomic/locked snapshot if needed. |
[email protected] | 877ef56 | 2012-10-20 02:56:18 | [diff] [blame] | 198 | virtual scoped_ptr<HistogramSamples> SnapshotSamples() const = 0; |
| 199 | |
bcwhite | c85a1f82 | 2016-02-18 21:22:14 | [diff] [blame] | 200 | // Calculate the change (delta) in histogram counts since the previous call |
| 201 | // to this method. Each successive call will return only those counts |
| 202 | // changed since the last call. |
| 203 | virtual scoped_ptr<HistogramSamples> SnapshotDelta() = 0; |
| 204 | |
[email protected] | c884117b | 2012-07-19 05:31:49 | [diff] [blame] | 205 | // The following methods provide graphical histogram displays. |
| 206 | virtual void WriteHTMLGraph(std::string* output) const = 0; |
| 207 | virtual void WriteAscii(std::string* output) const = 0; |
| 208 | |
[email protected] | 24a7ec5e | 2012-10-08 10:31:50 | [diff] [blame] | 209 | // Produce a JSON representation of the histogram. This is implemented with |
| 210 | // the help of GetParameters and GetCountAndBucketData; overwrite them to |
| 211 | // customize the output. |
| 212 | void WriteJSON(std::string* output) const; |
| 213 | |
bcwhite | d723c25 | 2016-03-16 17:25:41 | [diff] [blame] | 214 | // This enables a histogram that reports the what types of histograms are |
| 215 | // created and their flags. It must be called while still single-threaded. |
| 216 | // |
| 217 | // IMPORTANT: Callers must update tools/metrics/histograms/histograms.xml |
| 218 | // with the following histogram: |
| 219 | // UMA.Histograms.process_type.Creations |
| 220 | static void EnableActivityReportHistogram(const std::string& process_type); |
| 221 | |
[email protected] | 5bfd0a4 | 2014-02-15 03:11:45 | [diff] [blame] | 222 | protected: |
bcwhite | d723c25 | 2016-03-16 17:25:41 | [diff] [blame] | 223 | enum ReportActivity { HISTOGRAM_CREATED, HISTOGRAM_LOOKUP }; |
| 224 | |
[email protected] | c50c21d | 2013-01-11 21:52:44 | [diff] [blame] | 225 | // Subclasses should implement this function to make SerializeInfo work. |
brettw | 05cfd8ddb | 2015-06-02 07:02:47 | [diff] [blame] | 226 | virtual bool SerializeInfoImpl(base::Pickle* pickle) const = 0; |
[email protected] | c50c21d | 2013-01-11 21:52:44 | [diff] [blame] | 227 | |
[email protected] | 24a7ec5e | 2012-10-08 10:31:50 | [diff] [blame] | 228 | // Writes information about the construction parameters in |params|. |
| 229 | virtual void GetParameters(DictionaryValue* params) const = 0; |
| 230 | |
| 231 | // Writes information about the current (non-empty) buckets and their sample |
[email protected] | cdd98fc | 2013-05-10 09:32:58 | [diff] [blame] | 232 | // counts to |buckets|, the total sample count to |count| and the total sum |
| 233 | // to |sum|. |
[email protected] | 24a7ec5e | 2012-10-08 10:31:50 | [diff] [blame] | 234 | virtual void GetCountAndBucketData(Count* count, |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 235 | int64_t* sum, |
[email protected] | 24a7ec5e | 2012-10-08 10:31:50 | [diff] [blame] | 236 | ListValue* buckets) const = 0; |
[email protected] | f2bb320 | 2013-04-05 21:21:54 | [diff] [blame] | 237 | |
| 238 | //// Produce actual graph (set of blank vs non blank char's) for a bucket. |
| 239 | void WriteAsciiBucketGraph(double current_size, |
| 240 | double max_size, |
| 241 | std::string* output) const; |
| 242 | |
| 243 | // Return a string description of what goes in a given bucket. |
| 244 | const std::string GetSimpleAsciiBucketRange(Sample sample) const; |
| 245 | |
| 246 | // Write textual description of the bucket contents (relative to histogram). |
| 247 | // Output is the count in the buckets, as well as the percentage. |
| 248 | void WriteAsciiBucketValue(Count current, |
| 249 | double scaled_sum, |
| 250 | std::string* output) const; |
| 251 | |
simonhatch | df5a814 | 2015-07-15 22:22:57 | [diff] [blame] | 252 | // Retrieves the callback for this histogram, if one exists, and runs it |
| 253 | // passing |sample| as the parameter. |
| 254 | void FindAndRunCallback(Sample sample) const; |
| 255 | |
bcwhite | d723c25 | 2016-03-16 17:25:41 | [diff] [blame] | 256 | // Update report with an |activity| that occurred for |histogram|. |
| 257 | static void ReportHistogramActivity(const HistogramBase& histogram, |
| 258 | ReportActivity activicty); |
| 259 | |
| 260 | // Retrieves the global histogram reporting what histograms are created. |
| 261 | static HistogramBase* report_histogram_; |
| 262 | |
[email protected] | c884117b | 2012-07-19 05:31:49 | [diff] [blame] | 263 | private: |
bcwhite | d723c25 | 2016-03-16 17:25:41 | [diff] [blame] | 264 | friend class HistogramBaseTest; |
| 265 | |
[email protected] | c884117b | 2012-07-19 05:31:49 | [diff] [blame] | 266 | const std::string histogram_name_; |
asvitkine | a74e3d5 | 2015-11-20 02:37:56 | [diff] [blame] | 267 | AtomicCount flags_; |
[email protected] | 7c7a4275 | 2012-08-09 05:14:15 | [diff] [blame] | 268 | |
| 269 | DISALLOW_COPY_AND_ASSIGN(HistogramBase); |
[email protected] | c884117b | 2012-07-19 05:31:49 | [diff] [blame] | 270 | }; |
| 271 | |
| 272 | } // namespace base |
| 273 | |
| 274 | #endif // BASE_METRICS_HISTOGRAM_BASE_H_ |