Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef BASE_METRICS_HISTOGRAM_MACROS_H_ | 5 #ifndef BASE_METRICS_HISTOGRAM_MACROS_H_ |
| 6 #define BASE_METRICS_HISTOGRAM_MACROS_H_ | 6 #define BASE_METRICS_HISTOGRAM_MACROS_H_ |
| 7 | 7 |
| 8 #include "base/atomicops.h" | |
| 9 #include "base/logging.h" | 8 #include "base/logging.h" |
|
Mark P
2016/09/23 19:30:42
I think this doesn't need logging anymore.
rkaplow
2016/09/26 20:16:10
Done.
| |
| 10 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
| 10 #include "base/metrics/histogram_macros_internal.h" | |
| 11 #include "base/metrics/local_histogram_macros.h" | |
| 11 #include "base/time/time.h" | 12 #include "base/time/time.h" |
| 12 | 13 |
| 13 // Macros for efficient use of histograms. See documentation in histogram.h. | 14 // TODO(nikunjb): Move sparse macros here. |
|
Mark P
2016/09/23 19:30:41
nit: here -> to this file
rkaplow
2016/09/26 20:16:09
Done.
| |
| 14 // | |
| 15 // UMA_HISTOGRAM_SPARSE_SLOWLY is defined in sparse_histogram.h as it has | 15 // UMA_HISTOGRAM_SPARSE_SLOWLY is defined in sparse_histogram.h as it has |
| 16 // different #include dependencies. | 16 // different #include dependencies. |
| 17 | 17 |
| 18 //------------------------------------------------------------------------------ | 18 // TODO(rkaplow): Link to proper documentation on metric creation once we have |
| 19 // Histograms are often put in areas where they are called many many times, and | 19 // it in a good state. |
| 20 // performance is critical. As a result, they are designed to have a very low | 20 |
| 21 // recurring cost of executing (adding additional samples). Toward that end, | 21 //------------------------------------------------------------------------------ |
| 22 // the macros declare a static pointer to the histogram in question, and only | 22 // Count histograms. These are used for collecting numeric data. Note that we |
| 23 // take a "slow path" to construct (or find) the histogram on the first run | 23 // have macros for more specialized use cases below (memory, time, percentages). |
| 24 // through the macro. We leak the histograms at shutdown time so that we don't | 24 |
| 25 // have to validate using the pointers at any time during the running of the | 25 // The number suffixes here refer to the max size of the sample, i.e. COUNT_1000 |
| 26 // process. | 26 // will be able to collect samples of counts up to 1000. The default number of |
| 27 | 27 // buckets in all default macros is 50. |
| 28 // The following code is generally what a thread-safe static pointer | 28 // Note that all these macros default to exponential histograms - i.e. the |
|
Mark P
2016/09/23 19:30:41
nit: omit "Note that"
rkaplow
2016/09/26 20:16:10
Done.
| |
| 29 // initialization looks like for a histogram (after a macro is expanded). This | 29 // lengths of the bucket ranges exponentially increase as the sample range |
| 30 // sample is an expansion (with comments) of the code for | 30 // increases. |
| 31 // LOCAL_HISTOGRAM_CUSTOM_COUNTS(). | 31 // These should *not* be used if you are interested in exact counts, i.e. a |
| 32 | 32 // bucket range of 1. In these cases, you should use the ENUMERATION macros |
| 33 /* | 33 // defined later. |
| 34 do { | 34 |
| 35 // The pointer's presence indicates the initialization is complete. | 35 // Sample Usage: |
| 36 // Initialization is idempotent, so it can safely be atomically repeated. | 36 // UMA_HISTOGRAM_COUNTS_100("My.Histogram", sample); |
| 37 static base::subtle::AtomicWord atomic_histogram_pointer = 0; | 37 |
| 38 | 38 #define UMA_HISTOGRAM_COUNTS_100(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ |
| 39 // Acquire_Load() ensures that we acquire visibility to the pointed-to data | 39 name, sample, 1, 100, 50) |
| 40 // in the histogram. | 40 |
| 41 base::Histogram* histogram_pointer(reinterpret_cast<base::Histogram*>( | 41 #define UMA_HISTOGRAM_COUNTS_1000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ |
| 42 base::subtle::Acquire_Load(&atomic_histogram_pointer))); | 42 name, sample, 1, 1000, 50) |
| 43 | 43 |
| 44 if (!histogram_pointer) { | 44 #define UMA_HISTOGRAM_COUNTS_10000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ |
| 45 // This is the slow path, which will construct OR find the matching | 45 name, sample, 1, 10000, 50) |
| 46 // histogram. FactoryGet includes locks on a global histogram name map | 46 |
| 47 // and is completely thread safe. | 47 #define UMA_HISTOGRAM_COUNTS_100000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ |
| 48 histogram_pointer = base::Histogram::FactoryGet( | 48 name, sample, 1, 100000, 50) |
| 49 name, min, max, bucket_count, base::HistogramBase::kNoFlags); | 49 |
| 50 | 50 #define UMA_HISTOGRAM_COUNTS_1000000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS(\ |
| 51 // Use Release_Store to ensure that the histogram data is made available | 51 name, sample, 1, 1000000, 50) |
| 52 // globally before we make the pointer visible. | 52 |
| 53 // Several threads may perform this store, but the same value will be | 53 // This can be used when the default ranges are not sufficient. This macro lets |
| 54 // stored in all cases (for a given named/spec'ed histogram). | 54 // the metric developer customize the min and max of the sampled range, as well |
| 55 // We could do this without any barrier, since FactoryGet entered and | 55 // as the number of buckets recorded. Usage: |
|
Mark P
2016/09/23 19:30:41
Please mention here that values less than the min
rkaplow
2016/09/26 20:16:10
gave a quick answer - think it's worth putting an
| |
| 56 // exited a lock after construction, but this barrier makes things clear. | 56 // UMA_HISTOGRAM_CUSTOM_COUNTS("My.Histogram", 1, 100000000, 100); |
| 57 base::subtle::Release_Store(&atomic_histogram_pointer, | 57 #define UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \ |
|
nikunjb1
2016/09/23 21:14:12
Small comment: Generally it is easier to follow th
Mark P
2016/09/23 21:24:08
I agree that Nik's suggestion would make the code
rkaplow
2016/09/26 20:16:10
That was my reasoning for placing it this way - I'
| |
| 58 reinterpret_cast<base::subtle::AtomicWord>(histogram_pointer)); | 58 INTERNAL_HISTOGRAM_CUSTOM_COUNTS_WITH_FLAG( \ |
| 59 } | 59 name, sample, min, max, bucket_count, \ |
| 60 | 60 base::HistogramBase::kUmaTargetedHistogramFlag) |
| 61 // Ensure calling contract is upheld, and the name does NOT vary. | 61 |
| 62 DCHECK(histogram_pointer->histogram_name() == constant_histogram_name); | 62 |
| 63 | 63 //------------------------------------------------------------------------------ |
| 64 histogram_pointer->Add(sample); | 64 // Timing histograms. These are used for collecting timing data (generally |
| 65 } while (0); | 65 // latencies). |
| 66 */ | 66 |
| 67 | 67 // These macros create exponentially sized histograms (lengths of the bucket |
| 68 // The above pattern is repeated in several macros. The only elements that | 68 // ranges exponentially increase as the sample range increases). The input |
| 69 // vary are the invocation of the Add(sample) vs AddTime(sample), and the choice | 69 // sample must be a number measured in ms. |
|
Mark P
2016/09/23 19:30:42
This last sentence is wrong I think. Isn't the in
rkaplow
2016/09/26 20:16:10
Ah, thanks.
| |
| 70 // of which FactoryGet method to use. The different FactoryGet methods have | 70 |
| 71 // various argument lists, so the function with its argument list is provided as | 71 // Sample Usage: |
| 72 // a macro argument here. The name is only used in a DCHECK, to assure that | 72 // UMA_HISTOGRAM_TIMES("My.Timing.Histogram", duration_in_ms); |
| 73 // callers don't try to vary the name of the histogram (which would tend to be | 73 |
| 74 // ignored by the one-time initialization of the histogtram_pointer). | 74 // Short timings - up to 10 seconds. |
| 75 | 75 #define UMA_HISTOGRAM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ |
| 76 // In some cases (integration into 3rd party code), it's useful to seperate the | 76 name, sample, base::TimeDelta::FromMilliseconds(1), \ |
| 77 // definition of |atomic_histogram_poiner| from its use. To achieve this we | |
| 78 // define HISTOGRAM_POINTER_USE, which uses an |atomic_histogram_pointer|, and | |
| 79 // STATIC_HISTOGRAM_POINTER_BLOCK, which defines an |atomic_histogram_pointer| | |
| 80 // and forwards to HISTOGRAM_POINTER_USE. | |
| 81 #define HISTOGRAM_POINTER_USE(atomic_histogram_pointer, \ | |
| 82 constant_histogram_name, \ | |
| 83 histogram_add_method_invocation, \ | |
| 84 histogram_factory_get_invocation) \ | |
| 85 do { \ | |
| 86 base::HistogramBase* histogram_pointer( \ | |
| 87 reinterpret_cast<base::HistogramBase*>( \ | |
| 88 base::subtle::Acquire_Load(atomic_histogram_pointer))); \ | |
| 89 if (!histogram_pointer) { \ | |
| 90 histogram_pointer = histogram_factory_get_invocation; \ | |
| 91 base::subtle::Release_Store( \ | |
| 92 atomic_histogram_pointer, \ | |
| 93 reinterpret_cast<base::subtle::AtomicWord>(histogram_pointer)); \ | |
| 94 } \ | |
| 95 if (DCHECK_IS_ON()) \ | |
| 96 histogram_pointer->CheckName(constant_histogram_name); \ | |
| 97 histogram_pointer->histogram_add_method_invocation; \ | |
| 98 } while (0) | |
| 99 | |
| 100 // Defines the static |atomic_histogram_pointer| and forwards to | |
| 101 // HISTOGRAM_POINTER_USE. | |
| 102 #define STATIC_HISTOGRAM_POINTER_BLOCK(constant_histogram_name, \ | |
|
nikunjb1
2016/09/23 21:14:12
I see usage of this outside histogram_macros.h e.g
rkaplow
2016/09/26 20:16:10
Probably not ideal - we'd need to see why they wer
Mark P
2016/09/26 23:06:47
Generally I've been advising people to use ENUMERA
Mark P
2016/09/29 23:15:00
What do you think about this suggestion?
| |
| 103 histogram_add_method_invocation, \ | |
| 104 histogram_factory_get_invocation) \ | |
| 105 do { \ | |
| 106 static base::subtle::AtomicWord atomic_histogram_pointer = 0; \ | |
| 107 HISTOGRAM_POINTER_USE(&atomic_histogram_pointer, constant_histogram_name, \ | |
| 108 histogram_add_method_invocation, \ | |
| 109 histogram_factory_get_invocation); \ | |
| 110 } while (0) | |
| 111 | |
| 112 //------------------------------------------------------------------------------ | |
| 113 // Provide easy general purpose histogram in a macro, just like stats counters. | |
| 114 // Most of these macros use 50 buckets, but check the definition for details. | |
| 115 // | |
| 116 // All of these macros must be called with |name| as a runtime constant --- it | |
|
Mark P
2016/09/23 19:30:41
This comments needs to stay in this file, prominen
rkaplow
2016/09/26 20:16:10
made a less technical version at the top of the fi
| |
| 117 // doesn't have to literally be a constant, but it must be the same string on | |
| 118 // all calls from a particular call site. If this rule is violated, | |
| 119 // STATIC_HISTOGRAM_POINTER_BLOCK will DCHECK, and if DCHECKS are disabled, the | |
| 120 // data will be written to the wrong histogram. | |
| 121 | |
| 122 #define LOCAL_HISTOGRAM_TIMES(name, sample) LOCAL_HISTOGRAM_CUSTOM_TIMES( \ | |
| 123 name, sample, base::TimeDelta::FromMilliseconds(1), \ | |
| 124 base::TimeDelta::FromSeconds(10), 50) | 77 base::TimeDelta::FromSeconds(10), 50) |
| 125 | 78 |
| 126 // For folks that need real specific times, use this to select a precise range | 79 // Medium timings - up to 3 minutes. Note this starts at 10ms (no good reason, |
| 127 // of times you want plotted, and the number of buckets you want used. | 80 // but not worth changing). |
| 128 #define LOCAL_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \ | 81 #define UMA_HISTOGRAM_MEDIUM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ |
| 129 STATIC_HISTOGRAM_POINTER_BLOCK(name, AddTime(sample), \ | 82 name, sample, base::TimeDelta::FromMilliseconds(10), \ |
| 130 base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ | |
| 131 base::HistogramBase::kNoFlags)) | |
| 132 | |
| 133 #define LOCAL_HISTOGRAM_COUNTS(name, sample) LOCAL_HISTOGRAM_CUSTOM_COUNTS( \ | |
| 134 name, sample, 1, 1000000, 50) | |
| 135 | |
| 136 #define LOCAL_HISTOGRAM_COUNTS_100(name, sample) \ | |
| 137 LOCAL_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 100, 50) | |
| 138 | |
| 139 #define LOCAL_HISTOGRAM_COUNTS_10000(name, sample) \ | |
| 140 LOCAL_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 10000, 50) | |
| 141 | |
| 142 #define LOCAL_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \ | |
| 143 INTERNAL_HISTOGRAM_CUSTOM_COUNTS_WITH_FLAG( \ | |
| 144 name, sample, min, max, bucket_count, base::HistogramBase::kNoFlags) | |
| 145 | |
| 146 // This is a helper macro used by other macros and shouldn't be used directly. | |
| 147 #define INTERNAL_HISTOGRAM_CUSTOM_COUNTS_WITH_FLAG(name, sample, min, max, \ | |
| 148 bucket_count, flag) \ | |
| 149 STATIC_HISTOGRAM_POINTER_BLOCK( \ | |
| 150 name, Add(sample), \ | |
| 151 base::Histogram::FactoryGet(name, min, max, bucket_count, flag)) | |
| 152 | |
| 153 // This is a helper macro used by other macros and shouldn't be used directly. | |
| 154 // One additional bucket is created in the LinearHistogram for the illegal | |
| 155 // values >= boundary_value so that mistakes in calling the UMA enumeration | |
| 156 // macros can be detected. | |
| 157 #define INTERNAL_HISTOGRAM_ENUMERATION_WITH_FLAG(name, sample, boundary, flag) \ | |
| 158 STATIC_HISTOGRAM_POINTER_BLOCK( \ | |
| 159 name, Add(sample), \ | |
| 160 base::LinearHistogram::FactoryGet( \ | |
| 161 name, 1, boundary, boundary + 1, flag)) | |
| 162 | |
| 163 #define LOCAL_HISTOGRAM_PERCENTAGE(name, under_one_hundred) \ | |
| 164 LOCAL_HISTOGRAM_ENUMERATION(name, under_one_hundred, 101) | |
| 165 | |
| 166 #define LOCAL_HISTOGRAM_BOOLEAN(name, sample) \ | |
| 167 STATIC_HISTOGRAM_POINTER_BLOCK(name, AddBoolean(sample), \ | |
| 168 base::BooleanHistogram::FactoryGet(name, base::Histogram::kNoFlags)) | |
| 169 | |
| 170 // Support histograming of an enumerated value. The samples should always be | |
| 171 // strictly less than |boundary_value| -- this prevents you from running into | |
| 172 // problems down the line if you add additional buckets to the histogram. Note | |
| 173 // also that, despite explicitly setting the minimum bucket value to |1| below, | |
| 174 // it is fine for enumerated histograms to be 0-indexed -- this is because | |
| 175 // enumerated histograms should never have underflow. One additional bucket is | |
| 176 // created in the LinearHistogram for the illegal values >= boundary_value so | |
| 177 // that mistakes in calling this macro can be detected. | |
| 178 #define LOCAL_HISTOGRAM_ENUMERATION(name, sample, boundary_value) \ | |
| 179 STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \ | |
| 180 base::LinearHistogram::FactoryGet(name, 1, boundary_value, \ | |
| 181 boundary_value + 1, base::HistogramBase::kNoFlags)) | |
| 182 | |
| 183 // Support histograming of an enumerated value. Samples should be one of the | |
|
Mark P
2016/09/23 19:30:42
Please keep this comment by the CUSTOM_ENUMERATION
rkaplow
2016/09/26 20:16:10
This was attached to the local version - I assume
| |
| 184 // std::vector<int> list provided via |custom_ranges|. See comments above | |
| 185 // CustomRanges::FactoryGet about the requirement of |custom_ranges|. | |
| 186 // You can use the helper function CustomHistogram::ArrayToCustomRanges to | |
| 187 // transform a C-style array of valid sample values to a std::vector<int>. | |
| 188 #define LOCAL_HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) \ | |
| 189 STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \ | |
| 190 base::CustomHistogram::FactoryGet(name, custom_ranges, \ | |
| 191 base::HistogramBase::kNoFlags)) | |
| 192 | |
| 193 #define LOCAL_HISTOGRAM_MEMORY_KB(name, sample) LOCAL_HISTOGRAM_CUSTOM_COUNTS( \ | |
| 194 name, sample, 1000, 500000, 50) | |
| 195 | |
| 196 //------------------------------------------------------------------------------ | |
| 197 // The following macros provide typical usage scenarios for callers that wish | |
| 198 // to record histogram data, and have the data submitted/uploaded via UMA. | |
| 199 // Not all systems support such UMA, but if they do, the following macros | |
| 200 // should work with the service. | |
| 201 | |
| 202 #define UMA_HISTOGRAM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ | |
| 203 name, sample, base::TimeDelta::FromMilliseconds(1), \ | |
| 204 base::TimeDelta::FromSeconds(10), 50) | |
| 205 | |
| 206 #define UMA_HISTOGRAM_MEDIUM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ | |
| 207 name, sample, base::TimeDelta::FromMilliseconds(10), \ | |
| 208 base::TimeDelta::FromMinutes(3), 50) | 83 base::TimeDelta::FromMinutes(3), 50) |
| 209 | 84 |
| 210 // Use this macro when times can routinely be much longer than 10 seconds. | 85 // Long timings - up to an hour. |
| 211 #define UMA_HISTOGRAM_LONG_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ | 86 #define UMA_HISTOGRAM_LONG_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ |
| 212 name, sample, base::TimeDelta::FromMilliseconds(1), \ | 87 name, sample, base::TimeDelta::FromMilliseconds(1), \ |
| 213 base::TimeDelta::FromHours(1), 50) | 88 base::TimeDelta::FromHours(1), 50) |
| 214 | 89 |
| 215 // Use this macro when times can routinely be much longer than 10 seconds and | 90 // Long timings with higher granularity - up to an hour with 100 buckets. |
| 216 // you want 100 buckets. | |
| 217 #define UMA_HISTOGRAM_LONG_TIMES_100(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ | 91 #define UMA_HISTOGRAM_LONG_TIMES_100(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ |
| 218 name, sample, base::TimeDelta::FromMilliseconds(1), \ | 92 name, sample, base::TimeDelta::FromMilliseconds(1), \ |
| 219 base::TimeDelta::FromHours(1), 100) | 93 base::TimeDelta::FromHours(1), 100) |
| 220 | 94 |
| 221 #define UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \ | 95 // This can be used when the default ranges are not sufficient. This macro lets |
| 222 STATIC_HISTOGRAM_POINTER_BLOCK(name, AddTime(sample), \ | 96 // the metric developer customize the min and max of the sampled range, as well |
| 223 base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ | 97 // as the number of buckets recorded. Usage: |
| 224 base::HistogramBase::kUmaTargetedHistogramFlag)) | 98 // UMA_HISTOGRAM_CUSTOM_TIMES("Very.Long.Timing.Histogram", duration_in_ms, |
| 225 | 99 // base::TimeDelta::FromSeconds(1), base::TimeDelta::FromDays(1), 100); |
| 226 #define UMA_HISTOGRAM_COUNTS(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ | 100 #define UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \ |
| 227 name, sample, 1, 1000000, 50) | 101 STATIC_HISTOGRAM_POINTER_BLOCK(name, AddTime(sample), \ |
| 228 | 102 base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ |
| 229 #define UMA_HISTOGRAM_COUNTS_100(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ | |
| 230 name, sample, 1, 100, 50) | |
| 231 | |
| 232 #define UMA_HISTOGRAM_COUNTS_1000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ | |
| 233 name, sample, 1, 1000, 50) | |
| 234 | |
| 235 #define UMA_HISTOGRAM_COUNTS_10000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ | |
| 236 name, sample, 1, 10000, 50) | |
| 237 | |
| 238 #define UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \ | |
| 239 INTERNAL_HISTOGRAM_CUSTOM_COUNTS_WITH_FLAG( \ | |
| 240 name, sample, min, max, bucket_count, \ | |
| 241 base::HistogramBase::kUmaTargetedHistogramFlag) | |
| 242 | |
| 243 #define UMA_STABILITY_HISTOGRAM_COUNTS_100(name, sample) \ | |
| 244 UMA_STABILITY_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 100, 50) | |
| 245 | |
| 246 #define UMA_STABILITY_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, \ | |
| 247 bucket_count) \ | |
| 248 INTERNAL_HISTOGRAM_CUSTOM_COUNTS_WITH_FLAG( \ | |
| 249 name, sample, min, max, bucket_count, \ | |
| 250 base::HistogramBase::kUmaStabilityHistogramFlag) | |
| 251 | |
| 252 #define UMA_HISTOGRAM_MEMORY_KB(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ | |
| 253 name, sample, 1000, 500000, 50) | |
| 254 | |
| 255 #define UMA_HISTOGRAM_MEMORY_MB(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ | |
| 256 name, sample, 1, 1000, 50) | |
| 257 | |
| 258 #define UMA_HISTOGRAM_MEMORY_LARGE_MB(name, sample) \ | |
| 259 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 64000, 100) | |
| 260 | |
| 261 #define UMA_HISTOGRAM_PERCENTAGE(name, under_one_hundred) \ | |
| 262 UMA_HISTOGRAM_ENUMERATION(name, under_one_hundred, 101) | |
| 263 | |
| 264 #define UMA_HISTOGRAM_BOOLEAN(name, sample) \ | |
| 265 STATIC_HISTOGRAM_POINTER_BLOCK(name, AddBoolean(sample), \ | |
| 266 base::BooleanHistogram::FactoryGet(name, \ | |
| 267 base::HistogramBase::kUmaTargetedHistogramFlag)) | |
| 268 | |
| 269 // The samples should always be strictly less than |boundary_value|. For more | |
| 270 // details, see the comment for the |LOCAL_HISTOGRAM_ENUMERATION| macro, above. | |
| 271 #define UMA_HISTOGRAM_ENUMERATION(name, sample, boundary_value) \ | |
| 272 INTERNAL_HISTOGRAM_ENUMERATION_WITH_FLAG( \ | |
| 273 name, sample, boundary_value, \ | |
| 274 base::HistogramBase::kUmaTargetedHistogramFlag) | |
| 275 | |
| 276 // Similar to UMA_HISTOGRAM_ENUMERATION, but used for recording stability | |
| 277 // histograms. Use this if recording a histogram that should be part of the | |
| 278 // initial stability log. | |
| 279 #define UMA_STABILITY_HISTOGRAM_ENUMERATION(name, sample, boundary_value) \ | |
| 280 INTERNAL_HISTOGRAM_ENUMERATION_WITH_FLAG( \ | |
| 281 name, sample, boundary_value, \ | |
| 282 base::HistogramBase::kUmaStabilityHistogramFlag) | |
| 283 | |
| 284 #define UMA_HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) \ | |
| 285 STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \ | |
| 286 base::CustomHistogram::FactoryGet(name, custom_ranges, \ | |
| 287 base::HistogramBase::kUmaTargetedHistogramFlag)) | 103 base::HistogramBase::kUmaTargetedHistogramFlag)) |
| 288 | 104 |
| 289 // Scoped class which logs its time on this earth as a UMA statistic. This is | 105 // Scoped class which logs its time on this earth as a UMA statistic. This is |
| 290 // recommended for when you want a histogram which measures the time it takes | 106 // recommended for when you want a histogram which measures the time it takes |
| 291 // for a method to execute. This measures up to 10 seconds. | 107 // for a method to execute. This measures up to 10 seconds (this uses |
|
Mark P
2016/09/23 19:30:42
nit: consider
(This uses UMA_HISTOGRAM_TIMES under
rkaplow
2016/09/26 20:16:10
just removed the parenthesis.
| |
| 292 #define SCOPED_UMA_HISTOGRAM_TIMER(name) \ | 108 // UMA_HISTOGRAM_TIMES under the hood). |
| 109 // Sample usage: | |
| 110 // void Function() { | |
| 111 // SCOPED_UMA_HISTOGRAM_TIMER("Component.FunctionTime"); | |
| 112 // ... | |
| 113 // } | |
| 114 #define SCOPED_UMA_HISTOGRAM_TIMER(name) \ | |
| 293 SCOPED_UMA_HISTOGRAM_TIMER_EXPANDER(name, false, __COUNTER__) | 115 SCOPED_UMA_HISTOGRAM_TIMER_EXPANDER(name, false, __COUNTER__) |
| 294 | 116 |
| 295 // Similar scoped histogram timer, but this uses UMA_HISTOGRAM_LONG_TIMES_100, | 117 // Similar scoped histogram timer, but this uses UMA_HISTOGRAM_LONG_TIMES_100, |
| 296 // which measures up to an hour, and uses 100 buckets. This is more expensive | 118 // which measures up to an hour, and uses 100 buckets. This is more expensive |
| 297 // to store, so only use if this often takes >10 seconds. | 119 // to store, so only use if this often takes >10 seconds. |
| 298 #define SCOPED_UMA_HISTOGRAM_LONG_TIMER(name) \ | 120 #define SCOPED_UMA_HISTOGRAM_LONG_TIMER(name) \ |
| 299 SCOPED_UMA_HISTOGRAM_TIMER_EXPANDER(name, true, __COUNTER__) | 121 SCOPED_UMA_HISTOGRAM_TIMER_EXPANDER(name, true, __COUNTER__) |
| 300 | 122 |
| 301 // This nested macro is necessary to expand __COUNTER__ to an actual value. | 123 |
| 302 #define SCOPED_UMA_HISTOGRAM_TIMER_EXPANDER(name, is_long, key) \ | 124 //------------------------------------------------------------------------------ |
| 303 SCOPED_UMA_HISTOGRAM_TIMER_UNIQUE(name, is_long, key) | 125 // Memory histograms. |
| 304 | 126 |
| 305 #define SCOPED_UMA_HISTOGRAM_TIMER_UNIQUE(name, is_long, key) \ | 127 // These macros create exponentially sized histograms (lengths of the bucket |
| 306 class ScopedHistogramTimer##key { \ | 128 // ranges exponentially increase as the sample range increases). The input |
| 307 public: \ | 129 // sample must be a number measured in ms. |
|
Mark P
2016/09/23 19:30:42
ms -> kilobytes
rkaplow
2016/09/26 20:16:10
Done.
| |
| 308 ScopedHistogramTimer##key() : constructed_(base::TimeTicks::Now()) {} \ | 130 |
| 309 ~ScopedHistogramTimer##key() { \ | 131 // Sample Usage: |
| 310 base::TimeDelta elapsed = base::TimeTicks::Now() - constructed_; \ | 132 // UMA_HISTOGRAM_MEMORY_KB("My.Memory.Histogram", memory_in_kb); |
| 311 if (is_long) { \ | 133 |
| 312 UMA_HISTOGRAM_LONG_TIMES_100(name, elapsed); \ | 134 // Used to measure common KB-granularity memory stats. Range is up to 500000KB - |
| 313 } else { \ | 135 // approximately 500M. |
| 314 UMA_HISTOGRAM_TIMES(name, elapsed); \ | 136 #define UMA_HISTOGRAM_MEMORY_KB(name, sample) \ |
| 315 } \ | 137 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1000, 500000, 50) |
| 316 } \ | 138 |
| 317 private: \ | 139 // Used to measure common MB-granularity memory stats. Range is up to ~64G. |
| 318 base::TimeTicks constructed_; \ | 140 #define UMA_HISTOGRAM_MEMORY_LARGE_MB(name, sample) \ |
| 319 } scoped_histogram_timer_##key | 141 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 64000, 100) |
| 142 | |
| 143 | |
| 144 //------------------------------------------------------------------------------ | |
| 145 // Enumeration histograms. | |
| 146 | |
| 147 // These macros create histograms for enumerated data. Ideally, the data should | |
| 148 // be of the form of "event occurs, log the result". We recommended not putting | |
| 149 // related but not directly connected data as enums within the same histogram. | |
| 150 // You should be defining an associated Enum, and the input sample should be | |
| 151 // an element of the Enum. | |
| 152 | |
| 153 // Sample Usage: | |
| 154 // UMA_HISTOGRAM_ENUMERATION("My.Enumeration", Enum::VALUE, Enum::EVENT_MAX); | |
| 155 // Enum values can be appended, but the order should never change. The value | |
|
Mark P
2016/09/23 19:30:41
Instead of "Enum values can be appended, but the o
rkaplow
2016/09/26 20:16:10
Done.
| |
| 156 // in |sample| must be strictly less than |enum_max|. | |
| 157 | |
| 158 #define UMA_HISTOGRAM_ENUMERATION(name, sample, enum_max) \ | |
| 159 INTERNAL_HISTOGRAM_ENUMERATION_WITH_FLAG( \ | |
| 160 name, sample, enum_max, \ | |
| 161 base::HistogramBase::kUmaTargetedHistogramFlag) | |
| 162 | |
| 163 // Histogram for boolean values. | |
| 164 // Sample Usage: | |
| 165 // UMA_HISTOGRAM_BOOLEAN("Histogram.Boolean", bool); | |
| 166 #define UMA_HISTOGRAM_BOOLEAN(name, sample) \ | |
| 167 STATIC_HISTOGRAM_POINTER_BLOCK(name, AddBoolean(sample), \ | |
| 168 base::BooleanHistogram::FactoryGet(name, \ | |
| 169 base::HistogramBase::kUmaTargetedHistogramFlag)) | |
| 170 | |
| 171 // Histogram for percentages. This will be 100 buckets of length 1. | |
|
Mark P
2016/09/23 19:30:41
length -> size
rkaplow
2016/09/26 20:16:10
Done.
| |
| 172 // Sample Usage: | |
| 173 // UMA_HISTOGRAM_PERCENTAGE("Histogram.Percent", percent_as_int); | |
| 174 #define UMA_HISTOGRAM_PERCENTAGE(name, under_one_hundred) \ | |
| 175 UMA_HISTOGRAM_ENUMERATION(name, under_one_hundred, 101) | |
| 176 | |
| 177 | |
| 178 //------------------------------------------------------------------------------ | |
| 179 // Stability-specific histograms. | |
| 180 | |
| 181 // Histograms logged in as stability histograms will be included in the initial | |
| 182 // stability log. |MetricsService::PrepareInitialStabilityLog|. | |
|
Mark P
2016/09/23 19:30:41
are you missing the word "See" at the beginning of
rkaplow
2016/09/26 20:16:10
yup I was.
| |
| 183 // For details on usage, see the documentation on the non-stability equivalents. | |
| 184 | |
| 185 #define UMA_STABILITY_HISTOGRAM_COUNTS_100(name, sample) \ | |
| 186 UMA_STABILITY_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 100, 50) | |
| 187 | |
| 188 #define UMA_STABILITY_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, \ | |
| 189 bucket_count) \ | |
| 190 INTERNAL_HISTOGRAM_CUSTOM_COUNTS_WITH_FLAG( \ | |
| 191 name, sample, min, max, bucket_count, \ | |
| 192 base::HistogramBase::kUmaStabilityHistogramFlag) | |
| 193 | |
| 194 #define UMA_STABILITY_HISTOGRAM_ENUMERATION(name, sample, enum_max) \ | |
| 195 INTERNAL_HISTOGRAM_ENUMERATION_WITH_FLAG( \ | |
| 196 name, sample, enum_max, \ | |
| 197 base::HistogramBase::kUmaStabilityHistogramFlag) | |
| 198 | |
| 199 | |
| 200 //------------------------------------------------------------------------------ | |
| 201 // Deprecated histograms. Not recommended for current use. | |
| 202 | |
| 203 // Legacy name for UMA_HISTOGRAM_COUNTS_1000000. Suggest using explicit naming | |
| 204 // and not using this macro going forward. | |
| 205 #define UMA_HISTOGRAM_COUNTS(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ | |
| 206 name, sample, 1, 1000000, 50) | |
| 207 | |
| 208 // MB-granularity memory metric. This has a short max (1G). | |
| 209 #define UMA_HISTOGRAM_MEMORY_MB(name, sample) \ | |
| 210 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 1000, 50) | |
| 211 | |
| 212 // For a enum with customized range. In general, sparse histograms should be | |
|
Mark P
2016/09/23 19:30:42
nit: a -> an
rkaplow
2016/09/26 20:16:10
Done.
| |
| 213 // used instead. | |
| 214 #define UMA_HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) \ | |
| 215 STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \ | |
| 216 base::CustomHistogram::FactoryGet(name, custom_ranges, \ | |
| 217 base::HistogramBase::kUmaTargetedHistogramFlag)) | |
| 320 | 218 |
| 321 #endif // BASE_METRICS_HISTOGRAM_MACROS_H_ | 219 #endif // BASE_METRICS_HISTOGRAM_MACROS_H_ |
| OLD | NEW |