15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_METRICS_HISTOGRAM_BASE_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_METRICS_HISTOGRAM_BASE_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/atomicops.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_export.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_piece.h"
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class Pickle;
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PickleIterator;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DictionaryValue;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class HistogramBase;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HistogramSamples;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ListValue;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These enums are used to facilitate deserialization of histograms from other
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// processes into the browser. If you create another class that inherits from
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HistogramBase, add new histogram types and names below.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum BASE_EXPORT HistogramType {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HISTOGRAM,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LINEAR_HISTOGRAM,
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BOOLEAN_HISTOGRAM,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CUSTOM_HISTOGRAM,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SPARSE_HISTOGRAM,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string HistogramTypeToString(HistogramType type);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Create or find existing histogram that matches the pickled info.
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns NULL if the pickled data has problems.
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BASE_EXPORT_PRIVATE HistogramBase* DeserializeHistogramInfo(
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PickleIterator* iter);
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT HistogramBase {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef int Sample;                    // Used for samples.
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef subtle::Atomic32 AtomicCount;  // Used to count samples.
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef int32 Count;  // Used to manipulate counts in temporaries.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const Sample kSampleType_MAX;  // INT_MAX
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum Flags {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kNoFlags = 0,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Histogram should be UMA uploaded.
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    kUmaTargetedHistogramFlag = 0x1,
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Indicates that this is a stability histogram. This flag exists to specify
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // which histograms should be included in the initial stability log. Please
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // refer to |MetricsService::PrepareInitialStabilityLog|.
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    kUmaStabilityHistogramFlag = kUmaTargetedHistogramFlag | 0x2,
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Indicates that the histogram was pickled to be sent across an IPC
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Channel. If we observe this flag on a histogram being aggregated into
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // after IPC, then we are running in a single process mode, and the
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // aggregation should not take place (as we would be aggregating back into
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // the source histogram!).
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kIPCSerializationSourceFlag = 0x10,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Only for Histogram and its sub classes: fancy bucket-naming support.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kHexRangePrintingFlag = 0x8000,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Histogram data inconsistency types.
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum Inconsistency {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NO_INCONSISTENCIES = 0x0,
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RANGE_CHECKSUM_ERROR = 0x1,
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BUCKET_ORDER_ERROR = 0x2,
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    COUNT_HIGH_ERROR = 0x4,
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    COUNT_LOW_ERROR = 0x8,
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NEVER_EXCEEDED_VALUE = 0x10
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit HistogramBase(const std::string& name);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~HistogramBase();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string histogram_name() const { return histogram_name_; }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Comapres |name| to the histogram name and triggers a DCHECK if they do not
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // match. This is a helper function used by histogram macros, which results in
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // in more compact machine code being generated by the macros.
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void CheckName(const StringPiece& name) const;
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Operations with Flags enum.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 flags() const { return flags_; }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetFlags(int32 flags);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ClearFlags(int32 flags);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual HistogramType GetHistogramType() const = 0;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Whether the histogram has construction arguments as parameters specified.
109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // For histograms that don't have the concept of minimum, maximum or
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // bucket_count, this function always returns false.
111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual bool HasConstructionArguments(Sample expected_minimum,
112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        Sample expected_maximum,
113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                        size_t expected_bucket_count) const = 0;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Add(Sample value) = 0;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 2 convenient functions that call Add(Sample).
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddTime(const TimeDelta& time);
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddBoolean(bool value);
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddSamples(const HistogramSamples& samples) = 0;
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool AddSamplesFromPickle(PickleIterator* iter) = 0;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Serialize the histogram info into |pickle|.
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Note: This only serializes the construction arguments of the histogram, but
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // does not serialize the samples.
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool SerializeInfo(Pickle* pickle) const;
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Try to find out data corruption from histogram and the samples.
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The returned value is a combination of Inconsistency enum.
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual int FindCorruption(const HistogramSamples& samples) const;
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Snapshot the current complete set of sample data.
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Override with atomic/locked snapshot if needed.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual scoped_ptr<HistogramSamples> SnapshotSamples() const = 0;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The following methods provide graphical histogram displays.
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void WriteHTMLGraph(std::string* output) const = 0;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void WriteAscii(std::string* output) const = 0;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Produce a JSON representation of the histogram. This is implemented with
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the help of GetParameters and GetCountAndBucketData; overwrite them to
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // customize the output.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WriteJSON(std::string* output) const;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Subclasses should implement this function to make SerializeInfo work.
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool SerializeInfoImpl(Pickle* pickle) const = 0;
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Writes information about the construction parameters in |params|.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetParameters(DictionaryValue* params) const = 0;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Writes information about the current (non-empty) buckets and their sample
154b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // counts to |buckets|, the total sample count to |count| and the total sum
155b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // to |sum|.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetCountAndBucketData(Count* count,
157b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                     int64* sum,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ListValue* buckets) const = 0;
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //// Produce actual graph (set of blank vs non blank char's) for a bucket.
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void WriteAsciiBucketGraph(double current_size,
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             double max_size,
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             std::string* output) const;
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Return a string description of what goes in a given bucket.
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const std::string GetSimpleAsciiBucketRange(Sample sample) const;
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Write textual description of the bucket contents (relative to histogram).
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Output is the count in the buckets, as well as the percentage.
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void WriteAsciiBucketValue(Count current,
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             double scaled_sum,
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             std::string* output) const;
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string histogram_name_;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 flags_;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(HistogramBase);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_METRICS_HISTOGRAM_BASE_H_
184