Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(388)

Side by Side Diff: base/metrics/histogram_macros.h

Issue 2361933002: Refactor histogram_macros.h. This improves documentation for the macros in the file, moves LOCAL_* … (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698