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" | |
10 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/metrics/histogram_macros_internal.h" | |
10 #include "base/metrics/histogram_macros_local.h" | |
11 #include "base/time/time.h" | 11 #include "base/time/time.h" |
12 | 12 |
13 // Macros for efficient use of histograms. See documentation in histogram.h. | 13 // TODO(nikunjb): Move sparse macros to this file. |
14 // | |
15 // UMA_HISTOGRAM_SPARSE_SLOWLY is defined in sparse_histogram.h as it has | 14 // UMA_HISTOGRAM_SPARSE_SLOWLY is defined in sparse_histogram.h as it has |
16 // different #include dependencies. | 15 // different #include dependencies. |
17 | 16 |
18 //------------------------------------------------------------------------------ | 17 // 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 | 18 // it in a good state. |
20 // performance is critical. As a result, they are designed to have a very low | 19 |
21 // recurring cost of executing (adding additional samples). Toward that end, | 20 // All of these macros must be called with |name| as a runtime constant - it |
22 // the macros declare a static pointer to the histogram in question, and only | |
23 // take a "slow path" to construct (or find) the histogram on the first run | |
24 // through the macro. We leak the histograms at shutdown time so that we don't | |
25 // have to validate using the pointers at any time during the running of the | |
26 // process. | |
27 | |
28 // The following code is generally what a thread-safe static pointer | |
29 // initialization looks like for a histogram (after a macro is expanded). This | |
30 // sample is an expansion (with comments) of the code for | |
31 // LOCAL_HISTOGRAM_CUSTOM_COUNTS(). | |
32 | |
33 /* | |
34 do { | |
35 // The pointer's presence indicates the initialization is complete. | |
36 // Initialization is idempotent, so it can safely be atomically repeated. | |
37 static base::subtle::AtomicWord atomic_histogram_pointer = 0; | |
38 | |
39 // Acquire_Load() ensures that we acquire visibility to the pointed-to data | |
40 // in the histogram. | |
41 base::Histogram* histogram_pointer(reinterpret_cast<base::Histogram*>( | |
42 base::subtle::Acquire_Load(&atomic_histogram_pointer))); | |
43 | |
44 if (!histogram_pointer) { | |
45 // This is the slow path, which will construct OR find the matching | |
46 // histogram. FactoryGet includes locks on a global histogram name map | |
47 // and is completely thread safe. | |
48 histogram_pointer = base::Histogram::FactoryGet( | |
49 name, min, max, bucket_count, base::HistogramBase::kNoFlags); | |
50 | |
51 // Use Release_Store to ensure that the histogram data is made available | |
52 // globally before we make the pointer visible. | |
53 // Several threads may perform this store, but the same value will be | |
54 // stored in all cases (for a given named/spec'ed histogram). | |
55 // We could do this without any barrier, since FactoryGet entered and | |
56 // exited a lock after construction, but this barrier makes things clear. | |
57 base::subtle::Release_Store(&atomic_histogram_pointer, | |
58 reinterpret_cast<base::subtle::AtomicWord>(histogram_pointer)); | |
59 } | |
60 | |
61 // Ensure calling contract is upheld, and the name does NOT vary. | |
62 DCHECK(histogram_pointer->histogram_name() == constant_histogram_name); | |
63 | |
64 histogram_pointer->Add(sample); | |
65 } while (0); | |
66 */ | |
67 | |
68 // The above pattern is repeated in several macros. The only elements that | |
69 // vary are the invocation of the Add(sample) vs AddTime(sample), and the choice | |
70 // of which FactoryGet method to use. The different FactoryGet methods have | |
71 // various argument lists, so the function with its argument list is provided as | |
72 // a macro argument here. The name is only used in a DCHECK, to assure that | |
73 // callers don't try to vary the name of the histogram (which would tend to be | |
74 // ignored by the one-time initialization of the histogtram_pointer). | |
75 | |
76 // In some cases (integration into 3rd party code), it's useful to seperate the | |
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, \ | |
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 | |
117 // doesn't have to literally be a constant, but it must be the same string on | 21 // 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, | 22 // all calls from a particular call site. If this rule is violated, it is |
119 // STATIC_HISTOGRAM_POINTER_BLOCK will DCHECK, and if DCHECKS are disabled, the | 23 // possible the data will be written to the wrong histogram. |
120 // data will be written to the wrong histogram. | 24 |
121 | 25 //------------------------------------------------------------------------------ |
122 #define LOCAL_HISTOGRAM_TIMES(name, sample) LOCAL_HISTOGRAM_CUSTOM_TIMES( \ | 26 // Count histograms. These are used for collecting numeric data. Note that we |
123 name, sample, base::TimeDelta::FromMilliseconds(1), \ | 27 // have macros for more specialized use cases below (memory, time, percentages). |
28 | |
29 // The number suffixes here refer to the max size of the sample, i.e. COUNT_1000 | |
30 // will be able to collect samples of counts up to 1000. The default number of | |
31 // buckets in all default macros is 50. | |
32 // These macros default to exponential histograms - i.e. the lengths of the | |
33 // bucket ranges exponentially increase as the sample range increases. | |
34 // These should *not* be used if you are interested in exact counts, i.e. a | |
35 // bucket range of 1. In these cases, you should use the ENUMERATION macros | |
36 // defined later. | |
37 | |
38 // Sample Usage: | |
Alexei Svitkine (slow)
2016/09/26 20:35:48
Nit: Don't capitalize usage, i.e. "Sample usage:".
rkaplow
2016/09/26 21:15:21
Done.
| |
39 // UMA_HISTOGRAM_COUNTS_100("My.Histogram", sample); | |
Alexei Svitkine (slow)
2016/09/26 20:35:48
Nit: I suggest indenting these sample usage lines
rkaplow
2016/09/26 21:15:20
Done.
| |
40 | |
41 #define UMA_HISTOGRAM_COUNTS_100(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ | |
42 name, sample, 1, 100, 50) | |
43 | |
44 #define UMA_HISTOGRAM_COUNTS_1000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ | |
45 name, sample, 1, 1000, 50) | |
46 | |
47 #define UMA_HISTOGRAM_COUNTS_10000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ | |
48 name, sample, 1, 10000, 50) | |
49 | |
50 #define UMA_HISTOGRAM_COUNTS_100000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ | |
51 name, sample, 1, 100000, 50) | |
52 | |
53 #define UMA_HISTOGRAM_COUNTS_1000000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS(\ | |
Alexei Svitkine (slow)
2016/09/26 20:35:47
1000000 is quite a mouthful. Let's name it 10M and
rkaplow
2016/09/26 21:15:20
done, switched the example too
| |
54 name, sample, 1, 1000000, 50) | |
55 | |
56 // This can be used when the default ranges are not sufficient. This macro lets | |
57 // the metric developer customize the min and max of the sampled range, as well | |
58 // as the number of buckets recorded. | |
59 // Any data outside the range here will be put in underflow and overflow | |
60 // buckets. | |
61 // Usage: | |
Alexei Svitkine (slow)
2016/09/26 20:35:47
Nit: "Sample usage:" and put an empty line above,
rkaplow
2016/09/26 21:15:20
Done.
| |
62 // UMA_HISTOGRAM_CUSTOM_COUNTS("My.Histogram", 1, 100000000, 100); | |
63 #define UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \ | |
64 INTERNAL_HISTOGRAM_CUSTOM_COUNTS_WITH_FLAG( \ | |
65 name, sample, min, max, bucket_count, \ | |
66 base::HistogramBase::kUmaTargetedHistogramFlag) | |
67 | |
68 | |
69 //------------------------------------------------------------------------------ | |
70 // Timing histograms. These are used for collecting timing data (generally | |
71 // latencies). | |
72 | |
73 // These macros create exponentially sized histograms (lengths of the bucket | |
74 // ranges exponentially increase as the sample range increases). The input | |
75 // sample is a base::TimeDelta. The output data is measured in ms granularity. | |
76 // All of these macros must be called with |name| as a runtime constant. | |
77 | |
78 // Sample Usage: | |
79 // UMA_HISTOGRAM_TIMES("My.Timing.Histogram", time_delta); | |
80 | |
81 // Short timings - up to 10 seconds. | |
82 #define UMA_HISTOGRAM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ | |
83 name, sample, base::TimeDelta::FromMilliseconds(1), \ | |
124 base::TimeDelta::FromSeconds(10), 50) | 84 base::TimeDelta::FromSeconds(10), 50) |
125 | 85 |
126 // For folks that need real specific times, use this to select a precise range | 86 // 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. | 87 // but not worth changing). |
128 #define LOCAL_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \ | 88 #define UMA_HISTOGRAM_MEDIUM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ |
129 STATIC_HISTOGRAM_POINTER_BLOCK(name, AddTime(sample), \ | 89 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 | |
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) | 90 base::TimeDelta::FromMinutes(3), 50) |
209 | 91 |
210 // Use this macro when times can routinely be much longer than 10 seconds. | 92 // Long timings - up to an hour. |
211 #define UMA_HISTOGRAM_LONG_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ | 93 #define UMA_HISTOGRAM_LONG_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ |
212 name, sample, base::TimeDelta::FromMilliseconds(1), \ | 94 name, sample, base::TimeDelta::FromMilliseconds(1), \ |
213 base::TimeDelta::FromHours(1), 50) | 95 base::TimeDelta::FromHours(1), 50) |
214 | 96 |
215 // Use this macro when times can routinely be much longer than 10 seconds and | 97 // 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( \ | 98 #define UMA_HISTOGRAM_LONG_TIMES_100(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \ |
218 name, sample, base::TimeDelta::FromMilliseconds(1), \ | 99 name, sample, base::TimeDelta::FromMilliseconds(1), \ |
219 base::TimeDelta::FromHours(1), 100) | 100 base::TimeDelta::FromHours(1), 100) |
220 | 101 |
221 #define UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \ | 102 // This can be used when the default ranges are not sufficient. This macro lets |
222 STATIC_HISTOGRAM_POINTER_BLOCK(name, AddTime(sample), \ | 103 // the metric developer customize the min and max of the sampled range, as well |
223 base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ | 104 // as the number of buckets recorded. Usage: |
Alexei Svitkine (slow)
2016/09/26 20:35:48
Nit: "Sample usage:" on a separate line with a bla
rkaplow
2016/09/26 21:15:21
Done.
| |
224 base::HistogramBase::kUmaTargetedHistogramFlag)) | 105 // UMA_HISTOGRAM_CUSTOM_TIMES("Very.Long.Timing.Histogram", duration_in_ms, |
225 | 106 // base::TimeDelta::FromSeconds(1), base::TimeDelta::FromDays(1), 100); |
226 #define UMA_HISTOGRAM_COUNTS(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ | 107 #define UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \ |
227 name, sample, 1, 1000000, 50) | 108 STATIC_HISTOGRAM_POINTER_BLOCK(name, AddTime(sample), \ |
228 | 109 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)) | 110 base::HistogramBase::kUmaTargetedHistogramFlag)) |
288 | 111 |
289 // Scoped class which logs its time on this earth as a UMA statistic. This is | 112 // 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 | 113 // 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. | 114 // for a method to execute. This measures up to 10 seconds. This uses |
292 #define SCOPED_UMA_HISTOGRAM_TIMER(name) \ | 115 // UMA_HISTOGRAM_TIMES under the hood. |
116 // Sample usage: | |
Alexei Svitkine (slow)
2016/09/26 20:35:48
Nit: Add a blank line before.
rkaplow
2016/09/26 21:15:21
Done.
| |
117 // void Function() { | |
118 // SCOPED_UMA_HISTOGRAM_TIMER("Component.FunctionTime"); | |
119 // ... | |
120 // } | |
121 #define SCOPED_UMA_HISTOGRAM_TIMER(name) \ | |
293 SCOPED_UMA_HISTOGRAM_TIMER_EXPANDER(name, false, __COUNTER__) | 122 SCOPED_UMA_HISTOGRAM_TIMER_EXPANDER(name, false, __COUNTER__) |
294 | 123 |
295 // Similar scoped histogram timer, but this uses UMA_HISTOGRAM_LONG_TIMES_100, | 124 // 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 | 125 // 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. | 126 // to store, so only use if this often takes >10 seconds. |
298 #define SCOPED_UMA_HISTOGRAM_LONG_TIMER(name) \ | 127 #define SCOPED_UMA_HISTOGRAM_LONG_TIMER(name) \ |
299 SCOPED_UMA_HISTOGRAM_TIMER_EXPANDER(name, true, __COUNTER__) | 128 SCOPED_UMA_HISTOGRAM_TIMER_EXPANDER(name, true, __COUNTER__) |
300 | 129 |
301 // This nested macro is necessary to expand __COUNTER__ to an actual value. | 130 |
302 #define SCOPED_UMA_HISTOGRAM_TIMER_EXPANDER(name, is_long, key) \ | 131 //------------------------------------------------------------------------------ |
303 SCOPED_UMA_HISTOGRAM_TIMER_UNIQUE(name, is_long, key) | 132 // Memory histograms. |
304 | 133 |
305 #define SCOPED_UMA_HISTOGRAM_TIMER_UNIQUE(name, is_long, key) \ | 134 // These macros create exponentially sized histograms (lengths of the bucket |
306 class ScopedHistogramTimer##key { \ | 135 // ranges exponentially increase as the sample range increases). The input |
307 public: \ | 136 // sample must be a number measured in kilobytes. |
308 ScopedHistogramTimer##key() : constructed_(base::TimeTicks::Now()) {} \ | 137 // All of these macros must be called with |name| as a runtime constant. |
309 ~ScopedHistogramTimer##key() { \ | 138 |
310 base::TimeDelta elapsed = base::TimeTicks::Now() - constructed_; \ | 139 // Sample Usage: |
311 if (is_long) { \ | 140 // UMA_HISTOGRAM_MEMORY_KB("My.Memory.Histogram", memory_in_kb); |
312 UMA_HISTOGRAM_LONG_TIMES_100(name, elapsed); \ | 141 |
313 } else { \ | 142 // Used to measure common KB-granularity memory stats. Range is up to 500000KB - |
314 UMA_HISTOGRAM_TIMES(name, elapsed); \ | 143 // approximately 500M. |
315 } \ | 144 #define UMA_HISTOGRAM_MEMORY_KB(name, sample) \ |
316 } \ | 145 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1000, 500000, 50) |
317 private: \ | 146 |
318 base::TimeTicks constructed_; \ | 147 // Used to measure common MB-granularity memory stats. Range is up to ~64G. |
319 } scoped_histogram_timer_##key | 148 #define UMA_HISTOGRAM_MEMORY_LARGE_MB(name, sample) \ |
149 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 64000, 100) | |
150 | |
151 | |
152 //------------------------------------------------------------------------------ | |
153 // Enumeration histograms. | |
Alexei Svitkine (slow)
2016/09/26 20:35:47
Nit: How about making this first? Otherwise someon
rkaplow
2016/09/26 21:15:20
done, and local to match
| |
154 | |
155 // These macros create histograms for enumerated data. Ideally, the data should | |
156 // be of the form of "event occurs, log the result". We recommended not putting | |
157 // related but not directly connected data as enums within the same histogram. | |
158 // You should be defining an associated Enum, and the input sample should be | |
159 // an element of the Enum. | |
160 // All of these macros must be called with |name| as a runtime constant. | |
161 | |
162 | |
163 // Sample Usage: | |
164 // UMA_HISTOGRAM_ENUMERATION("My.Enumeration", Enum::VALUE, Enum::EVENT_MAX); | |
165 // Enum values can be appended, but existing enums must never be renumbered or | |
166 // delete and reused. The value in |sample| must be strictly less than | |
167 // |enum_max|. | |
168 | |
169 #define UMA_HISTOGRAM_ENUMERATION(name, sample, enum_max) \ | |
170 INTERNAL_HISTOGRAM_ENUMERATION_WITH_FLAG( \ | |
171 name, sample, enum_max, \ | |
172 base::HistogramBase::kUmaTargetedHistogramFlag) | |
173 | |
174 // Histogram for boolean values. | |
175 // Sample Usage: | |
176 // UMA_HISTOGRAM_BOOLEAN("Histogram.Boolean", bool); | |
177 #define UMA_HISTOGRAM_BOOLEAN(name, sample) \ | |
178 STATIC_HISTOGRAM_POINTER_BLOCK(name, AddBoolean(sample), \ | |
179 base::BooleanHistogram::FactoryGet(name, \ | |
180 base::HistogramBase::kUmaTargetedHistogramFlag)) | |
181 | |
182 // Histogram for percentages. This will be 100 buckets of size 1. | |
Alexei Svitkine (slow)
2016/09/26 20:35:47
I'd put its own header here, since I don't think p
rkaplow
2016/09/26 21:15:21
Done.
| |
183 // Sample Usage: | |
184 // UMA_HISTOGRAM_PERCENTAGE("Histogram.Percent", percent_as_int); | |
185 #define UMA_HISTOGRAM_PERCENTAGE(name, under_one_hundred) \ | |
186 UMA_HISTOGRAM_ENUMERATION(name, under_one_hundred, 101) | |
187 | |
188 | |
189 //------------------------------------------------------------------------------ | |
190 // Stability-specific histograms. | |
191 | |
192 // Histograms logged in as stability histograms will be included in the initial | |
193 // stability log. See comments by declaration of | |
194 // MetricsService::PrepareInitialStabilityLog(). | |
195 // All of these macros must be called with |name| as a runtime constant. | |
196 | |
197 // For details on usage, see the documentation on the non-stability equivalents. | |
198 | |
199 #define UMA_STABILITY_HISTOGRAM_COUNTS_100(name, sample) \ | |
200 UMA_STABILITY_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 100, 50) | |
201 | |
202 #define UMA_STABILITY_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, \ | |
203 bucket_count) \ | |
204 INTERNAL_HISTOGRAM_CUSTOM_COUNTS_WITH_FLAG( \ | |
205 name, sample, min, max, bucket_count, \ | |
206 base::HistogramBase::kUmaStabilityHistogramFlag) | |
207 | |
208 #define UMA_STABILITY_HISTOGRAM_ENUMERATION(name, sample, enum_max) \ | |
209 INTERNAL_HISTOGRAM_ENUMERATION_WITH_FLAG( \ | |
210 name, sample, enum_max, \ | |
211 base::HistogramBase::kUmaStabilityHistogramFlag) | |
212 | |
213 | |
214 //------------------------------------------------------------------------------ | |
215 // Deprecated histograms. Not recommended for current use. | |
216 | |
217 // Legacy name for UMA_HISTOGRAM_COUNTS_1000000. Suggest using explicit naming | |
218 // and not using this macro going forward. | |
219 #define UMA_HISTOGRAM_COUNTS(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ | |
220 name, sample, 1, 1000000, 50) | |
221 | |
222 // MB-granularity memory metric. This has a short max (1G). | |
223 #define UMA_HISTOGRAM_MEMORY_MB(name, sample) \ | |
224 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 1000, 50) | |
225 | |
226 // For an enum with customized range. In general, sparse histograms should be | |
227 // used instead. | |
228 // Samples should be one of the std::vector<int> list provided via | |
229 // |custom_ranges|. See comments above CustomRanges::FactoryGet about the | |
230 // requirement of |custom_ranges|. You can use the helper function | |
231 // CustomHistogram::ArrayToCustomRanges to transform a C-style array of valid | |
232 // sample values to a std::vector<int>. | |
233 #define UMA_HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) \ | |
234 STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \ | |
235 base::CustomHistogram::FactoryGet(name, custom_ranges, \ | |
236 base::HistogramBase::kUmaTargetedHistogramFlag)) | |
320 | 237 |
321 #endif // BASE_METRICS_HISTOGRAM_MACROS_H_ | 238 #endif // BASE_METRICS_HISTOGRAM_MACROS_H_ |
OLD | NEW |