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/common_types.h"
17 
18 // Macros for allowing WebRTC clients (e.g. Chrome) to gather and aggregate
19 // statistics.
20 //
21 // Histogram for counters.
22 // RTC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count);
23 //
24 // Histogram for enumerators.
25 // The boundary should be above the max enumerator sample.
26 // RTC_HISTOGRAM_ENUMERATION(name, sample, boundary);
27 //
28 //
29 // The macros use the methods HistogramFactoryGetCounts,
30 // HistogramFactoryGetEnumeration and HistogramAdd.
31 //
32 // Therefore, WebRTC clients must either:
33 //
34 // - provide implementations of
35 //   Histogram* webrtc::metrics::HistogramFactoryGetCounts(
36 //       const std::string& name, int sample, int min, int max,
37 //       int bucket_count);
38 //   Histogram* webrtc::metrics::HistogramFactoryGetEnumeration(
39 //       const std::string& name, int sample, int boundary);
40 //   void webrtc::metrics::HistogramAdd(
41 //       Histogram* histogram_pointer, const std::string& name, int sample);
42 //
43 // - or link with the default implementations (i.e.
44 //   system_wrappers/system_wrappers.gyp:metrics_default).
45 //
46 //
47 // Example usage:
48 //
49 // RTC_HISTOGRAM_COUNTS("WebRTC.Video.NacksSent", nacks_sent, 1, 100000, 100);
50 //
51 // enum Types {
52 //   kTypeX,
53 //   kTypeY,
54 //   kBoundary,
55 // };
56 //
57 // RTC_HISTOGRAM_ENUMERATION("WebRTC.Types", kTypeX, kBoundary);
58 
59 
60 // Macros for adding samples to a named histogram.
61 //
62 // NOTE: this is a temporary solution.
63 // The aim is to mimic the behaviour in Chromium's src/base/metrics/histograms.h
64 // However as atomics are not supported in webrtc, this is for now a modified
65 // and temporary solution. Note that the histogram is constructed/found for
66 // each call. Therefore, for now only use this implementation for metrics
67 // that do not need to be updated frequently.
68 // TODO(asapersson): Change implementation when atomics are supported.
69 // Also consider changing string to const char* when switching to atomics.
70 
71 // Histogram for counters.
72 #define RTC_HISTOGRAM_COUNTS_100(name, sample) RTC_HISTOGRAM_COUNTS( \
73     name, sample, 1, 100, 50)
74 
75 #define RTC_HISTOGRAM_COUNTS_200(name, sample) RTC_HISTOGRAM_COUNTS( \
76     name, sample, 1, 200, 50)
77 
78 #define RTC_HISTOGRAM_COUNTS_1000(name, sample) RTC_HISTOGRAM_COUNTS( \
79     name, sample, 1, 1000, 50)
80 
81 #define RTC_HISTOGRAM_COUNTS_10000(name, sample) RTC_HISTOGRAM_COUNTS( \
82     name, sample, 1, 10000, 50)
83 
84 #define RTC_HISTOGRAM_COUNTS_100000(name, sample) RTC_HISTOGRAM_COUNTS( \
85     name, sample, 1, 100000, 50)
86 
87 #define RTC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count) \
88     RTC_HISTOGRAM_COMMON_BLOCK(name, sample, \
89         webrtc::metrics::HistogramFactoryGetCounts( \
90             name, min, max, bucket_count))
91 
92 // Histogram for percentage.
93 #define RTC_HISTOGRAM_PERCENTAGE(name, sample) \
94     RTC_HISTOGRAM_ENUMERATION(name, sample, 101)
95 
96 // Histogram for enumerators.
97 // |boundary| should be above the max enumerator sample.
98 #define RTC_HISTOGRAM_ENUMERATION(name, sample, boundary) \
99     RTC_HISTOGRAM_COMMON_BLOCK(name, sample, \
100         webrtc::metrics::HistogramFactoryGetEnumeration(name, boundary))
101 
102 #define RTC_HISTOGRAM_COMMON_BLOCK(constant_name, sample, \
103                                    factory_get_invocation) \
104   do { \
105     webrtc::metrics::Histogram* histogram_pointer = factory_get_invocation; \
106     webrtc::metrics::HistogramAdd(histogram_pointer, constant_name, sample); \
107   } while (0)
108 
109 
110 namespace webrtc {
111 namespace metrics {
112 
113 // Time that should have elapsed for stats that are gathered once per call.
114 enum { kMinRunTimeInSeconds = 10 };
115 
116 class Histogram;
117 
118 // Functions for getting pointer to histogram (constructs or finds the named
119 // histogram).
120 
121 // Get histogram for counters.
122 Histogram* HistogramFactoryGetCounts(
123     const std::string& name, int min, int max, int bucket_count);
124 
125 // Get histogram for enumerators.
126 // |boundary| should be above the max enumerator sample.
127 Histogram* HistogramFactoryGetEnumeration(
128     const std::string& name, int boundary);
129 
130 // Function for adding a |sample| to a histogram.
131 // |name| can be used to verify that it matches the histogram name.
132 void HistogramAdd(
133     Histogram* histogram_pointer, const std::string& name, int sample);
134 
135 }  // namespace metrics
136 }  // namespace webrtc
137 
138 #endif  // WEBRTC_SYSTEM_WRAPPERS_INCLUDE_METRICS_H_
139 
140