Home | History | Annotate | Download | only in include
      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