1580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//
2580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//
4580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// Use of this source code is governed by a BSD-style license
5580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// that can be found in the LICENSE file in the root of the source
6580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// tree. An additional intellectual property rights grant can be found
7580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// in the file PATENTS.  All contributing project authors may
8580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// be found in the AUTHORS file in the root of the source tree.
9580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//
10580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org
11d56d68cd272783ae0cfe11834c2a141ec62519c2kjellander#ifndef WEBRTC_SYSTEM_WRAPPERS_INCLUDE_METRICS_H_
12d56d68cd272783ae0cfe11834c2a141ec62519c2kjellander#define WEBRTC_SYSTEM_WRAPPERS_INCLUDE_METRICS_H_
13580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org
14580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org#include <string>
15580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org
161fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson#include "webrtc/base/atomicops.h"
171fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson#include "webrtc/base/checks.h"
18580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org#include "webrtc/common_types.h"
19580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org
20580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// Macros for allowing WebRTC clients (e.g. Chrome) to gather and aggregate
21580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// statistics.
22580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//
23580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// Histogram for counters.
24580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// RTC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count);
25580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//
26580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// Histogram for enumerators.
27580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// The boundary should be above the max enumerator sample.
28580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// RTC_HISTOGRAM_ENUMERATION(name, sample, boundary);
29580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//
30580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//
31580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// The macros use the methods HistogramFactoryGetCounts,
32580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// HistogramFactoryGetEnumeration and HistogramAdd.
33580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//
34580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// Therefore, WebRTC clients must either:
35580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//
36580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// - provide implementations of
37580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//   Histogram* webrtc::metrics::HistogramFactoryGetCounts(
38580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//       const std::string& name, int sample, int min, int max,
39580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//       int bucket_count);
40580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//   Histogram* webrtc::metrics::HistogramFactoryGetEnumeration(
41580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//       const std::string& name, int sample, int boundary);
42580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//   void webrtc::metrics::HistogramAdd(
43580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//       Histogram* histogram_pointer, const std::string& name, int sample);
44580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//
45580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// - or link with the default implementations (i.e.
4686e1e487e73ec33177d8c03989042a31cc157575andresp@webrtc.org//   system_wrappers/system_wrappers.gyp:metrics_default).
47580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//
48580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//
49580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// Example usage:
50580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//
51580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// RTC_HISTOGRAM_COUNTS("WebRTC.Video.NacksSent", nacks_sent, 1, 100000, 100);
52580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//
53580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// enum Types {
54580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//   kTypeX,
55580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//   kTypeY,
56580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//   kBoundary,
57580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// };
58580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org//
59580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// RTC_HISTOGRAM_ENUMERATION("WebRTC.Types", kTypeX, kBoundary);
60580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org
61580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org
62580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// Macros for adding samples to a named histogram.
63580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org
641fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson// Histogram for counters (exponentially spaced buckets).
651fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson#define RTC_HISTOGRAM_COUNTS_100(name, sample) \
661fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson  RTC_HISTOGRAM_COUNTS(name, sample, 1, 100, 50)
671fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson
681fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson#define RTC_HISTOGRAM_COUNTS_200(name, sample) \
691fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson  RTC_HISTOGRAM_COUNTS(name, sample, 1, 200, 50)
701fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson
711fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson#define RTC_HISTOGRAM_COUNTS_1000(name, sample) \
721fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson  RTC_HISTOGRAM_COUNTS(name, sample, 1, 1000, 50)
731fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson
741fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson#define RTC_HISTOGRAM_COUNTS_10000(name, sample) \
751fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson  RTC_HISTOGRAM_COUNTS(name, sample, 1, 10000, 50)
761fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson
771fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson#define RTC_HISTOGRAM_COUNTS_100000(name, sample) \
781fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson  RTC_HISTOGRAM_COUNTS(name, sample, 1, 100000, 50)
791fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson
801fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson#define RTC_HISTOGRAM_COUNTS(name, sample, min, max, bucket_count) \
811fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson  RTC_HISTOGRAM_COMMON_BLOCK(name, sample, \
821fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson      webrtc::metrics::HistogramFactoryGetCounts(name, min, max, bucket_count))
831fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson
841fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson// Deprecated.
851fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson// TODO(asapersson): Remove.
8653805324c0fa904d796cc0b333868c591f2c5f2casapersson#define RTC_HISTOGRAM_COUNTS_SPARSE_100(name, sample) \
8753805324c0fa904d796cc0b333868c591f2c5f2casapersson  RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 100, 50)
8896dc685143094e5834248b38ca4b03ee9f85d694asapersson@webrtc.org
8953805324c0fa904d796cc0b333868c591f2c5f2casapersson#define RTC_HISTOGRAM_COUNTS_SPARSE_200(name, sample) \
9053805324c0fa904d796cc0b333868c591f2c5f2casapersson  RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 200, 50)
9186b016027d2d27c62fedd108354a2b1274118ae3asapersson
9253805324c0fa904d796cc0b333868c591f2c5f2casapersson#define RTC_HISTOGRAM_COUNTS_SPARSE_1000(name, sample) \
9353805324c0fa904d796cc0b333868c591f2c5f2casapersson  RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 1000, 50)
9496dc685143094e5834248b38ca4b03ee9f85d694asapersson@webrtc.org
9553805324c0fa904d796cc0b333868c591f2c5f2casapersson#define RTC_HISTOGRAM_COUNTS_SPARSE_10000(name, sample) \
9653805324c0fa904d796cc0b333868c591f2c5f2casapersson  RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 10000, 50)
9796dc685143094e5834248b38ca4b03ee9f85d694asapersson@webrtc.org
9853805324c0fa904d796cc0b333868c591f2c5f2casapersson#define RTC_HISTOGRAM_COUNTS_SPARSE_100000(name, sample) \
9953805324c0fa904d796cc0b333868c591f2c5f2casapersson  RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, 1, 100000, 50)
10097d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org
10153805324c0fa904d796cc0b333868c591f2c5f2casapersson#define RTC_HISTOGRAM_COUNTS_SPARSE(name, sample, min, max, bucket_count) \
10253805324c0fa904d796cc0b333868c591f2c5f2casapersson  RTC_HISTOGRAM_COMMON_BLOCK_SLOW(name, sample, \
1031fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson      webrtc::metrics::HistogramFactoryGetCounts(name, min, max, bucket_count))
1041fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson
1051fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson// Histogram for percentage (evenly spaced buckets).
1061fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson#define RTC_HISTOGRAM_PERCENTAGE(name, sample) \
1071fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson  RTC_HISTOGRAM_ENUMERATION(name, sample, 101)
108580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org
1091fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson// Deprecated.
1101fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson// TODO(asapersson): Remove.
11153805324c0fa904d796cc0b333868c591f2c5f2casapersson#define RTC_HISTOGRAM_PERCENTAGE_SPARSE(name, sample) \
11253805324c0fa904d796cc0b333868c591f2c5f2casapersson  RTC_HISTOGRAM_ENUMERATION_SPARSE(name, sample, 101)
11396dc685143094e5834248b38ca4b03ee9f85d694asapersson@webrtc.org
1141fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson// Histogram for enumerators (evenly spaced buckets).
11596dc685143094e5834248b38ca4b03ee9f85d694asapersson@webrtc.org// |boundary| should be above the max enumerator sample.
1161fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson#define RTC_HISTOGRAM_ENUMERATION(name, sample, boundary) \
1171fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson  RTC_HISTOGRAM_COMMON_BLOCK(name, sample, \
1181fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson      webrtc::metrics::HistogramFactoryGetEnumeration(name, boundary))
1191fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson
1201fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson// Deprecated.
1211fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson// TODO(asapersson): Remove.
12253805324c0fa904d796cc0b333868c591f2c5f2casapersson#define RTC_HISTOGRAM_ENUMERATION_SPARSE(name, sample, boundary) \
12353805324c0fa904d796cc0b333868c591f2c5f2casapersson  RTC_HISTOGRAM_COMMON_BLOCK_SLOW(name, sample, \
12453805324c0fa904d796cc0b333868c591f2c5f2casapersson      webrtc::metrics::HistogramFactoryGetEnumeration(name, boundary))
125580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org
1261fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson// The name of the histogram should not vary.
1271fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson// TODO(asapersson): Consider changing string to const char*.
1281fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson#define RTC_HISTOGRAM_COMMON_BLOCK(constant_name, sample, \
1291fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson                                   factory_get_invocation) \
130580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org  do { \
1311fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson    static webrtc::metrics::Histogram* atomic_histogram_pointer = nullptr; \
1321fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson    webrtc::metrics::Histogram* histogram_pointer = \
1331fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson        rtc::AtomicOps::AcquireLoadPtr(&atomic_histogram_pointer); \
1341fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson    if (!histogram_pointer) { \
1351fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson      histogram_pointer = factory_get_invocation; \
1361fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson      webrtc::metrics::Histogram* prev_pointer = \
1371fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson          rtc::AtomicOps::CompareAndSwapPtr( \
1381fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson              &atomic_histogram_pointer, \
1391fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson              static_cast<webrtc::metrics::Histogram*>(nullptr), \
1401fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson              histogram_pointer); \
1411fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson      RTC_DCHECK(prev_pointer == nullptr || \
1421fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson                 prev_pointer == histogram_pointer); \
1431fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson    } \
144580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org    webrtc::metrics::HistogramAdd(histogram_pointer, constant_name, sample); \
145580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org  } while (0)
146580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org
1471fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson// Deprecated.
1481fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson// The histogram is constructed/found for each call.
1491fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson// May be used for histograms with infrequent updates.
1501fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson#define RTC_HISTOGRAM_COMMON_BLOCK_SLOW(name, sample, factory_get_invocation) \
1511fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson  do { \
1521fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson    webrtc::metrics::Histogram* histogram_pointer = factory_get_invocation; \
1531fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson    webrtc::metrics::HistogramAdd(histogram_pointer, name, sample); \
1541fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson  } while (0)
1551fe48a5e1dbc752b24b6c63eb2e6abd80c01c1dcasapersson
156580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.orgnamespace webrtc {
157580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.orgnamespace metrics {
158580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org
15983b5200f957bc0667e18c7e353f3311589d29a72asapersson@webrtc.org// Time that should have elapsed for stats that are gathered once per call.
16083b5200f957bc0667e18c7e353f3311589d29a72asapersson@webrtc.orgenum { kMinRunTimeInSeconds = 10 };
16183b5200f957bc0667e18c7e353f3311589d29a72asapersson@webrtc.org
162580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.orgclass Histogram;
163580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org
164580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// Functions for getting pointer to histogram (constructs or finds the named
165580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// histogram).
166580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org
167580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// Get histogram for counters.
168580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.orgHistogram* HistogramFactoryGetCounts(
169580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org    const std::string& name, int min, int max, int bucket_count);
170580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org
171580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// Get histogram for enumerators.
172580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// |boundary| should be above the max enumerator sample.
173580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.orgHistogram* HistogramFactoryGetEnumeration(
174580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org    const std::string& name, int boundary);
175580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org
176580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// Function for adding a |sample| to a histogram.
177580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org// |name| can be used to verify that it matches the histogram name.
178580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.orgvoid HistogramAdd(
179580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org    Histogram* histogram_pointer, const std::string& name, int sample);
180580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org
181580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org}  // namespace metrics
182580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org}  // namespace webrtc
183580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org
184d56d68cd272783ae0cfe11834c2a141ec62519c2kjellander#endif  // WEBRTC_SYSTEM_WRAPPERS_INCLUDE_METRICS_H_
185580d367b1482b2472f6c220a5c30d3942524f36casapersson@webrtc.org
186