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 8 #include <limits.h> 9 #include <stddef.h> 10 #include <stdint.h> 11 12 #include <string> 13 #include <vector> 14 15 #include "base/atomicops.h" 16 #include "base/base_export.h" 17 #include "base/macros.h" 18 #include "base/memory/scoped_ptr.h" 19 #include "base/strings/string_piece.h" 20 #include "base/time/time.h" 21 22 namespace base { 23 24 class DictionaryValue; 25 class HistogramBase; 26 class HistogramSamples; 27 class ListValue; 28 class Pickle; 29 class PickleIterator; 30 31 //////////////////////////////////////////////////////////////////////////////// 32 // These enums are used to facilitate deserialization of histograms from other 33 // processes into the browser. If you create another class that inherits from 34 // HistogramBase, add new histogram types and names below. 35 36 enum HistogramType { 37 HISTOGRAM, 38 LINEAR_HISTOGRAM, 39 BOOLEAN_HISTOGRAM, 40 CUSTOM_HISTOGRAM, 41 SPARSE_HISTOGRAM, 42 }; 43 44 std::string HistogramTypeToString(HistogramType type); 45 46 // Create or find existing histogram that matches the pickled info. 47 // Returns NULL if the pickled data has problems. 48 BASE_EXPORT HistogramBase* DeserializeHistogramInfo(base::PickleIterator* iter); 49 50 //////////////////////////////////////////////////////////////////////////////// 51 52 class BASE_EXPORT HistogramBase { 53 public: 54 typedef int32_t Sample; // Used for samples. 55 typedef subtle::Atomic32 AtomicCount; // Used to count samples. 56 typedef int32_t Count; // Used to manipulate counts in temporaries. 57 58 static const Sample kSampleType_MAX; // INT_MAX 59 60 enum Flags { 61 kNoFlags = 0, 62 63 // Histogram should be UMA uploaded. 64 kUmaTargetedHistogramFlag = 0x1, 65 66 // Indicates that this is a stability histogram. This flag exists to specify 67 // which histograms should be included in the initial stability log. Please 68 // refer to |MetricsService::PrepareInitialStabilityLog|. 69 kUmaStabilityHistogramFlag = kUmaTargetedHistogramFlag | 0x2, 70 71 // Indicates that the histogram was pickled to be sent across an IPC 72 // Channel. If we observe this flag on a histogram being aggregated into 73 // after IPC, then we are running in a single process mode, and the 74 // aggregation should not take place (as we would be aggregating back into 75 // the source histogram!). 76 kIPCSerializationSourceFlag = 0x10, 77 78 // Indicates that a callback exists for when a new sample is recorded on 79 // this histogram. We store this as a flag with the histogram since 80 // histograms can be in performance critical code, and this allows us 81 // to shortcut looking up the callback if it doesn't exist. 82 kCallbackExists = 0x20, 83 84 // Only for Histogram and its sub classes: fancy bucket-naming support. 85 kHexRangePrintingFlag = 0x8000, 86 }; 87 88 // Histogram data inconsistency types. 89 enum Inconsistency { 90 NO_INCONSISTENCIES = 0x0, 91 RANGE_CHECKSUM_ERROR = 0x1, 92 BUCKET_ORDER_ERROR = 0x2, 93 COUNT_HIGH_ERROR = 0x4, 94 COUNT_LOW_ERROR = 0x8, 95 96 NEVER_EXCEEDED_VALUE = 0x10 97 }; 98 99 explicit HistogramBase(const std::string& name); 100 virtual ~HistogramBase(); 101 histogram_name()102 const std::string& histogram_name() const { return histogram_name_; } 103 104 // Comapres |name| to the histogram name and triggers a DCHECK if they do not 105 // match. This is a helper function used by histogram macros, which results in 106 // in more compact machine code being generated by the macros. 107 void CheckName(const StringPiece& name) const; 108 109 // Get a unique ID for this histogram's samples. 110 virtual uint64_t name_hash() const = 0; 111 112 // Operations with Flags enum. flags()113 int32_t flags() const { return subtle::NoBarrier_Load(&flags_); } 114 void SetFlags(int32_t flags); 115 void ClearFlags(int32_t flags); 116 117 virtual HistogramType GetHistogramType() const = 0; 118 119 // Whether the histogram has construction arguments as parameters specified. 120 // For histograms that don't have the concept of minimum, maximum or 121 // bucket_count, this function always returns false. 122 virtual bool HasConstructionArguments(Sample expected_minimum, 123 Sample expected_maximum, 124 size_t expected_bucket_count) const = 0; 125 126 virtual void Add(Sample value) = 0; 127 128 // In Add function the |value| bucket is increased by one, but in some use 129 // cases we need to increase this value by an arbitrary integer. AddCount 130 // function increases the |value| bucket by |count|. |count| should be greater 131 // than or equal to 1. 132 virtual void AddCount(Sample value, int count) = 0; 133 134 // 2 convenient functions that call Add(Sample). 135 void AddTime(const TimeDelta& time); 136 void AddBoolean(bool value); 137 138 virtual void AddSamples(const HistogramSamples& samples) = 0; 139 virtual bool AddSamplesFromPickle(base::PickleIterator* iter) = 0; 140 141 // Serialize the histogram info into |pickle|. 142 // Note: This only serializes the construction arguments of the histogram, but 143 // does not serialize the samples. 144 bool SerializeInfo(base::Pickle* pickle) const; 145 146 // Try to find out data corruption from histogram and the samples. 147 // The returned value is a combination of Inconsistency enum. 148 virtual int FindCorruption(const HistogramSamples& samples) const; 149 150 // Snapshot the current complete set of sample data. 151 // Override with atomic/locked snapshot if needed. 152 virtual scoped_ptr<HistogramSamples> SnapshotSamples() const = 0; 153 154 // The following methods provide graphical histogram displays. 155 virtual void WriteHTMLGraph(std::string* output) const = 0; 156 virtual void WriteAscii(std::string* output) const = 0; 157 158 // Produce a JSON representation of the histogram. This is implemented with 159 // the help of GetParameters and GetCountAndBucketData; overwrite them to 160 // customize the output. 161 void WriteJSON(std::string* output) const; 162 163 protected: 164 // Subclasses should implement this function to make SerializeInfo work. 165 virtual bool SerializeInfoImpl(base::Pickle* pickle) const = 0; 166 167 // Writes information about the construction parameters in |params|. 168 virtual void GetParameters(DictionaryValue* params) const = 0; 169 170 // Writes information about the current (non-empty) buckets and their sample 171 // counts to |buckets|, the total sample count to |count| and the total sum 172 // to |sum|. 173 virtual void GetCountAndBucketData(Count* count, 174 int64_t* sum, 175 ListValue* buckets) const = 0; 176 177 //// Produce actual graph (set of blank vs non blank char's) for a bucket. 178 void WriteAsciiBucketGraph(double current_size, 179 double max_size, 180 std::string* output) const; 181 182 // Return a string description of what goes in a given bucket. 183 const std::string GetSimpleAsciiBucketRange(Sample sample) const; 184 185 // Write textual description of the bucket contents (relative to histogram). 186 // Output is the count in the buckets, as well as the percentage. 187 void WriteAsciiBucketValue(Count current, 188 double scaled_sum, 189 std::string* output) const; 190 191 // Retrieves the callback for this histogram, if one exists, and runs it 192 // passing |sample| as the parameter. 193 void FindAndRunCallback(Sample sample) const; 194 195 private: 196 const std::string histogram_name_; 197 AtomicCount flags_; 198 199 DISALLOW_COPY_AND_ASSIGN(HistogramBase); 200 }; 201 202 } // namespace base 203 204 #endif // BASE_METRICS_HISTOGRAM_BASE_H_ 205