// Copyright 2012 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Histogram is an object that aggregates statistics, and can summarize them in // various forms, including ASCII graphical, HTML, and numerically (as a // vector of numbers corresponding to each of the aggregating buckets). // It supports calls to accumulate either time intervals (which are processed // as integral number of milliseconds), or arbitrary integral units. // For Histogram (exponential histogram), LinearHistogram and CustomHistogram, // the minimum for a declared range is 1 (instead of 0), while the maximum is // (HistogramBase::kSampleType_MAX - 1). However, there will always be underflow // and overflow buckets added automatically, so a 0 bucket will always exist // even when a minimum value of 1 is specified. // Each use of a histogram with the same name will reference the same underlying // data, so it is safe to record to the same histogram from multiple locations // in the code. It is a runtime error if all uses of the same histogram do not // agree exactly in type, bucket size and range. // For Histogram and LinearHistogram, the maximum for a declared range should // always be larger (not equal) than minimal range. Zero and // HistogramBase::kSampleType_MAX are implicitly added as first and last ranges, // so the smallest legal bucket_count is 3. However CustomHistogram can have // bucket count as 2 (when you give a custom ranges vector containing only 1 // range). // For these 3 kinds of histograms, the max bucket count is always // (Histogram::kBucketCount_MAX - 1). // The buckets layout of class Histogram is exponential. For example, buckets // might contain (sequentially) the count of values in the following intervals: // [0,1), [1,2), [2,4), [4,8), [8,16), [16,32), [32,64), [64,infinity) // That bucket allocation would actually result from construction of a histogram // for values between 1 and 64, with 8 buckets, such as: // Histogram count("some name", 1, 64, 8); // Note that the underflow bucket [0,1) and the overflow bucket [64,infinity) // are also counted by the constructor in the user supplied "bucket_count" // argument. // The above example has an exponential ratio of 2 (doubling the bucket width // in each consecutive bucket). The Histogram class automatically calculates // the smallest ratio that it can use to construct the number of buckets // selected in the constructor. An another example, if you had 50 buckets, // and millisecond time values from 1 to 10000, then the ratio between // consecutive bucket widths will be approximately somewhere around the 50th // root of 10000. This approach provides very fine grain (narrow) buckets // at the low end of the histogram scale, but allows the histogram to cover a // gigantic range with the addition of very few buckets. // Usually we use macros to define and use a histogram, which are defined in // base/metrics/histogram_macros.h. Note: Callers should include that header // directly if they only access the histogram APIs through macros. // // Macros use a pattern involving a function static variable, that is a pointer // to a histogram. This static is explicitly initialized on any thread // that detects a uninitialized (NULL) pointer. The potentially racy // initialization is not a problem as it is always set to point to the same // value (i.e., the FactoryGet always returns the same value). FactoryGet // is also completely thread safe, which results in a completely thread safe, // and relatively fast, set of counters. To avoid races at shutdown, the static // pointer is NOT deleted, and we leak the histograms at process termination. #ifndef BASE_METRICS_HISTOGRAM_H_ #define BASE_METRICS_HISTOGRAM_H_ #include <stddef.h> #include <stdint.h> #include <map> #include <memory> #include <string> #include <string_view> #include <vector> #include "base/base_export.h" #include "base/compiler_specific.h" #include "base/containers/span.h" #include "base/dcheck_is_on.h" #include "base/gtest_prod_util.h" #include "base/memory/raw_ptr.h" #include "base/metrics/bucket_ranges.h" #include "base/metrics/histogram_base.h" #include "base/metrics/histogram_samples.h" #include "base/time/time.h" #include "base/values.h" namespace base { class BooleanHistogram; class CustomHistogram; class DelayedPersistentAllocation; class Histogram; class HistogramTest; class LinearHistogram; class Pickle; class PickleIterator; class SampleVector; class SampleVectorBase; class BASE_EXPORT Histogram : public HistogramBase { … }; //------------------------------------------------------------------------------ // LinearHistogram is a more traditional histogram, with evenly spaced // buckets. class BASE_EXPORT LinearHistogram : public Histogram { … }; //------------------------------------------------------------------------------ // ScaledLinearHistogram is a wrapper around a linear histogram that scales the // counts down by some factor. Remainder values are kept locally but lost when // uploaded or serialized. The integral counts are rounded up/down so should // average to the correct value when many reports are added. // // This is most useful when adding many counts at once via AddCount() that can // cause overflows of the 31-bit counters, usually with an enum as the value. class BASE_EXPORT ScaledLinearHistogram { … }; //------------------------------------------------------------------------------ // BooleanHistogram is a histogram for booleans. class BASE_EXPORT BooleanHistogram : public LinearHistogram { … }; //------------------------------------------------------------------------------ // CustomHistogram is a histogram for a set of custom integers. class BASE_EXPORT CustomHistogram : public Histogram { … }; namespace internal { // Controls whether invocations of UMA_HISTOGRAM_SPLIT_BY_PROCESS_PRIORITY in // this process log to their ".BestEffort" suffix or not. Timing metrics // reported through UMA_HISTOGRAM_SPLIT_BY_PROCESS_PRIORITY which overlap a // best-effort range will be suffixed with ".BestEffort". BASE_EXPORT void SetSharedLastForegroundTimeForMetrics( const std::atomic<TimeTicks>* last_foreground_time_ref); // Reports whether the interval [`now - range`, `now`] overlaps with a period // where this process was running at Process::Priority::kBestEffort. Defaults to // false if `last_foreground_time_ref` was never set (e.g. in processes not // affected by priorities) but otherwise defaults to true if there's ambiguity // (might have overlapped a best-effort range; as the reported timing might have // been affected and shouldn't be reported as "definitely measured in // foreground"). // This method is atomic and suitable for performance critical histogram // samples. BASE_EXPORT bool OverlapsBestEffortRange(TimeTicks now, TimeDelta range); } // namespace internal } // namespace base #endif // BASE_METRICS_HISTOGRAM_H_