histogram_base.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  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. #ifndef BASE_METRICS_HISTOGRAM_BASE_H_
  5. #define BASE_METRICS_HISTOGRAM_BASE_H_
  6. #include <limits.h>
  7. #include <stddef.h>
  8. #include <stdint.h>
  9. #include <memory>
  10. #include <string>
  11. #include <vector>
  12. #include "base/atomicops.h"
  13. #include "base/base_export.h"
  14. #include "base/macros.h"
  15. #include "base/strings/string_piece.h"
  16. #include "base/time/time.h"
  17. #include "base/values.h"
  18. namespace base {
  19. class DictionaryValue;
  20. class HistogramBase;
  21. class HistogramSamples;
  22. class ListValue;
  23. class Pickle;
  24. class PickleIterator;
  25. ////////////////////////////////////////////////////////////////////////////////
  26. // This enum is used to facilitate deserialization of histograms from other
  27. // processes into the browser. If you create another class that inherits from
  28. // HistogramBase, add new histogram types and names below.
  29. enum HistogramType {
  30. HISTOGRAM,
  31. LINEAR_HISTOGRAM,
  32. BOOLEAN_HISTOGRAM,
  33. CUSTOM_HISTOGRAM,
  34. SPARSE_HISTOGRAM,
  35. DUMMY_HISTOGRAM,
  36. };
  37. // Controls the verbosity of the information when the histogram is serialized to
  38. // a JSON.
  39. // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.base.metrics
  40. enum JSONVerbosityLevel {
  41. // The histogram is completely serialized.
  42. JSON_VERBOSITY_LEVEL_FULL,
  43. // The bucket information is not serialized.
  44. JSON_VERBOSITY_LEVEL_OMIT_BUCKETS,
  45. };
  46. std::string HistogramTypeToString(HistogramType type);
  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. // Count the total number of histograms created. It is the limit against
  55. // which all others are compared.
  56. HISTOGRAM_REPORT_HISTOGRAM_CREATED = 1,
  57. // Count the total number of histograms looked-up. It's better to cache
  58. // the result of a single lookup rather than do it repeatedly.
  59. HISTOGRAM_REPORT_HISTOGRAM_LOOKUP = 2,
  60. // These count the individual histogram types. This must follow the order
  61. // of HistogramType above.
  62. HISTOGRAM_REPORT_TYPE_LOGARITHMIC = 3,
  63. HISTOGRAM_REPORT_TYPE_LINEAR = 4,
  64. HISTOGRAM_REPORT_TYPE_BOOLEAN = 5,
  65. HISTOGRAM_REPORT_TYPE_CUSTOM = 6,
  66. HISTOGRAM_REPORT_TYPE_SPARSE = 7,
  67. // These indicate the individual flags that were set.
  68. HISTOGRAM_REPORT_FLAG_UMA_TARGETED = 8,
  69. HISTOGRAM_REPORT_FLAG_UMA_STABILITY = 9,
  70. HISTOGRAM_REPORT_FLAG_PERSISTENT = 10,
  71. // This must be last.
  72. HISTOGRAM_REPORT_MAX = 11
  73. };
  74. // Create or find existing histogram that matches the pickled info.
  75. // Returns NULL if the pickled data has problems.
  76. BASE_EXPORT HistogramBase* DeserializeHistogramInfo(base::PickleIterator* iter);
  77. ////////////////////////////////////////////////////////////////////////////////
  78. class BASE_EXPORT HistogramBase {
  79. public:
  80. typedef int32_t Sample; // Used for samples.
  81. typedef subtle::Atomic32 AtomicCount; // Used to count samples.
  82. typedef int32_t Count; // Used to manipulate counts in temporaries.
  83. static const Sample kSampleType_MAX; // INT_MAX
  84. enum Flags {
  85. kNoFlags = 0x0,
  86. // Histogram should be UMA uploaded.
  87. kUmaTargetedHistogramFlag = 0x1,
  88. // Indicates that this is a stability histogram. This flag exists to specify
  89. // which histograms should be included in the initial stability log. Please
  90. // refer to |MetricsService::PrepareInitialStabilityLog|.
  91. kUmaStabilityHistogramFlag = kUmaTargetedHistogramFlag | 0x2,
  92. // Indicates that the histogram was pickled to be sent across an IPC
  93. // Channel. If we observe this flag on a histogram being aggregated into
  94. // after IPC, then we are running in a single process mode, and the
  95. // aggregation should not take place (as we would be aggregating back into
  96. // the source histogram!).
  97. kIPCSerializationSourceFlag = 0x10,
  98. // Indicates that a callback exists for when a new sample is recorded on
  99. // this histogram. We store this as a flag with the histogram since
  100. // histograms can be in performance critical code, and this allows us
  101. // to shortcut looking up the callback if it doesn't exist.
  102. kCallbackExists = 0x20,
  103. // Indicates that the histogram is held in "persistent" memory and may
  104. // be accessible between processes. This is only possible if such a
  105. // memory segment has been created/attached, used to create a Persistent-
  106. // MemoryAllocator, and that loaded into the Histogram module before this
  107. // histogram is created.
  108. kIsPersistent = 0x40,
  109. };
  110. // Histogram data inconsistency types.
  111. enum Inconsistency : uint32_t {
  112. NO_INCONSISTENCIES = 0x0,
  113. RANGE_CHECKSUM_ERROR = 0x1,
  114. BUCKET_ORDER_ERROR = 0x2,
  115. COUNT_HIGH_ERROR = 0x4,
  116. COUNT_LOW_ERROR = 0x8,
  117. NEVER_EXCEEDED_VALUE = 0x10,
  118. };
  119. // Construct the base histogram. The name is not copied; it's up to the
  120. // caller to ensure that it lives at least as long as this object.
  121. explicit HistogramBase(const char* name);
  122. virtual ~HistogramBase();
  123. const char* histogram_name() const { return histogram_name_; }
  124. // Compares |name| to the histogram name and triggers a DCHECK if they do not
  125. // match. This is a helper function used by histogram macros, which results in
  126. // in more compact machine code being generated by the macros.
  127. virtual void CheckName(const StringPiece& name) const;
  128. // Get a unique ID for this histogram's samples.
  129. virtual uint64_t name_hash() const = 0;
  130. // Operations with Flags enum.
  131. int32_t flags() const { return subtle::NoBarrier_Load(&flags_); }
  132. void SetFlags(int32_t flags);
  133. void ClearFlags(int32_t flags);
  134. virtual HistogramType GetHistogramType() const = 0;
  135. // Whether the histogram has construction arguments as parameters specified.
  136. // For histograms that don't have the concept of minimum, maximum or
  137. // bucket_count, this function always returns false.
  138. virtual bool HasConstructionArguments(
  139. Sample expected_minimum,
  140. Sample expected_maximum,
  141. uint32_t expected_bucket_count) const = 0;
  142. virtual void Add(Sample value) = 0;
  143. // In Add function the |value| bucket is increased by one, but in some use
  144. // cases we need to increase this value by an arbitrary integer. AddCount
  145. // function increases the |value| bucket by |count|. |count| should be greater
  146. // than or equal to 1.
  147. virtual void AddCount(Sample value, int count) = 0;
  148. // Similar to above but divides |count| by the |scale| amount. Probabilistic
  149. // rounding is used to yield a reasonably accurate total when many samples
  150. // are added. Methods for common cases of scales 1000 and 1024 are included.
  151. // The ScaledLinearHistogram (which can also used be for enumerations) may be
  152. // a better (and faster) solution.
  153. void AddScaled(Sample value, int count, int scale);
  154. void AddKilo(Sample value, int count); // scale=1000
  155. void AddKiB(Sample value, int count); // scale=1024
  156. // Convenient functions that call Add(Sample).
  157. void AddTime(const TimeDelta& time) { AddTimeMillisecondsGranularity(time); }
  158. void AddTimeMillisecondsGranularity(const TimeDelta& time);
  159. // Note: AddTimeMicrosecondsGranularity() drops the report if this client
  160. // doesn't have a high-resolution clock.
  161. void AddTimeMicrosecondsGranularity(const TimeDelta& time);
  162. void AddBoolean(bool value);
  163. virtual void AddSamples(const HistogramSamples& samples) = 0;
  164. virtual bool AddSamplesFromPickle(base::PickleIterator* iter) = 0;
  165. // Serialize the histogram info into |pickle|.
  166. // Note: This only serializes the construction arguments of the histogram, but
  167. // does not serialize the samples.
  168. void SerializeInfo(base::Pickle* pickle) const;
  169. // Try to find out data corruption from histogram and the samples.
  170. // The returned value is a combination of Inconsistency enum.
  171. virtual uint32_t FindCorruption(const HistogramSamples& samples) const;
  172. // Snapshot the current complete set of sample data.
  173. // Override with atomic/locked snapshot if needed.
  174. // NOTE: this data can overflow for long-running sessions. It should be
  175. // handled with care and this method is recommended to be used only
  176. // in about:histograms and test code.
  177. virtual std::unique_ptr<HistogramSamples> SnapshotSamples() const = 0;
  178. // Calculate the change (delta) in histogram counts since the previous call
  179. // to this method. Each successive call will return only those counts
  180. // changed since the last call.
  181. virtual std::unique_ptr<HistogramSamples> SnapshotDelta() = 0;
  182. // Calculate the change (delta) in histogram counts since the previous call
  183. // to SnapshotDelta() but do so without modifying any internal data as to
  184. // what was previous logged. After such a call, no further calls to this
  185. // method or to SnapshotDelta() should be done as the result would include
  186. // data previously returned. Because no internal data is changed, this call
  187. // can be made on "const" histograms such as those with data held in
  188. // read-only memory.
  189. virtual std::unique_ptr<HistogramSamples> SnapshotFinalDelta() const = 0;
  190. // The following method provides graphical histogram displays.
  191. virtual void WriteAscii(std::string* output) const = 0;
  192. // Returns histograms data as a Dict (or an empty dict if not available),
  193. // with the following format:
  194. // {"header": "Name of the histogram with samples, mean, and/or flags",
  195. // "body": "ASCII histogram representation"}
  196. virtual base::DictionaryValue ToGraphDict() const = 0;
  197. // TODO(bcwhite): Remove this after https://crbug/836875.
  198. virtual void ValidateHistogramContents() const;
  199. // Produce a JSON representation of the histogram with |verbosity_level| as
  200. // the serialization verbosity. This is implemented with the help of
  201. // GetParameters and GetCountAndBucketData; overwrite them to customize the
  202. // output.
  203. void WriteJSON(std::string* output, JSONVerbosityLevel verbosity_level) const;
  204. protected:
  205. enum ReportActivity { HISTOGRAM_CREATED, HISTOGRAM_LOOKUP };
  206. // Subclasses should implement this function to make SerializeInfo work.
  207. virtual void SerializeInfoImpl(base::Pickle* pickle) const = 0;
  208. // Writes information about the construction parameters in |params|.
  209. virtual void GetParameters(DictionaryValue* params) const = 0;
  210. // Writes information about the current (non-empty) buckets and their sample
  211. // counts to |buckets|, the total sample count to |count| and the total sum
  212. // to |sum|.
  213. void GetCountAndBucketData(Count* count,
  214. int64_t* sum,
  215. ListValue* buckets) const;
  216. //// Produce actual graph (set of blank vs non blank char's) for a bucket.
  217. void WriteAsciiBucketGraph(double current_size,
  218. double max_size,
  219. std::string* output) const;
  220. // Return a string description of what goes in a given bucket.
  221. const std::string GetSimpleAsciiBucketRange(Sample sample) const;
  222. // Write textual description of the bucket contents (relative to histogram).
  223. // Output is the count in the buckets, as well as the percentage.
  224. void WriteAsciiBucketValue(Count current,
  225. double scaled_sum,
  226. std::string* output) const;
  227. // Retrieves the callback for this histogram, if one exists, and runs it
  228. // passing |sample| as the parameter.
  229. void FindAndRunCallback(Sample sample) const;
  230. // Gets a permanent string that can be used for histogram objects when the
  231. // original is not a code constant or held in persistent memory.
  232. static const char* GetPermanentName(const std::string& name);
  233. private:
  234. friend class HistogramBaseTest;
  235. // A pointer to permanent storage where the histogram name is held. This can
  236. // be code space or the output of GetPermanentName() or any other storage
  237. // that is known to never change. This is not StringPiece because (a) char*
  238. // is 1/2 the size and (b) StringPiece transparently casts from std::string
  239. // which can easily lead to a pointer to non-permanent space.
  240. // For persistent histograms, this will simply point into the persistent
  241. // memory segment, thus avoiding duplication. For heap histograms, the
  242. // GetPermanentName method will create the necessary copy.
  243. const char* const histogram_name_;
  244. // Additional information about the histogram.
  245. AtomicCount flags_;
  246. DISALLOW_COPY_AND_ASSIGN(HistogramBase);
  247. };
  248. } // namespace base
  249. #endif // BASE_METRICS_HISTOGRAM_BASE_H_