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 // StatisticsRecorder holds all Histograms and BucketRanges that are used by 6 // Histograms in the system. It provides a general place for 7 // Histograms/BucketRanges to register, and supports a global API for accessing 8 // (i.e., dumping, or graphing) the data. 9 10 #ifndef BASE_METRICS_STATISTICS_RECORDER_H_ 11 #define BASE_METRICS_STATISTICS_RECORDER_H_ 12 13 #include <stdint.h> 14 15 #include <list> 16 #include <map> 17 #include <string> 18 #include <vector> 19 20 #include "base/base_export.h" 21 #include "base/callback.h" 22 #include "base/gtest_prod_util.h" 23 #include "base/lazy_instance.h" 24 #include "base/macros.h" 25 #include "base/metrics/histogram_base.h" 26 27 namespace base { 28 29 class BucketRanges; 30 class Lock; 31 32 class BASE_EXPORT StatisticsRecorder { 33 public: 34 typedef std::vector<HistogramBase*> Histograms; 35 36 // Initializes the StatisticsRecorder system. Safe to call multiple times. 37 static void Initialize(); 38 39 // Find out if histograms can now be registered into our list. 40 static bool IsActive(); 41 42 // Register, or add a new histogram to the collection of statistics. If an 43 // identically named histogram is already registered, then the argument 44 // |histogram| will deleted. The returned value is always the registered 45 // histogram (either the argument, or the pre-existing registered histogram). 46 static HistogramBase* RegisterOrDeleteDuplicate(HistogramBase* histogram); 47 48 // Register, or add a new BucketRanges. If an identically BucketRanges is 49 // already registered, then the argument |ranges| will deleted. The returned 50 // value is always the registered BucketRanges (either the argument, or the 51 // pre-existing one). 52 static const BucketRanges* RegisterOrDeleteDuplicateRanges( 53 const BucketRanges* ranges); 54 55 // Methods for appending histogram data to a string. Only histograms which 56 // have |query| as a substring are written to |output| (an empty string will 57 // process all registered histograms). 58 static void WriteHTMLGraph(const std::string& query, std::string* output); 59 static void WriteGraph(const std::string& query, std::string* output); 60 61 // Returns the histograms with |query| as a substring as JSON text (an empty 62 // |query| will process all registered histograms). 63 static std::string ToJSON(const std::string& query); 64 65 // Method for extracting histograms which were marked for use by UMA. 66 static void GetHistograms(Histograms* output); 67 68 // Method for extracting BucketRanges used by all histograms registered. 69 static void GetBucketRanges(std::vector<const BucketRanges*>* output); 70 71 // Find a histogram by name. It matches the exact name. This method is thread 72 // safe. It returns NULL if a matching histogram is not found. 73 static HistogramBase* FindHistogram(const std::string& name); 74 75 // GetSnapshot copies some of the pointers to registered histograms into the 76 // caller supplied vector (Histograms). Only histograms which have |query| as 77 // a substring are copied (an empty string will process all registered 78 // histograms). 79 static void GetSnapshot(const std::string& query, Histograms* snapshot); 80 81 typedef base::Callback<void(HistogramBase::Sample)> OnSampleCallback; 82 83 // SetCallback sets the callback to notify when a new sample is recorded on 84 // the histogram referred to by |histogram_name|. The call to this method can 85 // be be done before or after the histogram is created. This method is thread 86 // safe. The return value is whether or not the callback was successfully set. 87 static bool SetCallback(const std::string& histogram_name, 88 const OnSampleCallback& callback); 89 90 // ClearCallback clears any callback set on the histogram referred to by 91 // |histogram_name|. This method is thread safe. 92 static void ClearCallback(const std::string& histogram_name); 93 94 // FindCallback retrieves the callback for the histogram referred to by 95 // |histogram_name|, or a null callback if no callback exists for this 96 // histogram. This method is thread safe. 97 static OnSampleCallback FindCallback(const std::string& histogram_name); 98 99 private: 100 // We keep all registered histograms in a map, indexed by the hash of the 101 // name of the histogram. 102 typedef std::map<uint64_t, HistogramBase*> HistogramMap; 103 104 // We keep a map of callbacks to histograms, so that as histograms are 105 // created, we can set the callback properly. 106 typedef std::map<std::string, OnSampleCallback> CallbackMap; 107 108 // We keep all |bucket_ranges_| in a map, from checksum to a list of 109 // |bucket_ranges_|. Checksum is calculated from the |ranges_| in 110 // |bucket_ranges_|. 111 typedef std::map<uint32_t, std::list<const BucketRanges*>*> RangesMap; 112 113 friend struct DefaultLazyInstanceTraits<StatisticsRecorder>; 114 friend class HistogramBaseTest; 115 friend class HistogramSnapshotManagerTest; 116 friend class HistogramTest; 117 friend class JsonPrefStoreTest; 118 friend class SparseHistogramTest; 119 friend class StatisticsRecorderTest; 120 FRIEND_TEST_ALL_PREFIXES(HistogramDeltaSerializationTest, 121 DeserializeHistogramAndAddSamples); 122 123 // The constructor just initializes static members. Usually client code should 124 // use Initialize to do this. But in test code, you can friend this class and 125 // call destructor/constructor to get a clean StatisticsRecorder. 126 StatisticsRecorder(); 127 ~StatisticsRecorder(); 128 129 static void DumpHistogramsToVlog(void* instance); 130 131 static HistogramMap* histograms_; 132 static CallbackMap* callbacks_; 133 static RangesMap* ranges_; 134 135 // Lock protects access to above maps. 136 static base::Lock* lock_; 137 138 DISALLOW_COPY_AND_ASSIGN(StatisticsRecorder); 139 }; 140 141 } // namespace base 142 143 #endif // BASE_METRICS_STATISTICS_RECORDER_H_ 144