asvitkine | 4a7d51f | 2014-11-15 10:47:07 +0900 | [diff] [blame] | 1 | // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef BASE_METRICS_HISTOGRAM_MACROS_H_ |
| 6 | #define BASE_METRICS_HISTOGRAM_MACROS_H_ |
| 7 | |
asvitkine | 4a7d51f | 2014-11-15 10:47:07 +0900 | [diff] [blame] | 8 | #include "base/metrics/histogram.h" |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 9 | #include "base/metrics/histogram_macros_internal.h" |
| 10 | #include "base/metrics/histogram_macros_local.h" |
asvitkine | 4a7d51f | 2014-11-15 10:47:07 +0900 | [diff] [blame] | 11 | #include "base/time/time.h" |
| 12 | |
nikunjb | 36febca | 2016-10-19 13:12:55 +0900 | [diff] [blame] | 13 | |
mpearson | 36ad821 | 2016-10-04 06:27:03 +0900 | [diff] [blame] | 14 | // Macros for efficient use of histograms. |
| 15 | // |
| 16 | // For best practices on deciding when to emit to a histogram and what form |
mpearson | ca6ae95 | 2016-10-07 09:18:03 +0900 | [diff] [blame] | 17 | // the histogram should take, see |
| 18 | // https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md |
scheib | 7fec1e9 | 2016-01-20 10:38:59 +0900 | [diff] [blame] | 19 | |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 20 | // TODO(rkaplow): Link to proper documentation on metric creation once we have |
| 21 | // it in a good state. |
asvitkine | 4a7d51f | 2014-11-15 10:47:07 +0900 | [diff] [blame] | 22 | |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 23 | // All of these macros must be called with |name| as a runtime constant - it |
mgiuca | 71e5d77 | 2016-04-08 14:21:53 +0900 | [diff] [blame] | 24 | // doesn't have to literally be a constant, but it must be the same string on |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 25 | // all calls from a particular call site. If this rule is violated, it is |
| 26 | // possible the data will be written to the wrong histogram. |
asvitkine | 4a7d51f | 2014-11-15 10:47:07 +0900 | [diff] [blame] | 27 | |
| 28 | //------------------------------------------------------------------------------ |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 29 | // Enumeration histograms. |
asvitkine | 4a7d51f | 2014-11-15 10:47:07 +0900 | [diff] [blame] | 30 | |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 31 | // These macros create histograms for enumerated data. Ideally, the data should |
| 32 | // be of the form of "event occurs, log the result". We recommended not putting |
| 33 | // related but not directly connected data as enums within the same histogram. |
| 34 | // You should be defining an associated Enum, and the input sample should be |
| 35 | // an element of the Enum. |
| 36 | // All of these macros must be called with |name| as a runtime constant. |
asvitkine | 4a7d51f | 2014-11-15 10:47:07 +0900 | [diff] [blame] | 37 | |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 38 | // Sample usage: |
| 39 | // UMA_HISTOGRAM_ENUMERATION("My.Enumeration", VALUE, EVENT_MAX_VALUE); |
| 40 | // New Enum values can be added, but existing enums must never be renumbered or |
| 41 | // delete and reused. The value in |sample| must be strictly less than |
| 42 | // |enum_max|. |
asvitkine | 4a7d51f | 2014-11-15 10:47:07 +0900 | [diff] [blame] | 43 | |
dcheng | 3368b51 | 2017-03-31 08:55:57 +0900 | [diff] [blame^] | 44 | #define UMA_HISTOGRAM_ENUMERATION(name, sample, enum_max) \ |
| 45 | INTERNAL_HISTOGRAM_ENUMERATION_WITH_FLAG( \ |
| 46 | name, sample, enum_max, base::HistogramBase::kUmaTargetedHistogramFlag) |
manzagop | eb2528c | 2016-09-09 08:40:05 +0900 | [diff] [blame] | 47 | |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 48 | // Histogram for boolean values. |
manzagop | eb2528c | 2016-09-09 08:40:05 +0900 | [diff] [blame] | 49 | |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 50 | // Sample usage: |
| 51 | // UMA_HISTOGRAM_BOOLEAN("Histogram.Boolean", bool); |
| 52 | #define UMA_HISTOGRAM_BOOLEAN(name, sample) \ |
| 53 | STATIC_HISTOGRAM_POINTER_BLOCK(name, AddBoolean(sample), \ |
| 54 | base::BooleanHistogram::FactoryGet(name, \ |
| 55 | base::HistogramBase::kUmaTargetedHistogramFlag)) |
asvitkine | 4a7d51f | 2014-11-15 10:47:07 +0900 | [diff] [blame] | 56 | |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 57 | //------------------------------------------------------------------------------ |
rkaplow | 96906ce | 2016-10-05 07:37:55 +0900 | [diff] [blame] | 58 | // Linear histograms. |
asvitkine | 4a7d51f | 2014-11-15 10:47:07 +0900 | [diff] [blame] | 59 | |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 60 | // All of these macros must be called with |name| as a runtime constant. |
asvitkine | 4a7d51f | 2014-11-15 10:47:07 +0900 | [diff] [blame] | 61 | |
rkaplow | 96906ce | 2016-10-05 07:37:55 +0900 | [diff] [blame] | 62 | // Used for capturing integer data with a linear bucketing scheme. This can be |
| 63 | // used when you want the exact value of some small numeric count, with a max of |
| 64 | // 100 or less. If you need to capture a range of greater than 100, we recommend |
| 65 | // the use of the COUNT histograms below. |
| 66 | |
| 67 | // Sample usage: |
| 68 | // UMA_HISTOGRAM_EXACT_LINEAR("Histogram.Linear", count, 10); |
nikunjb | 7961de9 | 2016-11-15 07:06:25 +0900 | [diff] [blame] | 69 | #define UMA_HISTOGRAM_EXACT_LINEAR(name, sample, value_max) \ |
dcheng | 3368b51 | 2017-03-31 08:55:57 +0900 | [diff] [blame^] | 70 | INTERNAL_HISTOGRAM_EXACT_LINEAR_WITH_FLAG( \ |
| 71 | name, sample, value_max, base::HistogramBase::kUmaTargetedHistogramFlag) |
rkaplow | 96906ce | 2016-10-05 07:37:55 +0900 | [diff] [blame] | 72 | |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 73 | // Used for capturing basic percentages. This will be 100 buckets of size 1. |
rkaplow | 4cf0e23 | 2015-08-06 00:56:45 +0900 | [diff] [blame] | 74 | |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 75 | // Sample usage: |
| 76 | // UMA_HISTOGRAM_PERCENTAGE("Histogram.Percent", percent_as_int); |
dcheng | 3368b51 | 2017-03-31 08:55:57 +0900 | [diff] [blame^] | 77 | #define UMA_HISTOGRAM_PERCENTAGE(name, percent_as_int) \ |
| 78 | UMA_HISTOGRAM_EXACT_LINEAR(name, percent_as_int, 101) |
asvitkine | 4a7d51f | 2014-11-15 10:47:07 +0900 | [diff] [blame] | 79 | |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 80 | //------------------------------------------------------------------------------ |
| 81 | // Count histograms. These are used for collecting numeric data. Note that we |
| 82 | // have macros for more specialized use cases below (memory, time, percentages). |
| 83 | |
| 84 | // The number suffixes here refer to the max size of the sample, i.e. COUNT_1000 |
| 85 | // will be able to collect samples of counts up to 1000. The default number of |
| 86 | // buckets in all default macros is 50. We recommend erring on the side of too |
| 87 | // large a range versus too short a range. |
| 88 | // These macros default to exponential histograms - i.e. the lengths of the |
| 89 | // bucket ranges exponentially increase as the sample range increases. |
| 90 | // These should *not* be used if you are interested in exact counts, i.e. a |
| 91 | // bucket range of 1. In these cases, you should use the ENUMERATION macros |
| 92 | // defined later. These should also not be used to capture the number of some |
| 93 | // event, i.e. "button X was clicked N times". In this cases, an enum should be |
| 94 | // used, ideally with an appropriate baseline enum entry included. |
| 95 | // All of these macros must be called with |name| as a runtime constant. |
| 96 | |
| 97 | // Sample usage: |
| 98 | // UMA_HISTOGRAM_COUNTS_1M("My.Histogram", sample); |
| 99 | |
| 100 | #define UMA_HISTOGRAM_COUNTS_100(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ |
| 101 | name, sample, 1, 100, 50) |
| 102 | |
| 103 | #define UMA_HISTOGRAM_COUNTS_1000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ |
| 104 | name, sample, 1, 1000, 50) |
| 105 | |
| 106 | #define UMA_HISTOGRAM_COUNTS_10000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ |
| 107 | name, sample, 1, 10000, 50) |
| 108 | |
| 109 | #define UMA_HISTOGRAM_COUNTS_100000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ |
| 110 | name, sample, 1, 100000, 50) |
| 111 | |
| 112 | #define UMA_HISTOGRAM_COUNTS_1M(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ |
| 113 | name, sample, 1, 1000000, 50) |
| 114 | |
| 115 | #define UMA_HISTOGRAM_COUNTS_10M(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ |
| 116 | name, sample, 1, 10000000, 50) |
| 117 | |
| 118 | // This can be used when the default ranges are not sufficient. This macro lets |
| 119 | // the metric developer customize the min and max of the sampled range, as well |
| 120 | // as the number of buckets recorded. |
| 121 | // Any data outside the range here will be put in underflow and overflow |
| 122 | // buckets. Min values should be >=1 as emitted 0s will still go into the |
| 123 | // underflow bucket. |
| 124 | |
| 125 | // Sample usage: |
| 126 | // UMA_HISTOGRAM_CUSTOM_COUNTS("My.Histogram", 1, 100000000, 100); |
| 127 | #define UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \ |
| 128 | INTERNAL_HISTOGRAM_CUSTOM_COUNTS_WITH_FLAG( \ |
| 129 | name, sample, min, max, bucket_count, \ |
asvitkine | 4a7d51f | 2014-11-15 10:47:07 +0900 | [diff] [blame] | 130 | base::HistogramBase::kUmaTargetedHistogramFlag) |
| 131 | |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 132 | //------------------------------------------------------------------------------ |
| 133 | // Timing histograms. These are used for collecting timing data (generally |
| 134 | // latencies). |
| 135 | |
| 136 | // These macros create exponentially sized histograms (lengths of the bucket |
| 137 | // ranges exponentially increase as the sample range increases). The input |
| 138 | // sample is a base::TimeDelta. The output data is measured in ms granularity. |
| 139 | // All of these macros must be called with |name| as a runtime constant. |
| 140 | |
| 141 | // Sample usage: |
| 142 | // UMA_HISTOGRAM_TIMES("My.Timing.Histogram", time_delta); |
| 143 | |
| 144 | // Short timings - up to 10 seconds. |
| 145 | #define UMA_HISTOGRAM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ |
| 146 | name, sample, base::TimeDelta::FromMilliseconds(1), \ |
| 147 | base::TimeDelta::FromSeconds(10), 50) |
| 148 | |
| 149 | // Medium timings - up to 3 minutes. Note this starts at 10ms (no good reason, |
| 150 | // but not worth changing). |
| 151 | #define UMA_HISTOGRAM_MEDIUM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ |
| 152 | name, sample, base::TimeDelta::FromMilliseconds(10), \ |
| 153 | base::TimeDelta::FromMinutes(3), 50) |
| 154 | |
| 155 | // Long timings - up to an hour. |
| 156 | #define UMA_HISTOGRAM_LONG_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ |
| 157 | name, sample, base::TimeDelta::FromMilliseconds(1), \ |
| 158 | base::TimeDelta::FromHours(1), 50) |
| 159 | |
| 160 | // Long timings with higher granularity - up to an hour with 100 buckets. |
| 161 | #define UMA_HISTOGRAM_LONG_TIMES_100(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ |
| 162 | name, sample, base::TimeDelta::FromMilliseconds(1), \ |
| 163 | base::TimeDelta::FromHours(1), 100) |
| 164 | |
| 165 | // This can be used when the default ranges are not sufficient. This macro lets |
| 166 | // the metric developer customize the min and max of the sampled range, as well |
| 167 | // as the number of buckets recorded. |
| 168 | |
| 169 | // Sample usage: |
| 170 | // UMA_HISTOGRAM_CUSTOM_TIMES("Very.Long.Timing.Histogram", duration_in_ms, |
| 171 | // base::TimeDelta::FromSeconds(1), base::TimeDelta::FromDays(1), 100); |
| 172 | #define UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \ |
| 173 | STATIC_HISTOGRAM_POINTER_BLOCK(name, AddTime(sample), \ |
| 174 | base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ |
asvitkine | 4a7d51f | 2014-11-15 10:47:07 +0900 | [diff] [blame] | 175 | base::HistogramBase::kUmaTargetedHistogramFlag)) |
| 176 | |
rkaplow | e8ef9a0 | 2015-02-18 08:42:13 +0900 | [diff] [blame] | 177 | // Scoped class which logs its time on this earth as a UMA statistic. This is |
| 178 | // recommended for when you want a histogram which measures the time it takes |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 179 | // for a method to execute. This measures up to 10 seconds. It uses |
| 180 | // UMA_HISTOGRAM_TIMES under the hood. |
| 181 | |
| 182 | // Sample usage: |
| 183 | // void Function() { |
| 184 | // SCOPED_UMA_HISTOGRAM_TIMER("Component.FunctionTime"); |
| 185 | // ... |
| 186 | // } |
| 187 | #define SCOPED_UMA_HISTOGRAM_TIMER(name) \ |
| 188 | INTERNAL_SCOPED_UMA_HISTOGRAM_TIMER_EXPANDER(name, false, __COUNTER__) |
rkaplow | 8e5c3c9 | 2015-02-14 01:40:10 +0900 | [diff] [blame] | 189 | |
rkaplow | e8ef9a0 | 2015-02-18 08:42:13 +0900 | [diff] [blame] | 190 | // Similar scoped histogram timer, but this uses UMA_HISTOGRAM_LONG_TIMES_100, |
| 191 | // which measures up to an hour, and uses 100 buckets. This is more expensive |
| 192 | // to store, so only use if this often takes >10 seconds. |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 193 | #define SCOPED_UMA_HISTOGRAM_LONG_TIMER(name) \ |
| 194 | INTERNAL_SCOPED_UMA_HISTOGRAM_TIMER_EXPANDER(name, true, __COUNTER__) |
rkaplow | 8e5c3c9 | 2015-02-14 01:40:10 +0900 | [diff] [blame] | 195 | |
rkaplow | e8ef9a0 | 2015-02-18 08:42:13 +0900 | [diff] [blame] | 196 | |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 197 | //------------------------------------------------------------------------------ |
| 198 | // Memory histograms. |
| 199 | |
| 200 | // These macros create exponentially sized histograms (lengths of the bucket |
| 201 | // ranges exponentially increase as the sample range increases). The input |
| 202 | // sample must be a number measured in kilobytes. |
| 203 | // All of these macros must be called with |name| as a runtime constant. |
| 204 | |
| 205 | // Sample usage: |
| 206 | // UMA_HISTOGRAM_MEMORY_KB("My.Memory.Histogram", memory_in_kb); |
| 207 | |
| 208 | // Used to measure common KB-granularity memory stats. Range is up to 500000KB - |
| 209 | // approximately 500M. |
| 210 | #define UMA_HISTOGRAM_MEMORY_KB(name, sample) \ |
| 211 | UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1000, 500000, 50) |
| 212 | |
| 213 | // Used to measure common MB-granularity memory stats. Range is up to ~64G. |
| 214 | #define UMA_HISTOGRAM_MEMORY_LARGE_MB(name, sample) \ |
| 215 | UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 64000, 100) |
| 216 | |
| 217 | |
| 218 | //------------------------------------------------------------------------------ |
| 219 | // Stability-specific histograms. |
| 220 | |
| 221 | // Histograms logged in as stability histograms will be included in the initial |
| 222 | // stability log. See comments by declaration of |
| 223 | // MetricsService::PrepareInitialStabilityLog(). |
| 224 | // All of these macros must be called with |name| as a runtime constant. |
| 225 | |
| 226 | // For details on usage, see the documentation on the non-stability equivalents. |
| 227 | |
| 228 | #define UMA_STABILITY_HISTOGRAM_COUNTS_100(name, sample) \ |
| 229 | UMA_STABILITY_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 100, 50) |
| 230 | |
| 231 | #define UMA_STABILITY_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, \ |
| 232 | bucket_count) \ |
| 233 | INTERNAL_HISTOGRAM_CUSTOM_COUNTS_WITH_FLAG( \ |
| 234 | name, sample, min, max, bucket_count, \ |
| 235 | base::HistogramBase::kUmaStabilityHistogramFlag) |
| 236 | |
| 237 | #define UMA_STABILITY_HISTOGRAM_ENUMERATION(name, sample, enum_max) \ |
| 238 | INTERNAL_HISTOGRAM_ENUMERATION_WITH_FLAG( \ |
| 239 | name, sample, enum_max, \ |
| 240 | base::HistogramBase::kUmaStabilityHistogramFlag) |
| 241 | |
nikunjb | 36febca | 2016-10-19 13:12:55 +0900 | [diff] [blame] | 242 | //------------------------------------------------------------------------------ |
| 243 | // Sparse histograms. |
| 244 | |
| 245 | // Sparse histograms are well suited for recording counts of exact sample values |
| 246 | // that are sparsely distributed over a large range. |
| 247 | // |
| 248 | // UMA_HISTOGRAM_SPARSE_SLOWLY is good for sparsely distributed and/or |
| 249 | // infrequently recorded values since the implementation is slower |
| 250 | // and takes more memory. |
| 251 | // |
| 252 | // For instance, Sqlite.Version.* are sparse because for any given database, |
| 253 | // there's going to be exactly one version logged. |
juncai | 928527a | 2016-11-01 11:03:28 +0900 | [diff] [blame] | 254 | // The |sample| can be a negative or non-negative number. |
nikunjb | 36febca | 2016-10-19 13:12:55 +0900 | [diff] [blame] | 255 | #define UMA_HISTOGRAM_SPARSE_SLOWLY(name, sample) \ |
| 256 | INTERNAL_HISTOGRAM_SPARSE_SLOWLY(name, sample) |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 257 | |
| 258 | //------------------------------------------------------------------------------ |
tdresser | 23f898e | 2017-01-13 23:03:16 +0900 | [diff] [blame] | 259 | // Histogram instantiation helpers. |
| 260 | |
| 261 | // Support a collection of histograms, perhaps one for each entry in an |
| 262 | // enumeration. This macro manages a block of pointers, adding to a specific |
| 263 | // one by its index. |
| 264 | // |
| 265 | // A typical instantiation looks something like this: |
| 266 | // STATIC_HISTOGRAM_POINTER_GROUP( |
| 267 | // GetHistogramNameForIndex(histogram_index), |
| 268 | // histogram_index, MAXIMUM_HISTOGRAM_INDEX, Add(some_delta), |
| 269 | // base::Histogram::FactoryGet( |
| 270 | // GetHistogramNameForIndex(histogram_index), |
| 271 | // MINIMUM_SAMPLE, MAXIMUM_SAMPLE, BUCKET_COUNT, |
| 272 | // base::HistogramBase::kUmaTargetedHistogramFlag)); |
| 273 | // |
| 274 | // Though it seems inefficient to generate the name twice, the first |
| 275 | // instance will be used only for DCHECK builds and the second will |
| 276 | // execute only during the first access to the given index, after which |
| 277 | // the pointer is cached and the name never needed again. |
| 278 | #define STATIC_HISTOGRAM_POINTER_GROUP(constant_histogram_name, index, \ |
| 279 | constant_maximum, \ |
| 280 | histogram_add_method_invocation, \ |
| 281 | histogram_factory_get_invocation) \ |
| 282 | do { \ |
| 283 | static base::subtle::AtomicWord atomic_histograms[constant_maximum]; \ |
| 284 | DCHECK_LE(0, index); \ |
| 285 | DCHECK_LT(index, constant_maximum); \ |
| 286 | HISTOGRAM_POINTER_USE(&atomic_histograms[index], constant_histogram_name, \ |
| 287 | histogram_add_method_invocation, \ |
| 288 | histogram_factory_get_invocation); \ |
| 289 | } while (0) |
| 290 | |
| 291 | //------------------------------------------------------------------------------ |
rkaplow | 0150a0d | 2016-09-28 02:12:08 +0900 | [diff] [blame] | 292 | // Deprecated histogram macros. Not recommended for current use. |
| 293 | |
| 294 | // Legacy name for UMA_HISTOGRAM_COUNTS_1M. Suggest using explicit naming |
| 295 | // and not using this macro going forward. |
| 296 | #define UMA_HISTOGRAM_COUNTS(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ |
| 297 | name, sample, 1, 1000000, 50) |
| 298 | |
| 299 | // MB-granularity memory metric. This has a short max (1G). |
| 300 | #define UMA_HISTOGRAM_MEMORY_MB(name, sample) \ |
| 301 | UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 1000, 50) |
| 302 | |
| 303 | // For an enum with customized range. In general, sparse histograms should be |
| 304 | // used instead. |
| 305 | // Samples should be one of the std::vector<int> list provided via |
| 306 | // |custom_ranges|. See comments above CustomRanges::FactoryGet about the |
| 307 | // requirement of |custom_ranges|. You can use the helper function |
| 308 | // CustomHistogram::ArrayToCustomRanges to transform a C-style array of valid |
| 309 | // sample values to a std::vector<int>. |
| 310 | #define UMA_HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) \ |
| 311 | STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \ |
| 312 | base::CustomHistogram::FactoryGet(name, custom_ranges, \ |
| 313 | base::HistogramBase::kUmaTargetedHistogramFlag)) |
rkaplow | 8e5c3c9 | 2015-02-14 01:40:10 +0900 | [diff] [blame] | 314 | |
asvitkine | 4a7d51f | 2014-11-15 10:47:07 +0900 | [diff] [blame] | 315 | #endif // BASE_METRICS_HISTOGRAM_MACROS_H_ |