xref: /aosp_15_r20/external/webrtc/system_wrappers/include/metrics.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker //
2*d9f75844SAndroid Build Coastguard Worker // Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker //
4*d9f75844SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker // that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker // tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker // in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker // be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker //
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #ifndef SYSTEM_WRAPPERS_INCLUDE_METRICS_H_
12*d9f75844SAndroid Build Coastguard Worker #define SYSTEM_WRAPPERS_INCLUDE_METRICS_H_
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include <stddef.h>
15*d9f75844SAndroid Build Coastguard Worker 
16*d9f75844SAndroid Build Coastguard Worker #include <atomic>
17*d9f75844SAndroid Build Coastguard Worker #include <map>
18*d9f75844SAndroid Build Coastguard Worker #include <memory>
19*d9f75844SAndroid Build Coastguard Worker #include <string>
20*d9f75844SAndroid Build Coastguard Worker 
21*d9f75844SAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
22*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
23*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/string_utils.h"
24*d9f75844SAndroid Build Coastguard Worker 
25*d9f75844SAndroid Build Coastguard Worker #if defined(RTC_DISABLE_METRICS)
26*d9f75844SAndroid Build Coastguard Worker #define RTC_METRICS_ENABLED 0
27*d9f75844SAndroid Build Coastguard Worker #else
28*d9f75844SAndroid Build Coastguard Worker #define RTC_METRICS_ENABLED 1
29*d9f75844SAndroid Build Coastguard Worker #endif
30*d9f75844SAndroid Build Coastguard Worker 
31*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
32*d9f75844SAndroid Build Coastguard Worker namespace metrics_impl {
33*d9f75844SAndroid Build Coastguard Worker template <typename... Ts>
NoOp(const Ts &...)34*d9f75844SAndroid Build Coastguard Worker void NoOp(const Ts&...) {}
35*d9f75844SAndroid Build Coastguard Worker }
36*d9f75844SAndroid Build Coastguard Worker }
37*d9f75844SAndroid Build Coastguard Worker 
38*d9f75844SAndroid Build Coastguard Worker #if RTC_METRICS_ENABLED
39*d9f75844SAndroid Build Coastguard Worker #define EXPECT_METRIC_EQ(val1, val2) EXPECT_EQ(val1, val2)
40*d9f75844SAndroid Build Coastguard Worker #define EXPECT_METRIC_EQ_WAIT(val1, val2, timeout) \
41*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ_WAIT(val1, val2, timeout)
42*d9f75844SAndroid Build Coastguard Worker #define EXPECT_METRIC_GT(val1, val2) EXPECT_GT(val1, val2)
43*d9f75844SAndroid Build Coastguard Worker #define EXPECT_METRIC_LE(val1, val2) EXPECT_LE(val1, val2)
44*d9f75844SAndroid Build Coastguard Worker #define EXPECT_METRIC_TRUE(conditon) EXPECT_TRUE(conditon)
45*d9f75844SAndroid Build Coastguard Worker #define EXPECT_METRIC_FALSE(conditon) EXPECT_FALSE(conditon)
46*d9f75844SAndroid Build Coastguard Worker #define EXPECT_METRIC_THAT(value, matcher) EXPECT_THAT(value, matcher)
47*d9f75844SAndroid Build Coastguard Worker #else
48*d9f75844SAndroid Build Coastguard Worker #define EXPECT_METRIC_EQ(val1, val2) webrtc::metrics_impl::NoOp(val1, val2)
49*d9f75844SAndroid Build Coastguard Worker #define EXPECT_METRIC_EQ_WAIT(val1, val2, timeout) webrtc::metrics_impl::NoOp(val1, val2, timeout)
50*d9f75844SAndroid Build Coastguard Worker #define EXPECT_METRIC_GT(val1, val2) webrtc::metrics_impl::NoOp(val1, val2)
51*d9f75844SAndroid Build Coastguard Worker #define EXPECT_METRIC_LE(val1, val2) webrtc::metrics_impl::NoOp(val1, val2)
52*d9f75844SAndroid Build Coastguard Worker #define EXPECT_METRIC_TRUE(condition) webrtc::metrics_impl::NoOp(condition || true)
53*d9f75844SAndroid Build Coastguard Worker #define EXPECT_METRIC_FALSE(condition) webrtc::metrics_impl::NoOp(condition && false)
54*d9f75844SAndroid Build Coastguard Worker #define EXPECT_METRIC_THAT(value, matcher) webrtc::metrics_impl::NoOp(value, testing::_)
55*d9f75844SAndroid Build Coastguard Worker #endif
56*d9f75844SAndroid Build Coastguard Worker 
57*d9f75844SAndroid Build Coastguard Worker #if RTC_METRICS_ENABLED
58*d9f75844SAndroid Build Coastguard Worker // Macros for allowing WebRTC clients (e.g. Chrome) to gather and aggregate
59*d9f75844SAndroid Build Coastguard Worker // statistics.
60*d9f75844SAndroid Build Coastguard Worker //
61*d9f75844SAndroid Build Coastguard Worker // Histogram for counters.
62*d9f75844SAndroid Build Coastguard Worker // RTC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count);
63*d9f75844SAndroid Build Coastguard Worker //
64*d9f75844SAndroid Build Coastguard Worker // Histogram for enumerators.
65*d9f75844SAndroid Build Coastguard Worker // The boundary should be above the max enumerator sample.
66*d9f75844SAndroid Build Coastguard Worker // RTC_HISTOGRAM_ENUMERATION(name, sample, boundary);
67*d9f75844SAndroid Build Coastguard Worker //
68*d9f75844SAndroid Build Coastguard Worker //
69*d9f75844SAndroid Build Coastguard Worker // The macros use the methods HistogramFactoryGetCounts,
70*d9f75844SAndroid Build Coastguard Worker // HistogramFactoryGetEnumeration and HistogramAdd.
71*d9f75844SAndroid Build Coastguard Worker //
72*d9f75844SAndroid Build Coastguard Worker // By default WebRTC provides implementations of the aforementioned methods
73*d9f75844SAndroid Build Coastguard Worker // that can be found in system_wrappers/source/metrics.cc. If clients want to
74*d9f75844SAndroid Build Coastguard Worker // provide a custom version, they will have to:
75*d9f75844SAndroid Build Coastguard Worker //
76*d9f75844SAndroid Build Coastguard Worker // 1. Compile WebRTC defining the preprocessor macro
77*d9f75844SAndroid Build Coastguard Worker //    WEBRTC_EXCLUDE_METRICS_DEFAULT (if GN is used this can be achieved
78*d9f75844SAndroid Build Coastguard Worker //    by setting the GN arg rtc_exclude_metrics_default to true).
79*d9f75844SAndroid Build Coastguard Worker // 2. Provide implementations of:
80*d9f75844SAndroid Build Coastguard Worker //    Histogram* webrtc::metrics::HistogramFactoryGetCounts(
81*d9f75844SAndroid Build Coastguard Worker //        absl::string_view name, int sample, int min, int max,
82*d9f75844SAndroid Build Coastguard Worker //        int bucket_count);
83*d9f75844SAndroid Build Coastguard Worker //    Histogram* webrtc::metrics::HistogramFactoryGetEnumeration(
84*d9f75844SAndroid Build Coastguard Worker //        absl::string_view name, int sample, int boundary);
85*d9f75844SAndroid Build Coastguard Worker //    void webrtc::metrics::HistogramAdd(
86*d9f75844SAndroid Build Coastguard Worker //        Histogram* histogram_pointer, absl::string_view name, int sample);
87*d9f75844SAndroid Build Coastguard Worker //
88*d9f75844SAndroid Build Coastguard Worker // Example usage:
89*d9f75844SAndroid Build Coastguard Worker //
90*d9f75844SAndroid Build Coastguard Worker // RTC_HISTOGRAM_COUNTS("WebRTC.Video.NacksSent", nacks_sent, 1, 100000, 100);
91*d9f75844SAndroid Build Coastguard Worker //
92*d9f75844SAndroid Build Coastguard Worker // enum Types {
93*d9f75844SAndroid Build Coastguard Worker //   kTypeX,
94*d9f75844SAndroid Build Coastguard Worker //   kTypeY,
95*d9f75844SAndroid Build Coastguard Worker //   kBoundary,
96*d9f75844SAndroid Build Coastguard Worker // };
97*d9f75844SAndroid Build Coastguard Worker //
98*d9f75844SAndroid Build Coastguard Worker // RTC_HISTOGRAM_ENUMERATION("WebRTC.Types", kTypeX, kBoundary);
99*d9f75844SAndroid Build Coastguard Worker //
100*d9f75844SAndroid Build Coastguard Worker // NOTE: It is recommended to do the Chromium review for modifications to
101*d9f75844SAndroid Build Coastguard Worker // histograms.xml before new metrics are committed to WebRTC.
102*d9f75844SAndroid Build Coastguard Worker 
103*d9f75844SAndroid Build Coastguard Worker // Macros for adding samples to a named histogram.
104*d9f75844SAndroid Build Coastguard Worker 
105*d9f75844SAndroid Build Coastguard Worker // Histogram for counters (exponentially spaced buckets).
106*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_100(name, sample) \
107*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_COUNTS(name, sample, 1, 100, 50)
108*d9f75844SAndroid Build Coastguard Worker 
109*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_200(name, sample) \
110*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_COUNTS(name, sample, 1, 200, 50)
111*d9f75844SAndroid Build Coastguard Worker 
112*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_500(name, sample) \
113*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_COUNTS(name, sample, 1, 500, 50)
114*d9f75844SAndroid Build Coastguard Worker 
115*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_1000(name, sample) \
116*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_COUNTS(name, sample, 1, 1000, 50)
117*d9f75844SAndroid Build Coastguard Worker 
118*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_10000(name, sample) \
119*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_COUNTS(name, sample, 1, 10000, 50)
120*d9f75844SAndroid Build Coastguard Worker 
121*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_100000(name, sample) \
122*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_COUNTS(name, sample, 1, 100000, 50)
123*d9f75844SAndroid Build Coastguard Worker 
124*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count)       \
125*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_COMMON_BLOCK(name, sample,                               \
126*d9f75844SAndroid Build Coastguard Worker                              webrtc::metrics::HistogramFactoryGetCounts( \
127*d9f75844SAndroid Build Coastguard Worker                                  name, min, max, bucket_count))
128*d9f75844SAndroid Build Coastguard Worker 
129*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_LINEAR(name, sample, min, max, bucket_count)      \
130*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_COMMON_BLOCK(name, sample,                                     \
131*d9f75844SAndroid Build Coastguard Worker                              webrtc::metrics::HistogramFactoryGetCountsLinear( \
132*d9f75844SAndroid Build Coastguard Worker                                  name, min, max, bucket_count))
133*d9f75844SAndroid Build Coastguard Worker 
134*d9f75844SAndroid Build Coastguard Worker // Slow metrics: pointer to metric is acquired at each call and is not cached.
135*d9f75844SAndroid Build Coastguard Worker //
136*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_SPARSE_100(name, sample) \
137*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 100, 50)
138*d9f75844SAndroid Build Coastguard Worker 
139*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_SPARSE_200(name, sample) \
140*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 200, 50)
141*d9f75844SAndroid Build Coastguard Worker 
142*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_SPARSE_500(name, sample) \
143*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 500, 50)
144*d9f75844SAndroid Build Coastguard Worker 
145*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_SPARSE_1000(name, sample) \
146*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 1000, 50)
147*d9f75844SAndroid Build Coastguard Worker 
148*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_SPARSE_10000(name, sample) \
149*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 10000, 50)
150*d9f75844SAndroid Build Coastguard Worker 
151*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_SPARSE_100000(name, sample) \
152*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 100000, 50)
153*d9f75844SAndroid Build Coastguard Worker 
154*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, min, max, bucket_count)     \
155*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_COMMON_BLOCK_SLOW(name, sample,                               \
156*d9f75844SAndroid Build Coastguard Worker                                   webrtc::metrics::HistogramFactoryGetCounts( \
157*d9f75844SAndroid Build Coastguard Worker                                       name, min, max, bucket_count))
158*d9f75844SAndroid Build Coastguard Worker 
159*d9f75844SAndroid Build Coastguard Worker // Histogram for percentage (evenly spaced buckets).
160*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_PERCENTAGE_SPARSE(name, sample) \
161*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_ENUMERATION_SPARSE(name, sample, 101)
162*d9f75844SAndroid Build Coastguard Worker 
163*d9f75844SAndroid Build Coastguard Worker // Histogram for booleans.
164*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_BOOLEAN_SPARSE(name, sample) \
165*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_ENUMERATION_SPARSE(name, sample, 2)
166*d9f75844SAndroid Build Coastguard Worker 
167*d9f75844SAndroid Build Coastguard Worker // Histogram for enumerators (evenly spaced buckets).
168*d9f75844SAndroid Build Coastguard Worker // `boundary` should be above the max enumerator sample.
169*d9f75844SAndroid Build Coastguard Worker //
170*d9f75844SAndroid Build Coastguard Worker // TODO(qingsi): Refactor the default implementation given by RtcHistogram,
171*d9f75844SAndroid Build Coastguard Worker // which is already sparse, and remove the boundary argument from the macro.
172*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_ENUMERATION_SPARSE(name, sample, boundary) \
173*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_COMMON_BLOCK_SLOW(                               \
174*d9f75844SAndroid Build Coastguard Worker       name, sample,                                              \
175*d9f75844SAndroid Build Coastguard Worker       webrtc::metrics::SparseHistogramFactoryGetEnumeration(name, boundary))
176*d9f75844SAndroid Build Coastguard Worker 
177*d9f75844SAndroid Build Coastguard Worker // Histogram for percentage (evenly spaced buckets).
178*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_PERCENTAGE(name, sample) \
179*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_ENUMERATION(name, sample, 101)
180*d9f75844SAndroid Build Coastguard Worker 
181*d9f75844SAndroid Build Coastguard Worker // Histogram for booleans.
182*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_BOOLEAN(name, sample) \
183*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_ENUMERATION(name, sample, 2)
184*d9f75844SAndroid Build Coastguard Worker 
185*d9f75844SAndroid Build Coastguard Worker // Histogram for enumerators (evenly spaced buckets).
186*d9f75844SAndroid Build Coastguard Worker // `boundary` should be above the max enumerator sample.
187*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_ENUMERATION(name, sample, boundary) \
188*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAM_COMMON_BLOCK_SLOW(                        \
189*d9f75844SAndroid Build Coastguard Worker       name, sample,                                       \
190*d9f75844SAndroid Build Coastguard Worker       webrtc::metrics::HistogramFactoryGetEnumeration(name, boundary))
191*d9f75844SAndroid Build Coastguard Worker 
192*d9f75844SAndroid Build Coastguard Worker // The name of the histogram should not vary.
193*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COMMON_BLOCK(constant_name, sample,                     \
194*d9f75844SAndroid Build Coastguard Worker                                    factory_get_invocation)                    \
195*d9f75844SAndroid Build Coastguard Worker   do {                                                                        \
196*d9f75844SAndroid Build Coastguard Worker     static std::atomic<webrtc::metrics::Histogram*> atomic_histogram_pointer( \
197*d9f75844SAndroid Build Coastguard Worker         nullptr);                                                             \
198*d9f75844SAndroid Build Coastguard Worker     webrtc::metrics::Histogram* histogram_pointer =                           \
199*d9f75844SAndroid Build Coastguard Worker         atomic_histogram_pointer.load(std::memory_order_acquire);             \
200*d9f75844SAndroid Build Coastguard Worker     if (!histogram_pointer) {                                                 \
201*d9f75844SAndroid Build Coastguard Worker       histogram_pointer = factory_get_invocation;                             \
202*d9f75844SAndroid Build Coastguard Worker       webrtc::metrics::Histogram* null_histogram = nullptr;                   \
203*d9f75844SAndroid Build Coastguard Worker       atomic_histogram_pointer.compare_exchange_strong(null_histogram,        \
204*d9f75844SAndroid Build Coastguard Worker                                                        histogram_pointer);    \
205*d9f75844SAndroid Build Coastguard Worker     }                                                                         \
206*d9f75844SAndroid Build Coastguard Worker     if (histogram_pointer) {                                                  \
207*d9f75844SAndroid Build Coastguard Worker       webrtc::metrics::HistogramAdd(histogram_pointer, sample);               \
208*d9f75844SAndroid Build Coastguard Worker     }                                                                         \
209*d9f75844SAndroid Build Coastguard Worker   } while (0)
210*d9f75844SAndroid Build Coastguard Worker 
211*d9f75844SAndroid Build Coastguard Worker // The histogram is constructed/found for each call.
212*d9f75844SAndroid Build Coastguard Worker // May be used for histograms with infrequent updates.`
213*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COMMON_BLOCK_SLOW(name, sample, factory_get_invocation) \
214*d9f75844SAndroid Build Coastguard Worker   do {                                                                        \
215*d9f75844SAndroid Build Coastguard Worker     webrtc::metrics::Histogram* histogram_pointer = factory_get_invocation;   \
216*d9f75844SAndroid Build Coastguard Worker     if (histogram_pointer) {                                                  \
217*d9f75844SAndroid Build Coastguard Worker       webrtc::metrics::HistogramAdd(histogram_pointer, sample);               \
218*d9f75844SAndroid Build Coastguard Worker     }                                                                         \
219*d9f75844SAndroid Build Coastguard Worker   } while (0)
220*d9f75844SAndroid Build Coastguard Worker 
221*d9f75844SAndroid Build Coastguard Worker // Helper macros.
222*d9f75844SAndroid Build Coastguard Worker // Macros for calling a histogram with varying name (e.g. when using a metric
223*d9f75844SAndroid Build Coastguard Worker // in different modes such as real-time vs screenshare). Fast, because pointer
224*d9f75844SAndroid Build Coastguard Worker // is cached. `index` should be different for different names. Allowed `index`
225*d9f75844SAndroid Build Coastguard Worker // values are 0, 1, and 2.
226*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAMS_COUNTS_100(index, name, sample) \
227*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAMS_COMMON(index, name, sample,           \
228*d9f75844SAndroid Build Coastguard Worker                         RTC_HISTOGRAM_COUNTS(name, sample, 1, 100, 50))
229*d9f75844SAndroid Build Coastguard Worker 
230*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAMS_COUNTS_200(index, name, sample) \
231*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAMS_COMMON(index, name, sample,           \
232*d9f75844SAndroid Build Coastguard Worker                         RTC_HISTOGRAM_COUNTS(name, sample, 1, 200, 50))
233*d9f75844SAndroid Build Coastguard Worker 
234*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAMS_COUNTS_500(index, name, sample) \
235*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAMS_COMMON(index, name, sample,           \
236*d9f75844SAndroid Build Coastguard Worker                         RTC_HISTOGRAM_COUNTS(name, sample, 1, 500, 50))
237*d9f75844SAndroid Build Coastguard Worker 
238*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAMS_COUNTS_1000(index, name, sample) \
239*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAMS_COMMON(index, name, sample,            \
240*d9f75844SAndroid Build Coastguard Worker                         RTC_HISTOGRAM_COUNTS(name, sample, 1, 1000, 50))
241*d9f75844SAndroid Build Coastguard Worker 
242*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAMS_COUNTS_10000(index, name, sample) \
243*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAMS_COMMON(index, name, sample,             \
244*d9f75844SAndroid Build Coastguard Worker                         RTC_HISTOGRAM_COUNTS(name, sample, 1, 10000, 50))
245*d9f75844SAndroid Build Coastguard Worker 
246*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAMS_COUNTS_100000(index, name, sample) \
247*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAMS_COMMON(index, name, sample,              \
248*d9f75844SAndroid Build Coastguard Worker                         RTC_HISTOGRAM_COUNTS(name, sample, 1, 100000, 50))
249*d9f75844SAndroid Build Coastguard Worker 
250*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAMS_ENUMERATION(index, name, sample, boundary) \
251*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAMS_COMMON(index, name, sample,                      \
252*d9f75844SAndroid Build Coastguard Worker                         RTC_HISTOGRAM_ENUMERATION(name, sample, boundary))
253*d9f75844SAndroid Build Coastguard Worker 
254*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAMS_PERCENTAGE(index, name, sample) \
255*d9f75844SAndroid Build Coastguard Worker   RTC_HISTOGRAMS_COMMON(index, name, sample,           \
256*d9f75844SAndroid Build Coastguard Worker                         RTC_HISTOGRAM_PERCENTAGE(name, sample))
257*d9f75844SAndroid Build Coastguard Worker 
258*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAMS_COMMON(index, name, sample, macro_invocation) \
259*d9f75844SAndroid Build Coastguard Worker   do {                                                               \
260*d9f75844SAndroid Build Coastguard Worker     switch (index) {                                                 \
261*d9f75844SAndroid Build Coastguard Worker       case 0:                                                        \
262*d9f75844SAndroid Build Coastguard Worker         macro_invocation;                                            \
263*d9f75844SAndroid Build Coastguard Worker         break;                                                       \
264*d9f75844SAndroid Build Coastguard Worker       case 1:                                                        \
265*d9f75844SAndroid Build Coastguard Worker         macro_invocation;                                            \
266*d9f75844SAndroid Build Coastguard Worker         break;                                                       \
267*d9f75844SAndroid Build Coastguard Worker       case 2:                                                        \
268*d9f75844SAndroid Build Coastguard Worker         macro_invocation;                                            \
269*d9f75844SAndroid Build Coastguard Worker         break;                                                       \
270*d9f75844SAndroid Build Coastguard Worker       default:                                                       \
271*d9f75844SAndroid Build Coastguard Worker         RTC_DCHECK_NOTREACHED();                                     \
272*d9f75844SAndroid Build Coastguard Worker     }                                                                \
273*d9f75844SAndroid Build Coastguard Worker   } while (0)
274*d9f75844SAndroid Build Coastguard Worker 
275*d9f75844SAndroid Build Coastguard Worker #else
276*d9f75844SAndroid Build Coastguard Worker 
277*d9f75844SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
278*d9f75844SAndroid Build Coastguard Worker // This section defines no-op alternatives to the metrics macros when
279*d9f75844SAndroid Build Coastguard Worker // RTC_METRICS_ENABLED is defined.
280*d9f75844SAndroid Build Coastguard Worker 
281*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_100(name, sample) webrtc::metrics_impl::NoOp(name, sample)
282*d9f75844SAndroid Build Coastguard Worker 
283*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_200(name, sample) webrtc::metrics_impl::NoOp(name, sample)
284*d9f75844SAndroid Build Coastguard Worker 
285*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_500(name, sample) webrtc::metrics_impl::NoOp(name, sample)
286*d9f75844SAndroid Build Coastguard Worker 
287*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_1000(name, sample) webrtc::metrics_impl::NoOp(name, sample)
288*d9f75844SAndroid Build Coastguard Worker 
289*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_10000(name, sample) webrtc::metrics_impl::NoOp(name, sample)
290*d9f75844SAndroid Build Coastguard Worker 
291*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_100000(name, sample) webrtc::metrics_impl::NoOp(name, sample)
292*d9f75844SAndroid Build Coastguard Worker 
293*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count) \
294*d9f75844SAndroid Build Coastguard Worker   webrtc::metrics_impl::NoOp(name, sample, min, max, bucket_count)
295*d9f75844SAndroid Build Coastguard Worker 
296*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_LINEAR(name, sample, min, max, bucket_count) \
297*d9f75844SAndroid Build Coastguard Worker   webrtc::metrics_impl::NoOp(name, sample, min, max, bucket_count)
298*d9f75844SAndroid Build Coastguard Worker 
299*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_SPARSE_100(name, sample) webrtc::metrics_impl::NoOp(name, sample)
300*d9f75844SAndroid Build Coastguard Worker 
301*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_SPARSE_200(name, sample) webrtc::metrics_impl::NoOp(name, sample)
302*d9f75844SAndroid Build Coastguard Worker 
303*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_SPARSE_500(name, sample) webrtc::metrics_impl::NoOp(name, sample)
304*d9f75844SAndroid Build Coastguard Worker 
305*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_SPARSE_1000(name, sample) webrtc::metrics_impl::NoOp(name, sample)
306*d9f75844SAndroid Build Coastguard Worker 
307*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_SPARSE_10000(name, sample) webrtc::metrics_impl::NoOp(name, sample)
308*d9f75844SAndroid Build Coastguard Worker 
309*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_SPARSE_100000(name, sample) webrtc::metrics_impl::NoOp(name, sample)
310*d9f75844SAndroid Build Coastguard Worker 
311*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, min, max, bucket_count) \
312*d9f75844SAndroid Build Coastguard Worker   webrtc::metrics_impl::NoOp(name, sample, min, max, bucket_count)
313*d9f75844SAndroid Build Coastguard Worker 
314*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_PERCENTAGE_SPARSE(name, sample) webrtc::metrics_impl::NoOp(name, sample)
315*d9f75844SAndroid Build Coastguard Worker 
316*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_BOOLEAN_SPARSE(name, sample) webrtc::metrics_impl::NoOp(name, sample)
317*d9f75844SAndroid Build Coastguard Worker 
318*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_ENUMERATION_SPARSE(name, sample, boundary) \
319*d9f75844SAndroid Build Coastguard Worker   webrtc::metrics_impl::NoOp(name, sample, boundary)
320*d9f75844SAndroid Build Coastguard Worker 
321*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_PERCENTAGE(name, sample) webrtc::metrics_impl::NoOp(name, sample)
322*d9f75844SAndroid Build Coastguard Worker 
323*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_BOOLEAN(name, sample) webrtc::metrics_impl::NoOp(name, sample)
324*d9f75844SAndroid Build Coastguard Worker 
325*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_ENUMERATION(name, sample, boundary) \
326*d9f75844SAndroid Build Coastguard Worker   webrtc::metrics_impl::NoOp(name, sample, boundary)
327*d9f75844SAndroid Build Coastguard Worker 
328*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COMMON_BLOCK(constant_name, sample,  \
329*d9f75844SAndroid Build Coastguard Worker                                    factory_get_invocation) \
330*d9f75844SAndroid Build Coastguard Worker   webrtc::metrics_impl::NoOp(constant_name, sample, factory_get_invocation)
331*d9f75844SAndroid Build Coastguard Worker 
332*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAM_COMMON_BLOCK_SLOW(name, sample, factory_get_invocation) \
333*d9f75844SAndroid Build Coastguard Worker   webrtc::metrics_impl::NoOp(name, sample, factory_get_invocation)
334*d9f75844SAndroid Build Coastguard Worker 
335*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAMS_COUNTS_100(index, name, sample) webrtc::metrics_impl::NoOp(index, name, sample)
336*d9f75844SAndroid Build Coastguard Worker 
337*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAMS_COUNTS_200(index, name, sample) webrtc::metrics_impl::NoOp(index, name, sample)
338*d9f75844SAndroid Build Coastguard Worker 
339*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAMS_COUNTS_500(index, name, sample) webrtc::metrics_impl::NoOp(index, name, sample)
340*d9f75844SAndroid Build Coastguard Worker 
341*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAMS_COUNTS_1000(index, name, sample) \
342*d9f75844SAndroid Build Coastguard Worker   webrtc::metrics_impl::NoOp(index, name, sample)
343*d9f75844SAndroid Build Coastguard Worker 
344*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAMS_COUNTS_10000(index, name, sample) \
345*d9f75844SAndroid Build Coastguard Worker   webrtc::metrics_impl::NoOp(index, name, sample)
346*d9f75844SAndroid Build Coastguard Worker 
347*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAMS_COUNTS_100000(index, name, sample) \
348*d9f75844SAndroid Build Coastguard Worker   webrtc::metrics_impl::NoOp(index, name, sample)
349*d9f75844SAndroid Build Coastguard Worker 
350*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAMS_ENUMERATION(index, name, sample, boundary) \
351*d9f75844SAndroid Build Coastguard Worker   webrtc::metrics_impl::NoOp(index, name, sample, boundary)
352*d9f75844SAndroid Build Coastguard Worker 
353*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAMS_PERCENTAGE(index, name, sample) webrtc::metrics_impl::NoOp(index, name, sample)
354*d9f75844SAndroid Build Coastguard Worker 
355*d9f75844SAndroid Build Coastguard Worker #define RTC_HISTOGRAMS_COMMON(index, name, sample, macro_invocation) \
356*d9f75844SAndroid Build Coastguard Worker   webrtc::metrics_impl::NoOp(index, name, sample, macro_invocation)
357*d9f75844SAndroid Build Coastguard Worker 
358*d9f75844SAndroid Build Coastguard Worker #endif  // RTC_METRICS_ENABLED
359*d9f75844SAndroid Build Coastguard Worker 
360*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
361*d9f75844SAndroid Build Coastguard Worker namespace metrics {
362*d9f75844SAndroid Build Coastguard Worker 
363*d9f75844SAndroid Build Coastguard Worker // Time that should have elapsed for stats that are gathered once per call.
364*d9f75844SAndroid Build Coastguard Worker constexpr int kMinRunTimeInSeconds = 10;
365*d9f75844SAndroid Build Coastguard Worker 
366*d9f75844SAndroid Build Coastguard Worker class Histogram;
367*d9f75844SAndroid Build Coastguard Worker 
368*d9f75844SAndroid Build Coastguard Worker // Functions for getting pointer to histogram (constructs or finds the named
369*d9f75844SAndroid Build Coastguard Worker // histogram).
370*d9f75844SAndroid Build Coastguard Worker 
371*d9f75844SAndroid Build Coastguard Worker // Get histogram for counters.
372*d9f75844SAndroid Build Coastguard Worker Histogram* HistogramFactoryGetCounts(absl::string_view name,
373*d9f75844SAndroid Build Coastguard Worker                                      int min,
374*d9f75844SAndroid Build Coastguard Worker                                      int max,
375*d9f75844SAndroid Build Coastguard Worker                                      int bucket_count);
376*d9f75844SAndroid Build Coastguard Worker 
377*d9f75844SAndroid Build Coastguard Worker // Get histogram for counters with linear bucket spacing.
378*d9f75844SAndroid Build Coastguard Worker Histogram* HistogramFactoryGetCountsLinear(absl::string_view name,
379*d9f75844SAndroid Build Coastguard Worker                                            int min,
380*d9f75844SAndroid Build Coastguard Worker                                            int max,
381*d9f75844SAndroid Build Coastguard Worker                                            int bucket_count);
382*d9f75844SAndroid Build Coastguard Worker 
383*d9f75844SAndroid Build Coastguard Worker // Get histogram for enumerators.
384*d9f75844SAndroid Build Coastguard Worker // `boundary` should be above the max enumerator sample.
385*d9f75844SAndroid Build Coastguard Worker Histogram* HistogramFactoryGetEnumeration(absl::string_view name, int boundary);
386*d9f75844SAndroid Build Coastguard Worker 
387*d9f75844SAndroid Build Coastguard Worker // Get sparse histogram for enumerators.
388*d9f75844SAndroid Build Coastguard Worker // `boundary` should be above the max enumerator sample.
389*d9f75844SAndroid Build Coastguard Worker Histogram* SparseHistogramFactoryGetEnumeration(absl::string_view name,
390*d9f75844SAndroid Build Coastguard Worker                                                 int boundary);
391*d9f75844SAndroid Build Coastguard Worker 
392*d9f75844SAndroid Build Coastguard Worker // Function for adding a `sample` to a histogram.
393*d9f75844SAndroid Build Coastguard Worker void HistogramAdd(Histogram* histogram_pointer, int sample);
394*d9f75844SAndroid Build Coastguard Worker 
395*d9f75844SAndroid Build Coastguard Worker struct SampleInfo {
396*d9f75844SAndroid Build Coastguard Worker   SampleInfo(absl::string_view name, int min, int max, size_t bucket_count);
397*d9f75844SAndroid Build Coastguard Worker   ~SampleInfo();
398*d9f75844SAndroid Build Coastguard Worker 
399*d9f75844SAndroid Build Coastguard Worker   const std::string name;
400*d9f75844SAndroid Build Coastguard Worker   const int min;
401*d9f75844SAndroid Build Coastguard Worker   const int max;
402*d9f75844SAndroid Build Coastguard Worker   const size_t bucket_count;
403*d9f75844SAndroid Build Coastguard Worker   std::map<int, int> samples;  // <value, # of events>
404*d9f75844SAndroid Build Coastguard Worker };
405*d9f75844SAndroid Build Coastguard Worker 
406*d9f75844SAndroid Build Coastguard Worker // Enables collection of samples.
407*d9f75844SAndroid Build Coastguard Worker // This method should be called before any other call into webrtc.
408*d9f75844SAndroid Build Coastguard Worker void Enable();
409*d9f75844SAndroid Build Coastguard Worker 
410*d9f75844SAndroid Build Coastguard Worker // Gets histograms and clears all samples.
411*d9f75844SAndroid Build Coastguard Worker void GetAndReset(
412*d9f75844SAndroid Build Coastguard Worker     std::map<std::string, std::unique_ptr<SampleInfo>, rtc::AbslStringViewCmp>*
413*d9f75844SAndroid Build Coastguard Worker         histograms);
414*d9f75844SAndroid Build Coastguard Worker 
415*d9f75844SAndroid Build Coastguard Worker // Functions below are mainly for testing.
416*d9f75844SAndroid Build Coastguard Worker 
417*d9f75844SAndroid Build Coastguard Worker // Clears all samples.
418*d9f75844SAndroid Build Coastguard Worker void Reset();
419*d9f75844SAndroid Build Coastguard Worker 
420*d9f75844SAndroid Build Coastguard Worker // Returns the number of times the `sample` has been added to the histogram.
421*d9f75844SAndroid Build Coastguard Worker int NumEvents(absl::string_view name, int sample);
422*d9f75844SAndroid Build Coastguard Worker 
423*d9f75844SAndroid Build Coastguard Worker // Returns the total number of added samples to the histogram.
424*d9f75844SAndroid Build Coastguard Worker int NumSamples(absl::string_view name);
425*d9f75844SAndroid Build Coastguard Worker 
426*d9f75844SAndroid Build Coastguard Worker // Returns the minimum sample value (or -1 if the histogram has no samples).
427*d9f75844SAndroid Build Coastguard Worker int MinSample(absl::string_view name);
428*d9f75844SAndroid Build Coastguard Worker 
429*d9f75844SAndroid Build Coastguard Worker // Returns a map with keys the samples with at least one event and values the
430*d9f75844SAndroid Build Coastguard Worker // number of events for that sample.
431*d9f75844SAndroid Build Coastguard Worker std::map<int, int> Samples(absl::string_view name);
432*d9f75844SAndroid Build Coastguard Worker 
433*d9f75844SAndroid Build Coastguard Worker }  // namespace metrics
434*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
435*d9f75844SAndroid Build Coastguard Worker 
436*d9f75844SAndroid Build Coastguard Worker #endif  // SYSTEM_WRAPPERS_INCLUDE_METRICS_H_
437