1 // 2 // Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 // 4 // Use of this source code is governed by a BSD-style license 5 // that can be found in the LICENSE file in the root of the source 6 // tree. An additional intellectual property rights grant can be found 7 // in the file PATENTS. All contributing project authors may 8 // be found in the AUTHORS file in the root of the source tree. 9 // 10 11 #ifndef WEBRTC_SYSTEM_WRAPPERS_INCLUDE_METRICS_H_ 12 #define WEBRTC_SYSTEM_WRAPPERS_INCLUDE_METRICS_H_ 13 14 #include <string> 15 16 #include "webrtc/base/atomicops.h" 17 #include "webrtc/base/checks.h" 18 #include "webrtc/common_types.h" 19 20 // Macros for allowing WebRTC clients (e.g. Chrome) to gather and aggregate 21 // statistics. 22 // 23 // Histogram for counters. 24 // RTC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count); 25 // 26 // Histogram for enumerators. 27 // The boundary should be above the max enumerator sample. 28 // RTC_HISTOGRAM_ENUMERATION(name, sample, boundary); 29 // 30 // 31 // The macros use the methods HistogramFactoryGetCounts, 32 // HistogramFactoryGetEnumeration and HistogramAdd. 33 // 34 // Therefore, WebRTC clients must either: 35 // 36 // - provide implementations of 37 // Histogram* webrtc::metrics::HistogramFactoryGetCounts( 38 // const std::string& name, int sample, int min, int max, 39 // int bucket_count); 40 // Histogram* webrtc::metrics::HistogramFactoryGetEnumeration( 41 // const std::string& name, int sample, int boundary); 42 // void webrtc::metrics::HistogramAdd( 43 // Histogram* histogram_pointer, const std::string& name, int sample); 44 // 45 // - or link with the default implementations (i.e. 46 // system_wrappers/system_wrappers.gyp:metrics_default). 47 // 48 // 49 // Example usage: 50 // 51 // RTC_HISTOGRAM_COUNTS("WebRTC.Video.NacksSent", nacks_sent, 1, 100000, 100); 52 // 53 // enum Types { 54 // kTypeX, 55 // kTypeY, 56 // kBoundary, 57 // }; 58 // 59 // RTC_HISTOGRAM_ENUMERATION("WebRTC.Types", kTypeX, kBoundary); 60 61 62 // Macros for adding samples to a named histogram. 63 64 // Histogram for counters (exponentially spaced buckets). 65 #define RTC_HISTOGRAM_COUNTS_100(name, sample) \ 66 RTC_HISTOGRAM_COUNTS(name, sample, 1, 100, 50) 67 68 #define RTC_HISTOGRAM_COUNTS_200(name, sample) \ 69 RTC_HISTOGRAM_COUNTS(name, sample, 1, 200, 50) 70 71 #define RTC_HISTOGRAM_COUNTS_1000(name, sample) \ 72 RTC_HISTOGRAM_COUNTS(name, sample, 1, 1000, 50) 73 74 #define RTC_HISTOGRAM_COUNTS_10000(name, sample) \ 75 RTC_HISTOGRAM_COUNTS(name, sample, 1, 10000, 50) 76 77 #define RTC_HISTOGRAM_COUNTS_100000(name, sample) \ 78 RTC_HISTOGRAM_COUNTS(name, sample, 1, 100000, 50) 79 80 #define RTC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count) \ 81 RTC_HISTOGRAM_COMMON_BLOCK(name, sample, \ 82 webrtc::metrics::HistogramFactoryGetCounts(name, min, max, bucket_count)) 83 84 // Deprecated. 85 // TODO(asapersson): Remove. 86 #define RTC_HISTOGRAM_COUNTS_SPARSE_100(name, sample) \ 87 RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 100, 50) 88 89 #define RTC_HISTOGRAM_COUNTS_SPARSE_200(name, sample) \ 90 RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 200, 50) 91 92 #define RTC_HISTOGRAM_COUNTS_SPARSE_1000(name, sample) \ 93 RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 1000, 50) 94 95 #define RTC_HISTOGRAM_COUNTS_SPARSE_10000(name, sample) \ 96 RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 10000, 50) 97 98 #define RTC_HISTOGRAM_COUNTS_SPARSE_100000(name, sample) \ 99 RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 100000, 50) 100 101 #define RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, min, max, bucket_count) \ 102 RTC_HISTOGRAM_COMMON_BLOCK_SLOW(name, sample, \ 103 webrtc::metrics::HistogramFactoryGetCounts(name, min, max, bucket_count)) 104 105 // Histogram for percentage (evenly spaced buckets). 106 #define RTC_HISTOGRAM_PERCENTAGE(name, sample) \ 107 RTC_HISTOGRAM_ENUMERATION(name, sample, 101) 108 109 // Deprecated. 110 // TODO(asapersson): Remove. 111 #define RTC_HISTOGRAM_PERCENTAGE_SPARSE(name, sample) \ 112 RTC_HISTOGRAM_ENUMERATION_SPARSE(name, sample, 101) 113 114 // Histogram for enumerators (evenly spaced buckets). 115 // |boundary| should be above the max enumerator sample. 116 #define RTC_HISTOGRAM_ENUMERATION(name, sample, boundary) \ 117 RTC_HISTOGRAM_COMMON_BLOCK(name, sample, \ 118 webrtc::metrics::HistogramFactoryGetEnumeration(name, boundary)) 119 120 // Deprecated. 121 // TODO(asapersson): Remove. 122 #define RTC_HISTOGRAM_ENUMERATION_SPARSE(name, sample, boundary) \ 123 RTC_HISTOGRAM_COMMON_BLOCK_SLOW(name, sample, \ 124 webrtc::metrics::HistogramFactoryGetEnumeration(name, boundary)) 125 126 // The name of the histogram should not vary. 127 // TODO(asapersson): Consider changing string to const char*. 128 #define RTC_HISTOGRAM_COMMON_BLOCK(constant_name, sample, \ 129 factory_get_invocation) \ 130 do { \ 131 static webrtc::metrics::Histogram* atomic_histogram_pointer = nullptr; \ 132 webrtc::metrics::Histogram* histogram_pointer = \ 133 rtc::AtomicOps::AcquireLoadPtr(&atomic_histogram_pointer); \ 134 if (!histogram_pointer) { \ 135 histogram_pointer = factory_get_invocation; \ 136 webrtc::metrics::Histogram* prev_pointer = \ 137 rtc::AtomicOps::CompareAndSwapPtr( \ 138 &atomic_histogram_pointer, \ 139 static_cast<webrtc::metrics::Histogram*>(nullptr), \ 140 histogram_pointer); \ 141 RTC_DCHECK(prev_pointer == nullptr || \ 142 prev_pointer == histogram_pointer); \ 143 } \ 144 webrtc::metrics::HistogramAdd(histogram_pointer, constant_name, sample); \ 145 } while (0) 146 147 // Deprecated. 148 // The histogram is constructed/found for each call. 149 // May be used for histograms with infrequent updates. 150 #define RTC_HISTOGRAM_COMMON_BLOCK_SLOW(name, sample, factory_get_invocation) \ 151 do { \ 152 webrtc::metrics::Histogram* histogram_pointer = factory_get_invocation; \ 153 webrtc::metrics::HistogramAdd(histogram_pointer, name, sample); \ 154 } while (0) 155 156 namespace webrtc { 157 namespace metrics { 158 159 // Time that should have elapsed for stats that are gathered once per call. 160 enum { kMinRunTimeInSeconds = 10 }; 161 162 class Histogram; 163 164 // Functions for getting pointer to histogram (constructs or finds the named 165 // histogram). 166 167 // Get histogram for counters. 168 Histogram* HistogramFactoryGetCounts( 169 const std::string& name, int min, int max, int bucket_count); 170 171 // Get histogram for enumerators. 172 // |boundary| should be above the max enumerator sample. 173 Histogram* HistogramFactoryGetEnumeration( 174 const std::string& name, int boundary); 175 176 // Function for adding a |sample| to a histogram. 177 // |name| can be used to verify that it matches the histogram name. 178 void HistogramAdd( 179 Histogram* histogram_pointer, const std::string& name, int sample); 180 181 } // namespace metrics 182 } // namespace webrtc 183 184 #endif // WEBRTC_SYSTEM_WRAPPERS_INCLUDE_METRICS_H_ 185 186